{
  "openapi": "3.1.0",
  "info": {
    "title": "Niftipay Partner API",
    "version": "2026-10-17",
    "description": "Generated from the partner reference at https://partners.niftipay.com. Carries the surface map — paths, methods, scopes and examples. Field-level contracts for KYB live at GET /api/v1/partner/onboarding/schema.",
    "contact": {
      "url": "https://partners.niftipay.com"
    }
  },
  "servers": [
    {
      "url": "https://www.niftipay.com"
    }
  ],
  "components": {
    "securitySchemes": {
      "partnerToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Short-lived JWT from POST /api/oauth/token (client_credentials). Scope requests are all-or-nothing."
      }
    }
  },
  "security": [
    {
      "partnerToken": []
    }
  ],
  "paths": {
    "/api/v1/partner/customers/{customerId}/agreements/{agreementId}/acceptances": {
      "post": {
        "operationId": "postCustomersByAgreementsByAcceptances",
        "summary": "Accept an agreement",
        "description": "Records that the customer accepted this agreement. The partner rendered the document in its own UI, so the record must carry the exact agreement_version, a content_hash is captured server-side, and the acceptance_channel — these are the only evidence that the act happened.",
        "tags": [
          "Agreements"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "agreementId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Response `201` (new) / `200` (replay)",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "acceptance": {
                      "acceptance_id": "acc-1",
                      "agreement_id": "tos",
                      "agreement_version": "1.0",
                      "content_hash": "a1b2c3…64hex",
                      "acceptance_channel": "partner_web",
                      "accepted_at": "2026-08-19T09:00:00.000Z",
                      "recorded_at": "2026-08-19T09:00:01.000Z",
                      "accepted_via_partner": true,
                      "evidence": {
                        "external_session_id": "sess_88213"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "agreements:accept"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "agreement_version": "1.0",
                "acceptance_channel": "partner_web",
                "accepted_at": "2026-08-19T09:00:00.000Z",
                "evidence": {
                  "external_session_id": "sess_88213"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/partner/customers/{customerId}/agreements": {
      "get": {
        "operationId": "getCustomersByAgreements",
        "summary": "List agreements",
        "description": "Returns every catalogued agreement and where this customer stands on each. \"Assigned\" currently means all customers on the current version. status answers the only question you have: required (no valid acceptance), accepted (current version accepted), or superseded (an old version was accepted and must be re-collected).",
        "tags": [
          "Agreements"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "agreements": [
                      {
                        "agreement_id": "tos",
                        "title": "Terms of Service",
                        "version": "1.0",
                        "effective_date": "2026-01-01",
                        "document_url": "https://.../tos.pdf",
                        "content_hash": "a1b2c3…64hex",
                        "parties": [
                          {
                            "role": "provider",
                            "name": "Niftipay"
                          },
                          {
                            "role": "customer",
                            "name": "Example SL"
                          }
                        ],
                        "disclosure": "This agreement is between you and Niftipay …",
                        "status": "required",
                        "current_acceptance": null,
                        "previous_acceptances": []
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "agreements:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/capabilities": {
      "get": {
        "operationId": "getCustomersByCapabilities",
        "summary": "List capabilities",
        "description": "Reports, per capability, two independent facts: - enabled — the grant: whether your partner integration is permitted to use this capability on this customer. See How grants are set below. - available — merchant-side truth, which can flip on its own (e.g. KYB expiring, a chargeback threshold landing) with nobody touching the partner's configuration. Reporting both lets you explain a disabled action",
        "tags": [
          "Capabilities"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "capabilities": [
                      {
                        "capability": "payments.crypto",
                        "enabled": false,
                        "available": true,
                        "reason": null
                      },
                      {
                        "capability": "payments.fiat_card",
                        "enabled": true,
                        "available": false,
                        "reason": "chargeback_threshold"
                      },
                      {
                        "capability": "payouts",
                        "enabled": false,
                        "available": true,
                        "reason": null
                      },
                      {
                        "capability": "payout_wallets",
                        "enabled": false,
                        "available": true,
                        "reason": null
                      },
                      {
                        "capability": "refunds",
                        "enabled": false,
                        "available": true,
                        "reason": null
                      },
                      {
                        "capability": "wallets",
                        "enabled": false,
                        "available": true,
                        "reason": null
                      },
                      {
                        "capability": "withdrawals",
                        "enabled": false,
                        "available": true,
                        "reason": null
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "customers:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/chargebacks": {
      "get": {
        "operationId": "getCustomersByChargebacks",
        "summary": "Chargebacks",
        "description": "The disputes on a single order, newest first, with no customer id in the path — a partner holding nothing but the order_key can ask. An order you cannot see answers with an empty list rather than a 404: either way the answer is \"no chargebacks\", so there is no second signal worth protecting here. bash curl https://www.niftipay.com/api/v1/partner/fiat-orders/1001/chargebacks \\ -H \"Authorization: Be",
        "tags": [
          "API Reference"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "chargebacks": [
                      {
                        "id": "cbe-1",
                        "order_key": "1001",
                        "psp": "niftipayp1",
                        "order_status": "chargeback",
                        "amount_cents": 10000,
                        "currency": "EUR",
                        "fee_cents": 3500,
                        "fee_currency": "EUR",
                        "dispute_amount_cents": 8487,
                        "dispute_currency": "GBP",
                        "disputed_at": "2026-09-01T08:00:00.000Z",
                        "created_at": "2026-09-02T10:00:00.000Z"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:read"
        ]
      }
    },
    "/api/v1/partner/fiat-orders/{orderKey}/chargebacks": {
      "get": {
        "operationId": "getFiatOrdersByChargebacks",
        "summary": "Chargebacks",
        "description": "The disputes on a single order, newest first, with no customer id in the path — a partner holding nothing but the order_key can ask. An order you cannot see answers with an empty list rather than a 404: either way the answer is \"no chargebacks\", so there is no second signal worth protecting here. bash curl https://www.niftipay.com/api/v1/partner/fiat-orders/1001/chargebacks \\ -H \"Authorization: Be",
        "tags": [
          "API Reference"
        ],
        "parameters": [
          {
            "name": "orderKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "chargebacks": [
                      {
                        "id": "cbe-1",
                        "order_key": "1001",
                        "psp": "niftipayp1",
                        "order_status": "chargeback",
                        "amount_cents": 10000,
                        "currency": "EUR",
                        "fee_cents": 3500,
                        "fee_currency": "EUR",
                        "dispute_amount_cents": 8487,
                        "dispute_currency": "GBP",
                        "disputed_at": "2026-09-01T08:00:00.000Z",
                        "created_at": "2026-09-02T10:00:00.000Z"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/orders": {
      "post": {
        "operationId": "postCustomersByOrders",
        "summary": "Create a crypto order",
        "description": "Creates a crypto payment. Unlike the fiat rail, a duplicate reference is replayed rather than refused: the same reference for this customer returns the original order.",
        "tags": [
          "Crypto Orders"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Response `201`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "order": {
                      "id": "ord_1",
                      "reference": "CRY-1",
                      "network": "ETH",
                      "asset": "USDT",
                      "amount": "100.00000000",
                      "currency": "EUR",
                      "status": "pending",
                      "address": "0xdeadbeef",
                      "paymentUri": "ethereum:0xdeadbeef?amount=100",
                      "qrUrl": "https://qr.example.com/1",
                      "createdAt": "2026-08-21T10:00:00.000Z",
                      "expiresAt": "2026-08-21T11:00:00.000Z"
                    },
                    "replayed": false
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "orders:create"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "reference": "CRY-1",
                "network": "ETH",
                "asset": "USDT",
                "amount": 100,
                "currency": "EUR",
                "firstName": "Ada",
                "lastName": "Lovelace",
                "email": "ada@example.com",
                "phone": "+34600111222",
                "country": "ES"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getCustomersByOrders",
        "summary": "List a customer's crypto orders",
        "description": "Newest first. Returns only orders minted by this partner relationship — a partner never sees another partner's orders, even though both share the merchant's underlying account. bash curl \"https://www.niftipay.com/api/v1/partner/customers/pc-1/orders?limit=25\" \\ -H \"Authorization: Bearer \"",
        "tags": [
          "Crypto Orders"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "orders": [
                      {
                        "id": "7d1dcdd4-9f3a-4c21-8f0e-2b1c9a5d4e10",
                        "reference": "CRY-1042",
                        "network": "ETH",
                        "asset": "USDT",
                        "amount": "116.751879",
                        "totalToSend": "116.751879",
                        "networkFees": null,
                        "currency": "EUR",
                        "fiatAmount": "100",
                        "address": "0x49d83b0d1f2c4a6e8b7d5c3a9f1e0d2b4c6a8e70",
                        "paymentUri": "ethereum:0x49d83b0d?contract=0xdAC17F&amount=116.751879",
                        "qrUrl": "https://www.niftipay.com/api/qr?data=ethereum%3A0x49d83b0d",
                        "status": "pending",
                        "createdAt": "2026-08-27T09:12:02.923Z",
                        "expiresAt": "2026-08-27T21:12:02.923Z"
                      }
                    ],
                    "next_cursor": "b3JkOjE3NjQyMzc1MjI5MjM6N2QxZGNkZDQ"
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "orders:read"
        ]
      }
    },
    "/api/v1/partner/orders/{orderId}": {
      "get": {
        "operationId": "getOrdersBy",
        "summary": "Retrieve a crypto order",
        "description": "bash curl https://www.niftipay.com/api/v1/partner/orders/ord_1 \\ -H \"Authorization: Bearer \" Partners may only fetch orders they can see; a hit and a miss are indistinguishable (404 resource_not_found) to avoid leaking existence.",
        "tags": [
          "Crypto Orders"
        ],
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "order": {
                      "id": "ord_1",
                      "reference": "CRY-1",
                      "network": "ETH",
                      "asset": "USDT",
                      "amount": "100.00000000",
                      "currency": "EUR",
                      "status": "pending",
                      "address": "0xdeadbeef",
                      "paymentUri": "ethereum:0xdeadbeef?amount=100",
                      "qrUrl": "https://qr.example.com/1",
                      "createdAt": "2026-08-21T10:00:00.000Z",
                      "expiresAt": "2026-08-21T11:00:00.000Z"
                    },
                    "partner_customer_id": "pc-1"
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "orders:read"
        ]
      }
    },
    "/api/v1/partner/customers": {
      "post": {
        "operationId": "postCustomers",
        "summary": "Create a customer",
        "description": "Links a partner's external customer to the merchant ledger.",
        "tags": [
          "Customers"
        ],
        "parameters": [],
        "responses": {
          "201": {
            "description": "Response `201`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "partner_customer_id": "pc-1",
                    "customer_id": "user_abc",
                    "external_customer_id": "cust_42",
                    "relationship_status": "active",
                    "created_at": "2026-08-01T00:00:00.000Z",
                    "customer": {
                      "email": "buyer@example.com",
                      "name": null,
                      "country": null,
                      "created_at": null
                    }
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "customers:write"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "external_customer_id": "cust_42",
                "email": "buyer@example.com"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getCustomers",
        "summary": "List customers",
        "description": "Returns the partner's customers (cursor-paginated). bash curl https://www.niftipay.com/api/v1/partner/customers \\ -H \"Authorization: Bearer \" | Query | Type | Notes | |--------------|--------|---------------------------| | limit | int | Page size (default 50). | | cursor | string | Opaque cursor from prior response. |",
        "tags": [
          "Customers"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "customers": [
                      {
                        "partner_customer_id": "pc-1",
                        "customer_id": "user_abc",
                        "external_customer_id": "cust_42",
                        "relationship_status": "active",
                        "created_at": "2026-08-01T00:00:00.000Z",
                        "customer": {
                          "email": "buyer@example.com",
                          "name": null,
                          "country": null,
                          "created_at": null
                        }
                      }
                    ],
                    "next_cursor": null
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "customers:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}": {
      "get": {
        "operationId": "getCustomersBy",
        "summary": "Retrieve a customer",
        "description": "bash curl https://www.niftipay.com/api/v1/partner/customers/pc-1 \\ -H \"Authorization: Bearer \"",
        "tags": [
          "Customers"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "partner_customer_id": "pc-1",
                    "customer_id": "user_abc",
                    "external_customer_id": "cust_42",
                    "relationship_status": "active",
                    "created_at": "2026-08-01T00:00:00.000Z",
                    "customer": {
                      "email": "buyer@example.com",
                      "name": null,
                      "country": null,
                      "created_at": null
                    }
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "customers:read"
        ]
      }
    },
    "/api/v1/partner/documents/{documentId}/download": {
      "get": {
        "operationId": "getDocumentsByDownload",
        "summary": "Download a document",
        "description": "Returns a short-lived URL to the bytes rather than the bytes themselves. The URL is scoped to the calling partner: a document belonging to another partner (or an unknown id) returns the same 404, so existence cannot be probed.",
        "tags": [
          "Documents"
        ],
        "parameters": [
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "document": {
                      "document_id": "doc-1",
                      "document_type": "certificate_of_incorporation",
                      "file_name": "cert.pdf",
                      "mime_type": "application/pdf",
                      "file_size_bytes": 1024,
                      "status": "uploaded",
                      "rejection_reason": null,
                      "submitted_by_partner_id": "client-1",
                      "uploaded_at": "2026-08-18T09:00:00.000Z"
                    },
                    "download_url": "https://www.trapyfy.com/api/platform/onboarding/documents/download?applicationId=app-1&documentId=doc-1&token=tok",
                    "expires_at": "2026-08-19T10:15:00.000Z"
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "documents:read",
          "kyb:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/documents": {
      "get": {
        "operationId": "getCustomersByDocuments",
        "summary": "List documents",
        "description": "Returns evidence metadata for the customer. Bytes require the same documents:read scope and a separate download call (see Download a document). The blobUrl is never returned here. An empty list is a valid answer — it means the customer has contributed no evidence yet.",
        "tags": [
          "Documents"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "documents": [
                      {
                        "document_id": "doc-1",
                        "document_type": "proof_of_address",
                        "file_name": "poa.pdf",
                        "mime_type": "application/pdf",
                        "file_size_bytes": 1024,
                        "status": "uploaded",
                        "rejection_reason": "Illegible scan",
                        "submitted_by_partner_id": "client-1",
                        "uploaded_at": "2026-08-18T09:00:00.000Z"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "documents:read"
        ]
      },
      "post": {
        "operationId": "postCustomersByDocuments",
        "summary": "Upload a document",
        "description": "Contributes one piece of KYB evidence for your customer. This is the endpoint that carries Flow A from \"the business fields are filled in\" to \"the case can be reviewed\": a verification is only submitted once the required documents exist.",
        "tags": [
          "Documents"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Response `201`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "document": {
                      "document_id": "ba189d7e-702d-4139-9a46-8c0a8e8a1c00",
                      "document_type": "certificate_of_incorporation",
                      "file_name": "incorporation.pdf",
                      "mime_type": "application/pdf",
                      "file_size_bytes": 459,
                      "status": "uploaded",
                      "rejection_reason": null,
                      "submitted_by_partner_id": "client-1",
                      "uploaded_at": "2026-08-27T09:44:52.433Z"
                    }
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "documents:write"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/fiat-integrations": {
      "post": {
        "operationId": "postCustomersByFiatIntegrations",
        "summary": "Create a fiat integration",
        "description": "Creates a new checkout configuration for your customer. Use one per storefront that needs its own return destination. Like the rest of this resource, it is not gated on payments.fiat_card, so you can set an integration up while the customer's KYB is still pending.",
        "tags": [
          "Fiat Integrations"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Those four fields are the whole surface",
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "message": "`psp` is not a settable field on a fiat integration. Settable fields are: name, return_url, failure_url, contact_url.",
                    "request_id": "req-1",
                    "details": [
                      {
                        "field": "psp",
                        "reason": "unknown_field"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:create"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "storefront-eu",
                "return_url": "https://shop.test/done",
                "failure_url": "https://shop.test/oops",
                "contact_url": "https://shop.test/support"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getCustomersByFiatIntegrations",
        "summary": "List fiat integrations",
        "description": "An integration is one checkout configuration belonging to your customer: a name, and the URLs a buyer is sent to after paying or failing. Its integration_id is the value Create a fiat card order requires. Every customer starts with one integration seeded at signup, so this list is never empty for a live customer.",
        "tags": [
          "Fiat Integrations"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "integrations": [
                      {
                        "integration_id": "03c9bad0-3174-4def-8d88-651693617c39",
                        "name": "trapyfy",
                        "psp": "niftipayp1",
                        "return_url": "https://shop.test/done",
                        "failure_url": "https://shop.test/oops",
                        "contact_url": null,
                        "created_at": "2026-08-26T15:10:19.465Z",
                        "updated_at": null
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/fiat-integrations/{integrationId}": {
      "delete": {
        "operationId": "deleteCustomersByFiatIntegrationsBy",
        "summary": "Delete a fiat integration",
        "description": "Removes an integration from your customer.",
        "tags": [
          "Fiat Integrations"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "integrationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "deleted": true,
                    "integration_id": "95d92bb0-65a4-462f-ae14-90be85bea223"
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:create"
        ]
      },
      "get": {
        "operationId": "getCustomersByFiatIntegrationsBy",
        "summary": "Retrieve a fiat integration",
        "description": "Returns one integration. Same object as a list entry.",
        "tags": [
          "Fiat Integrations"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "integrationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "integration": {
                      "integration_id": "95d92bb0-65a4-462f-ae14-90be85bea223",
                      "name": "storefront-eu",
                      "psp": "niftipayp1",
                      "return_url": "https://shop.test/done",
                      "failure_url": "https://shop.test/oops",
                      "contact_url": null,
                      "created_at": "2026-08-27T08:53:29.538Z",
                      "updated_at": "2026-08-27T08:53:40.151Z"
                    }
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:read"
        ]
      },
      "patch": {
        "operationId": "patchCustomersByFiatIntegrationsBy",
        "summary": "Update a fiat integration",
        "description": "Changes named fields on an existing integration. Fields you omit are left alone.",
        "tags": [
          "Fiat Integrations"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "integrationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "integration": {
                      "integration_id": "95d92bb0-65a4-462f-ae14-90be85bea223",
                      "name": "storefront-eu-v2",
                      "psp": "niftipayp1",
                      "return_url": "https://shop.test/done",
                      "failure_url": "https://shop.test/oops",
                      "contact_url": "https://shop.test/support",
                      "created_at": "2026-08-27T08:53:29.538Z",
                      "updated_at": "2026-08-27T08:53:40.151Z"
                    }
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:create"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "storefront-eu-v2",
                "contact_url": "https://shop.test/support"
              }
            }
          }
        }
      }
    },
    "/api/v1/partner/customers/{customerId}/fiat-orders": {
      "post": {
        "operationId": "postCustomersByFiatOrders",
        "summary": "Create a fiat card order",
        "description": "Creates a card payment on behalf of the customer.",
        "tags": [
          "Fiat Orders"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Response `201`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "fiat_order": {
                      "order_key": "1001",
                      "status": "new",
                      "currency": "EUR",
                      "amount_cents": 1000,
                      "service_fee_cents": 25,
                      "total_cents": 1025,
                      "merchant_reference": "INV-1",
                      "created_at": "2026-08-24T10:00:00.000Z",
                      "updated_at": null
                    },
                    "pay_url": "https://psp.test/pay/1001"
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:create"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "integration_id": "int-1",
                "amount_cents": 1000,
                "currency": "EUR",
                "reference": "INV-1",
                "return_url": "https://shop.test/done",
                "failure_url": "https://shop.test/oops",
                "email": "ada@example.com",
                "first_name": "Ada",
                "last_name": "Lovelace",
                "phone": "+34600111222",
                "country": "ES"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getCustomersByFiatOrders",
        "summary": "List a customer's fiat orders",
        "description": "Returns only orders minted by this partner relationship. A partner can never see another partner's orders (they share the merchant's userId). bash curl https://www.niftipay.com/api/v1/partner/customers/pc-1/fiat-orders \\ -H \"Authorization: Bearer \"",
        "tags": [
          "Fiat Orders"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "fiat_orders": [
                      {
                        "order_key": "1001",
                        "status": "new",
                        "amount_cents": 1000,
                        "refunded_cents": 0,
                        "chargeback_cents": 0
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:read"
        ]
      }
    },
    "/api/v1/partner/fiat-orders/{orderKey}/refunds": {
      "post": {
        "operationId": "postFiatOrdersByRefunds",
        "summary": "Refund a fiat order",
        "description": "Sends money back to the buyer who paid the order — fully, or partially, as many times as the remaining balance allows. The identifier is order_key, the short integer returned on the order, and there is no customer id in the path: a partner that stored nothing but the key can refund. Refunds are issued against the processor that took the payment, on the merchant account that holds the order. You ne",
        "tags": [
          "Fiat Orders"
        ],
        "parameters": [
          {
            "name": "orderKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Response `201`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "order_key": "1001",
                    "currency": "EUR",
                    "refund": {
                      "amount_cents": 400,
                      "status": "partially_refunded"
                    },
                    "service_fee_payer": "customer",
                    "max_refundable_cents": 1025,
                    "refunded_cents": 400,
                    "remaining_refundable_cents": 625
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "refunds:write"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "amount_cents": 400,
                "description": "Item returned"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getFiatOrdersByRefunds",
        "summary": "List an order's refunds",
        "description": "Every refund issued on one order, with what is still refundable. The figures come from the processor on each call, so a refund issued outside this API — from the merchant's own dashboard, or by our support — is included. bash curl https://www.niftipay.com/api/v1/partner/fiat-orders/1001/refunds \\ -H \"Authorization: Bearer \"",
        "tags": [
          "Fiat Orders"
        ],
        "parameters": [
          {
            "name": "orderKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "order_key": "1001",
                    "refunds": [
                      {
                        "id": "rf-1",
                        "amount_cents": 400,
                        "status": "refunded",
                        "created_at": "2026-10-02T09:15:00.000Z"
                      }
                    ],
                    "service_fee_payer": "customer",
                    "max_refundable_cents": 1025,
                    "refunded_cents": 400,
                    "remaining_refundable_cents": 625
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:read"
        ]
      }
    },
    "/api/v1/partner/fiat-orders/{orderKey}": {
      "get": {
        "operationId": "getFiatOrdersBy",
        "summary": "Retrieve a fiat order",
        "description": "The identifier is order_key — the short integer returned on the order — not the order's uuid. There is no customer id in the path, so an order can be read back by a partner that stored nothing but the key. bash curl https://www.niftipay.com/api/v1/partner/fiat-orders/1001 \\ -H \"Authorization: Bearer \"",
        "tags": [
          "Fiat Orders"
        ],
        "parameters": [
          {
            "name": "orderKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "fiat_order": {
                      "order_key": "1001",
                      "status": "new",
                      "currency": "EUR",
                      "amount_cents": 1000,
                      "service_fee_cents": 25,
                      "total_cents": 1025,
                      "merchant_reference": "INV-1",
                      "refunded_cents": 0,
                      "chargeback_cents": 0,
                      "created_at": "2026-08-24T10:00:00.000Z",
                      "updated_at": null
                    },
                    "partner_customer_id": "pc-1"
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payments:read"
        ]
      }
    },
    "/api/v1/partner/onboarding/schema": {
      "get": {
        "operationId": "getOnboardingSchema",
        "summary": "Onboarding schema",
        "description": "Our KYB field set, as data. Build your onboarding form from this response instead of hardcoding seventeen industry strings that drift the day we add one.",
        "tags": [
          "Onboarding schema"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success"
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "partner:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/payout-wallets/{walletId}": {
      "post": {
        "operationId": "postCustomersByPayoutWalletsBy",
        "summary": "Set payout wallet / replace / restore",
        "description": "",
        "tags": [
          "Payout Wallets"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "walletId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "`set_payout` — make this the payout wallet",
            "content": {
              "application/json": {
                "example": {
                  "action": "set_payout",
                  "acknowledged": true
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html"
      },
      "delete": {
        "operationId": "deleteCustomersByPayoutWalletsBy",
        "summary": "Archive a payout wallet",
        "description": "Archives the wallet. It stays in the book as status: \"archived\" for history, and keeps its address reserved: a later create or replace with that same address answers 409 conflict. To use it again, bring the wallet itself back with restore rather than adding a second row. The current payout wallet cannot be archived — set another wallet as payout first, or use replace.",
        "tags": [
          "Payout Wallets"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "walletId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          }
        },
        "x-error-envelope": "/getting-started/errors.html"
      },
      "patch": {
        "operationId": "patchCustomersByPayoutWalletsBy",
        "summary": "Rename a payout wallet",
        "description": "Changes the label only. Address, chain and history are untouched. Counts toward the 24-hour change limit. bash curl -X PATCH https://www.niftipay.com/api/v1/partner/customers/{customerId}/payout-wallets/{walletId} \\ -H \"Authorization: Bearer \" \\ -H \"Idempotency-Key: \" \\ -H \"X-Withdrawal-Signature: \" \\ -H \"Content-Type: application/json\" \\ -d '{ \"label\": \"Treasury USDT\" }'",
        "tags": [
          "Payout Wallets"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "walletId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "label": "Treasury USDT"
              }
            }
          }
        }
      }
    },
    "/api/v1/partner/customers/{customerId}/payout-wallets": {
      "post": {
        "operationId": "postCustomersByPayoutWallets",
        "summary": "Add a payout wallet",
        "description": "Adds a wallet to the customer's book. The first wallet in an empty book becomes the payout wallet; otherwise the payout wallet is unchanged — use set as payout wallet after the 24-hour cooling-off.",
        "tags": [
          "Payout Wallets"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "chain": "TRC20",
                "asset": "USDT",
                "address": "TXYZ…",
                "label": "Main USDT",
                "acknowledged": true
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getCustomersByPayoutWallets",
        "summary": "List payout wallets",
        "description": "Returns the customer's fiat payout wallet book: the stablecoin wallets its fiat settlements are paid to. Exactly one active wallet has is_payout_wallet: true once the book is set up. Archived wallets are included so you can reconcile history. Reading the book does not require the merchant to be currently eligible to transact.",
        "tags": [
          "Payout Wallets"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "wallets": [
                      {
                        "id": "7c1e…",
                        "label": "Main USDT",
                        "chain": "TRC20",
                        "asset": "USDT",
                        "address": "TXYZ…",
                        "destination_tag": null,
                        "status": "active",
                        "is_payout_wallet": true,
                        "created_at": "2026-09-01T10:00:00.000Z",
                        "archived_at": null
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html"
      }
    },
    "/api/v1/partner/customers/{customerId}/payouts": {
      "get": {
        "operationId": "getCustomersByPayouts",
        "summary": "List a customer's payouts",
        "description": "Newest first. Merges two legs onto one timeline: forecast rows (status: \"upcoming\", not yet run) and history rows (every payout that has already been executed). A read of this endpoint is exempt from the merchant-eligibility gate — a lapsed KYB grace does not take a merchant's own settlement history offline for the partner that most needs it to reconcile. bash curl \"https://www.niftipay.com/api/v1",
        "tags": [
          "Payouts"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "payouts": [
                      {
                        "id": "upcoming_usr_a1b2c3d4_2026-10-15_EUR",
                        "status": "upcoming",
                        "currency": "EUR",
                        "net_cents": 128900,
                        "net_eur_cents": 128900,
                        "payout_due_at": "2026-10-15T00:00:00.000Z",
                        "paid_at": null,
                        "created_at": "2026-10-01T00:00:03.000Z",
                        "orders_count": 14
                      },
                      {
                        "id": "7d1dcdd4-9f3a-4c21-8f0e-2b1c9a5d4e10",
                        "status": "paid",
                        "currency": "EUR",
                        "net_cents": 483210,
                        "net_eur_cents": 483210,
                        "payout_due_at": "2026-09-30T00:00:00.000Z",
                        "paid_at": "2026-09-30T08:12:44.000Z",
                        "created_at": "2026-09-23T00:00:05.000Z",
                        "orders_count": 0
                      }
                    ],
                    "next_cursor": "MjAyNi0xMC0xNVQwMDowMDowMC4wMDBafHVwY29taW5nX3Vzcl9hMWIyYzNkNF8yMDI2LTEwLTE1X0VVUg"
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payouts:read"
        ]
      }
    },
    "/api/v1/partner/payouts/{payoutId}": {
      "get": {
        "operationId": "getPayoutsBy",
        "summary": "Retrieve a payout",
        "description": "Top-level, not nested under the customer — matching /api/v1/partner/orders/{orderId}: a payout id is globally unique, so requiring the caller to also know which customer it belongs to would add a lookup the caller often cannot do. {payoutId} accepts either id form the list endpoint hands out: - a real payout id, opaque — treat it as a token, not a value to construct or parse, or - a forecast id, u",
        "tags": [
          "Payouts"
        ],
        "parameters": [
          {
            "name": "payoutId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "payout": {
                      "id": "7d1dcdd4-9f3a-4c21-8f0e-2b1c9a5d4e10",
                      "status": "paid",
                      "currency": "EUR",
                      "net_cents": 483210,
                      "net_eur_cents": 483210,
                      "payout_due_at": "2026-09-30T00:00:00.000Z",
                      "paid_at": "2026-09-30T08:12:44.000Z",
                      "created_at": "2026-09-23T00:00:05.000Z",
                      "updated_at": "2026-09-30T08:12:44.000Z",
                      "orders_count": 3,
                      "payout_asset": "USDT",
                      "payout_asset_amount": "5232.45",
                      "payout_asset_rate_eur": 0.9238,
                      "payout_asset_decimals": 6,
                      "orders": [
                        {
                          "id": "9c1f2b3a-4d5e-6f70-8192-a3b4c5d6e7f8",
                          "order_key": "CRY-1042",
                          "merchant_reference": "INV-2026-0091",
                          "currency": "EUR",
                          "amount_cents": 210000,
                          "subtotal_cents": 205000,
                          "payable_now_cents": 210000,
                          "created_at": "2026-09-24T11:02:00.000Z",
                          "completed_at": "2026-09-24T11:08:41.000Z"
                        }
                      ],
                      "calculation": {
                        "orders_count": 3,
                        "gross_cents": 512000,
                        "fee_cents": 15360,
                        "retention_hold_cents": 10000,
                        "matured_retention_cents": null,
                        "deductions_cents": 3430,
                        "deduction_items": [
                          {
                            "reason": "chargeback",
                            "cents": 3430,
                            "currency": "EUR",
                            "source_id": "cb_2f1a9c",
                            "forfeited_at": "2026-09-27T09:15:00.000Z"
                          }
                        ],
                        "period_start": "2026-09-16T00:00:00.000Z",
                        "period_end": "2026-09-23T00:00:00.000Z",
                        "settlement_days": 7,
                        "settlement_cutoff": "2026-09-23T23:59:59.999Z"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "payouts:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/requirements": {
      "get": {
        "operationId": "getCustomersByRequirements",
        "summary": "Requirements",
        "description": "A requirement is one thing still outstanding on a KYB case, after it was submitted. Before this existed, the only way to ask for anything post-submission was to reject the whole case: you received one coarse rejection_reason, so \"an identity document for the second UBO\" arrived as documents_missing and you had to guess. A requirement names its own target, carries its own status and resolves on its",
        "tags": [
          "Requirements"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The object",
            "content": {
              "application/json": {
                "example": {
                  "requirement_id": "102b4aa0-05f2-439a-88fd-aabb0adf6e7d",
                  "kind": "document",
                  "target": "ubo:1",
                  "document_type": "director_id",
                  "message": "Identity document for the second UBO",
                  "status": "open",
                  "raised_by": "you",
                  "document_id": null,
                  "due_at": null,
                  "created_at": "2026-08-27T12:28:19.696Z",
                  "updated_at": null,
                  "resolved_at": null
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "kyb:read",
          "kyb:write"
        ]
      },
      "post": {
        "operationId": "postCustomersByRequirements",
        "summary": "Requirements",
        "description": "A requirement is one thing still outstanding on a KYB case, after it was submitted. Before this existed, the only way to ask for anything post-submission was to reject the whole case: you received one coarse rejection_reason, so \"an identity document for the second UBO\" arrived as documents_missing and you had to guess. A requirement names its own target, carries its own status and resolves on its",
        "tags": [
          "Requirements"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "The object",
            "content": {
              "application/json": {
                "example": {
                  "requirement_id": "102b4aa0-05f2-439a-88fd-aabb0adf6e7d",
                  "kind": "document",
                  "target": "ubo:1",
                  "document_type": "director_id",
                  "message": "Identity document for the second UBO",
                  "status": "open",
                  "raised_by": "you",
                  "document_id": null,
                  "due_at": null,
                  "created_at": "2026-08-27T12:28:19.696Z",
                  "updated_at": null,
                  "resolved_at": null
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "kyb:read",
          "kyb:write"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "kind": "document",
                "target": "ubo:1",
                "document_type": "director_id",
                "message": "Identity document for the second UBO",
                "due_at": "2026-09-10T00:00:00.000Z"
              }
            }
          }
        }
      }
    },
    "/api/v1/partner/customers/{customerId}/requirements/{requirementId}": {
      "get": {
        "operationId": "getCustomersByRequirementsBy",
        "summary": "Requirements",
        "description": "A requirement is one thing still outstanding on a KYB case, after it was submitted. Before this existed, the only way to ask for anything post-submission was to reject the whole case: you received one coarse rejection_reason, so \"an identity document for the second UBO\" arrived as documents_missing and you had to guess. A requirement names its own target, carries its own status and resolves on its",
        "tags": [
          "Requirements"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "requirementId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The object",
            "content": {
              "application/json": {
                "example": {
                  "requirement_id": "102b4aa0-05f2-439a-88fd-aabb0adf6e7d",
                  "kind": "document",
                  "target": "ubo:1",
                  "document_type": "director_id",
                  "message": "Identity document for the second UBO",
                  "status": "open",
                  "raised_by": "you",
                  "document_id": null,
                  "due_at": null,
                  "created_at": "2026-08-27T12:28:19.696Z",
                  "updated_at": null,
                  "resolved_at": null
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "kyb:read",
          "kyb:write"
        ]
      },
      "patch": {
        "operationId": "patchCustomersByRequirementsBy",
        "summary": "Requirements",
        "description": "A requirement is one thing still outstanding on a KYB case, after it was submitted. Before this existed, the only way to ask for anything post-submission was to reject the whole case: you received one coarse rejection_reason, so \"an identity document for the second UBO\" arrived as documents_missing and you had to guess. A requirement names its own target, carries its own status and resolves on its",
        "tags": [
          "Requirements"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "requirementId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The object",
            "content": {
              "application/json": {
                "example": {
                  "requirement_id": "102b4aa0-05f2-439a-88fd-aabb0adf6e7d",
                  "kind": "document",
                  "target": "ubo:1",
                  "document_type": "director_id",
                  "message": "Identity document for the second UBO",
                  "status": "open",
                  "raised_by": "you",
                  "document_id": null,
                  "due_at": null,
                  "created_at": "2026-08-27T12:28:19.696Z",
                  "updated_at": null,
                  "resolved_at": null
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "kyb:read",
          "kyb:write"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "kind": "document",
                "target": "ubo:1",
                "document_type": "director_id",
                "message": "Identity document for the second UBO",
                "due_at": "2026-09-10T00:00:00.000Z"
              }
            }
          }
        }
      }
    },
    "/api/v1/partner/customers/{customerId}/verifications": {
      "post": {
        "operationId": "postCustomersByVerifications",
        "summary": "Create a verification",
        "description": "Writes structured KYB data for the customer, then attempts to submit the case every time. Once the five required documents exist and the form is complete, the next POST carries the case into review — so \"submit\" is never a separate verb to forget. A submission blocked by missing evidence or an incomplete form is not an error: the response reports submitted: false and what is outstanding, and you r",
        "tags": [
          "Verifications"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "verification": {
                      "verification_id": "app-1",
                      "partner_customer_id": "pc-1",
                      "type": "kyb",
                      "status": "unverified",
                      "submitted_at": null,
                      "verified_at": null,
                      "valid_until": null,
                      "source": "niftipay",
                      "reusable": false,
                      "reuse_policy": "none",
                      "document_access": "restricted",
                      "created_at": "2026-08-01T00:00:00.000Z",
                      "updated_at": null,
                      "attributes": {
                        "legal_name": "Example SL",
                        "registration_number": "B123",
                        "trading_name": null,
                        "website": null,
                        "industry": null,
                        "registered_address_line1": null,
                        "registered_address_line2": null,
                        "registered_city": null,
                        "registered_postal_code": null,
                        "registered_country": null,
                        "incorporation_country": null,
                        "incorporation_date": null,
                        "business_registration_country": null
                      },
                      "directors": [],
                      "ubos": []
                    },
                    "submitted": false,
                    "blocked_by": "missing_documents",
                    "missing_documents": [
                      "proof_of_address",
                      "director_id"
                    ],
                    "incomplete_fields": []
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "kyb:write"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "business": {
                  "legal_name": "Example SL",
                  "registration_number": "B123"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getCustomersByVerifications",
        "summary": "List verifications",
        "description": "Returns the customer's single KYB case plus its status-transition history. A customer that has never started a verification gets 404, not an empty case.",
        "tags": [
          "Verifications"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "verifications": [
                      {
                        "verification_id": "app-1",
                        "partner_customer_id": "pc-1",
                        "type": "kyb",
                        "status": "unverified",
                        "submitted_at": null,
                        "verified_at": null,
                        "valid_until": null,
                        "source": "niftipay",
                        "reusable": false,
                        "reuse_policy": "none",
                        "document_access": "restricted",
                        "created_at": "2026-08-01T00:00:00.000Z",
                        "updated_at": null,
                        "attributes": {
                          "legal_name": "Example SL",
                          "registration_number": "B123",
                          "trading_name": null,
                          "website": null,
                          "industry": null,
                          "registered_address_line1": null,
                          "registered_address_line2": null,
                          "registered_city": null,
                          "registered_postal_code": null,
                          "registered_country": null,
                          "incorporation_country": null,
                          "incorporation_date": null,
                          "business_registration_country": null
                        },
                        "directors": [],
                        "ubos": []
                      }
                    ],
                    "history": [
                      {
                        "status": "kyb_submitted",
                        "occurred_at": "2026-08-10T10:00:00.000Z"
                      },
                      {
                        "status": "kyb_approved",
                        "occurred_at": "2026-08-12T14:08:00.000Z"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "kyb:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/verifications/{verificationId}": {
      "get": {
        "operationId": "getCustomersByVerificationsBy",
        "summary": "Retrieve a verification",
        "description": "Returns one KYB case and its status-transition history. A customer has exactly one KYB case, so this and List verifications return the same case — the list wraps it in an array, this returns it directly. Use whichever fits how you stored it: the list if you only kept the customer id, this if you kept the verification_id.",
        "tags": [
          "Verifications"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "verificationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "verification": {
                      "verification_id": "app-1",
                      "partner_customer_id": "pc-1",
                      "type": "kyb",
                      "status": "approved",
                      "submitted_at": "2026-08-10T10:00:00.000Z",
                      "verified_at": "2026-08-12T14:08:00.000Z",
                      "valid_until": null,
                      "source": "niftipay",
                      "reusable": false,
                      "reuse_policy": "none",
                      "document_access": "restricted",
                      "created_at": "2026-08-01T00:00:00.000Z",
                      "updated_at": "2026-08-12T14:08:00.000Z",
                      "attributes": {
                        "legal_name": "Example SL",
                        "registration_number": "B123",
                        "trading_name": null,
                        "website": null,
                        "industry": null,
                        "registered_address_line1": null,
                        "registered_address_line2": null,
                        "registered_city": null,
                        "registered_postal_code": null,
                        "registered_country": null,
                        "incorporation_country": null,
                        "incorporation_date": null,
                        "business_registration_country": null
                      },
                      "directors": [],
                      "ubos": []
                    },
                    "history": [
                      {
                        "status": "kyb_submitted",
                        "occurred_at": "2026-08-10T10:00:00.000Z"
                      },
                      {
                        "status": "kyb_approved",
                        "occurred_at": "2026-08-12T14:08:00.000Z"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "kyb:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/wallets": {
      "post": {
        "operationId": "postCustomersByWallets",
        "summary": "Create customer wallets",
        "description": "Provisions the customer's persistent master wallet addresses, one per chain (BTC, ETH, LTC, SOL, XRP, TRON) on mainnet, and returns them. Call this once per customer; it is idempotent per chain.",
        "tags": [
          "Wallets"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Response `201`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "wallets": [
                      {
                        "chain": "BTC",
                        "address": "bc1qbtc",
                        "balance": "0.5",
                        "network": "mainnet"
                      },
                      {
                        "chain": "ETH",
                        "address": "0xeth",
                        "balance": "0",
                        "balanceUnavailable": true,
                        "tokens": {
                          "USDT": "0",
                          "USDC": "0"
                        },
                        "tokensUnavailable": [
                          "USDT"
                        ],
                        "network": "mainnet"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "wallets:write"
        ]
      },
      "get": {
        "operationId": "getCustomersByWallets",
        "summary": "List customer wallets",
        "description": "Returns the customer's master wallet addresses and balances across all chains.",
        "tags": [
          "Wallets"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "wallets": [
                      {
                        "chain": "BTC",
                        "address": "bc1qbtc",
                        "balance": "0.5",
                        "network": "mainnet"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "wallets:read"
        ]
      }
    },
    "/api/v1/partner/webhooks": {
      "get": {
        "operationId": "getWebhooks",
        "summary": "Webhooks",
        "description": "Answers \"am I subscribed, and to what\" without a support ticket. Everything it returns is a fact you supplied. bash curl https://www.niftipay.com/api/v1/partner/webhooks \\ -H \"Authorization: Bearer \"",
        "tags": [
          "API Reference"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "webhooks": [
                      {
                        "webhook_id": "wh_3f9a2c10",
                        "url": "https://you.example.com/hooks/niftipay",
                        "event_types": [
                          "verification.approved",
                          "payment.confirmed"
                        ],
                        "status": "active",
                        "created_at": "2026-08-01T10:00:00.000Z"
                      }
                    ],
                    "available_event_types": [
                      "customer.updated",
                      "verification.pending",
                      "..."
                    ],
                    "signature": {
                      "algorithm": "hmac-sha256",
                      "header": "x-signature",
                      "format": "v1=<hex>",
                      "signed_payload": "<x-timestamp>.<raw request body>"
                    }
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "partner:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/withdrawal-wallets": {
      "post": {
        "operationId": "postCustomersByWithdrawalWallets",
        "summary": "Register a withdrawal wallet",
        "description": "Adds a destination to the customer's withdrawal allowlist. This is the endpoint the signature really protects. A withdrawal can only send to an address already on the allowlist, so an attacker holding just your bearer token cannot move funds anywhere new — adding a destination needs the signature too. Needs both an Idempotency-Key and an X-Withdrawal-Signature; see Signing withdrawals.",
        "tags": [
          "Withdrawal Wallets"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Response `201`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "wallet": {
                      "id": "w-1",
                      "chain": "BTC",
                      "asset": "BTC",
                      "label": "Treasury",
                      "address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
                      "destination_tag": "12345",
                      "created_at": "2026-08-24T10:00:00.000Z",
                      "last_used_at": null
                    }
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "withdrawals:write"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "chain": "BTC",
                "asset": "BTC",
                "label": "Treasury",
                "address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
                "destination_tag": "12345"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getCustomersByWithdrawalWallets",
        "summary": "List withdrawal wallets",
        "description": "Returns the customer's registered withdrawal destinations (the allowlist). Reading the allowlist does not require the merchant to be currently eligible to transact.",
        "tags": [
          "Withdrawal Wallets"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "wallets": [
                      {
                        "id": "w-1",
                        "chain": "BTC",
                        "asset": "BTC",
                        "label": "Treasury",
                        "address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
                        "destination_tag": null,
                        "created_at": "2026-08-24T10:00:00.000Z",
                        "last_used_at": null
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "withdrawals:read"
        ]
      }
    },
    "/api/v1/partner/customers/{customerId}/withdrawals": {
      "post": {
        "operationId": "postCustomersByWithdrawals",
        "summary": "Create a withdrawal",
        "description": "Sends crypto from the customer's wallet to a registered destination. Needs both an Idempotency-Key and an X-Withdrawal-Signature. See Signing withdrawals for how to build the assertion — it is the same construction for both money-out endpoints. Register the destination with Register a withdrawal wallet first; to must match one that already exists for this customer.",
        "tags": [
          "Withdrawals"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "The merchant may have a minimum",
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "below_minimum",
                    "message": "The amount is below the minimum withdrawal this merchant is configured for. See `details[0].minimum_eur`.",
                    "request_id": "req-1",
                    "details": [
                      {
                        "minimum_eur": 300
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "withdrawals:write"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "chain": "BTC",
                "asset": "BTC",
                "amount": "0.5",
                "to": "bc1qdest"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getCustomersByWithdrawals",
        "summary": "List customer withdrawals",
        "description": "Returns the customer's recent withdrawals, newest first. Reading history does not require the merchant to be currently eligible to transact.",
        "tags": [
          "Withdrawals"
        ],
        "parameters": [
          {
            "name": "customerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "request_id": "req-1",
                  "api_version": "2026-08-01",
                  "data": {
                    "withdrawals": [
                      {
                        "id": "wd-1",
                        "created_at": "2026-08-24T10:00:00.000Z",
                        "chain": "BTC",
                        "asset": "BTC",
                        "gross": "0.5",
                        "fee": "0.001",
                        "to_address": "bc1qdest",
                        "tx_hash": "0xabc",
                        "status": "sent"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "x-required-scopes": [
          "withdrawals:read"
        ]
      }
    },
    "/api/oauth/token": {
      "post": {
        "operationId": "postApiOauthToken",
        "summary": "Authentication",
        "description": "Exchange your client credentials for a JWT using the OAuth client_credentials grant: bash curl -X POST https://www.niftipay.com/api/oauth/token \\ -H \"Content-Type: application/json\" \\ -d '{ \"grant_type\": \"client_credentials\", \"client_id\": \"\", \"client_secret\": \"\", \"scope\": \"customers:read customers:write payments:create ...\" }' The token response uses the same envelope as every other endpoint — the",
        "tags": [
          "Getting Started"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Response `200`",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "access_token": "<jwt>",
                    "expires_in": 300,
                    "token_type": "bearer"
                  },
                  "request_id": "req-1",
                  "api_version": "2026-08-01"
                }
              }
            }
          }
        },
        "x-error-envelope": "/getting-started/errors.html",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "grant_type": "client_credentials",
                "client_id": "<partner_client_id>",
                "client_secret": "<partner_client_secret>",
                "scope": "customers:read customers:write payments:create ..."
              }
            }
          }
        }
      }
    }
  }
}