BXNK Hosted Payment Page (HPP) - Sandbox Testing Guide

Hosted Payment Page Payments

Use the Hosted Payment Page (HPP) integration when BXNK should collect payment details from the customer. Your server creates the payment, then redirects the customer to the hostedPaymentUrl returned by the API.

All Product API endpoints are served under /api/v1/product-apis. Except for token creation, requests require Authorization: Bearer <accessToken>.

Crypto payments creates a vault deposit address for every request.


Base URL

Sandbox: https://sandbox-api.bxnk.com/

Your live base URL is available in the Partner Portal under API Keys — it's listed at the bottom of the page.

Authentication

Generate a Product API bearer token before calling payment or webhook endpoints.

POST /api/v1/product-apis/auth/token
Content-Type: application/json
NameTypeRequiredDescription
accessKeystringYesAPI access key. Must be a non-empty string.
secretstringYesAPI secret. Must be a non-empty string.
{
  "accessKey": "test_pk_1234567890",
  "secret": "test_sk_1234567890"
}
{
  "message": "Product API token generated successfully",
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "tokenType": "Bearer",
    "expiresAt": "2026-03-24T10:00:00.000Z"
  }
}

Use the returned token on subsequent requests:

Authorization: Bearer <accessToken>

Register a Webhook Endpoint

Register a webhook endpoint before creating payments so your server can receive lifecycle events.

Strongly recommended: register a webhook endpoint for every new MID as soon as it's created to receive real-time payment status updates.

POST /api/v1/product-apis/psp/webhooks
Authorization: Bearer <accessToken>
Content-Type: application/json

Parameters

NameTypeRequiredDescription
urlURLYesPublic URL that receives webhook POSTs.
mIdstringYesMID for this endpoint. Must belong to the authenticated PSP.
secretstringNoSigning secret. Must be length 6..255. If omitted, BXNK generates one.
isActivebooleanNoDefaults to true.

Request

{
  "mId": "MID-ABCDEFGHIJ",
  "url": "https://merchant.example/webhooks/bxnk",
  "secret": "whsec_my_signing_secret",
  "isActive": true
}

Response 201

{
  "message": "Webhook endpoint created successfully",
  "data": {
    "id": 1,
    "mId": "MID-ABCDEFGHIJ",
    "url": "https://merchant.example/webhooks/bxnk",
    "secret": "whsec_my_signing_secret",
    "isActive": true,
    "createdAt": "2026-03-20T10:00:00.000Z",
    "updatedAt": "2026-03-20T10:00:00.000Z"
  }
}

BXNK includes secret only when an endpoint is created or rotated. List and status update responses omit it.

Rotate a Webhook Secret

POST /api/v1/product-apis/psp/webhooks/{endpointId}/rotate-secret
Authorization: Bearer <accessToken>
{
  "message": "Webhook endpoint secret rotated successfully",
  "data": {
    "id": 1,
    "mId": "MID-ABCDEFGHIJ",
    "secret": "whsec_new_signing_secret",
    "updatedAt": "2026-03-20T10:15:00.000Z"
  }
}

Create an HPP Payment

Create a payment with useHostedPaymentPage: true. The response includes hostedPaymentUrl; redirect the customer's browser to that exact value.

POST /api/v1/product-apis/payments
Authorization: Bearer <accessToken>
Content-Type: application/json
Idempotency-Key: order-1001-create

The Idempotency-Key header is optional. When present, BXNK reuses the first result for retries with the same request body.

Parameters

NameTypeRequiredDescription
amountnumberYesPayment amount. Must be at least 0.000005 and have no more than 8 decimal places.
currencystringYesCurrency code looked up by the backend. Must be a string with length 3..40; the service uppercases it before lookup.
paymentMethodstringConditionallyOne of card, crypto, or bank_transfer. Required when paymentMethods is omitted. Takes precedence if both fields are provided.
paymentMethodsstring[]ConditionallyNon-empty array of card, crypto, or bank_transfer. The first value is used when paymentMethod is omitted.
cardPaymentTypestringConditionallyRequired for card payments. Set to on_ramp for the provider-hosted on-ramp flow or native_on_ramp for the native BXNK checkout flow.
useHostedPaymentPagebooleanYesSet to true for HPP.
successUrlURLNoCallback URL used for success events and hosted redirects after success.
failureUrlURLNoCallback URL used for failed, cancelled, or expired events and hosted redirects after failure.
orderReferencestringNoMerchant order reference.
customerReferencestringNoMerchant customer reference.
expiryTimeISO 8601 stringNoFuture expiry timestamp. Invalid or past values return 400.
metadataobjectConditionallyAdditional metadata. Crypto and on-ramp payments require asset and network.
metadata.m_idstringNoMID to create the payment for. The MID embedded in the Product API bearer token is used automatically, so this key can be omitted when calling with a Product API token; it is only consulted as a fallback when the token carries no MID.
metadata.customerNamestringConditionallyCustomer full name, stored on the payment and returned in the response. Required for native on-ramp payments.
metadata.customerEmailstringConditionallyCustomer email, stored on the payment and returned in the response. Required for native on-ramp payments.
metadata.paymentMethodIdstringNoNative on-ramp payment method identifier. Use debit-credit-card for card collection or apple-pay for Apple Pay.
metadata.countrystringConditionallyCustomer's 2-letter ISO 3166-1 country code, for example AE. Required for native on-ramp payments. metadata.shippingCountry is accepted instead; metadata.country is used if both are sent.
metadata.statestringConditionally2-letter US state code, for example CA. Required for native on-ramp payments when the customer's country is US.
metadata.customerBirthDatestringConditionallyCustomer's date of birth, a past date in YYYY-MM-DD format. Required for native on-ramp payments.
metadata.billingStreet1stringConditionallyCustomer's street address. Required for native on-ramp payments; metadata.shippingStreet1 is accepted instead.
metadata.billingCitystringConditionallyCustomer's city. Required for native on-ramp payments; metadata.shippingCity is accepted instead.
metadata.billingPostcodestringConditionallyCustomer's postal code. Required for native on-ramp payments; metadata.shippingPostcode is accepted instead.
metadata.billingStatestringNoCustomer's state or region for the address. 2-letter code for US and Canada.
metadata.billingCountrystringNo2-letter ISO 3166-1 country code of the address. If sent, it must match metadata.country.

On-Ramp HPP

Use on-ramp only with paymentMethod: "card" and useHostedPaymentPage: true.

  1. Get the supported network and asset pairs.
  2. Use the selected networkCode as metadata.network and currencies[].name as metadata.asset.
  3. Create the HPP payment with cardPaymentType: "on_ramp", then redirect the customer to hostedPaymentUrl.
GET /api/v1/product-apis/on-ramp-networks
Authorization: Bearer <accessToken>
{
  "message": "On-ramp networks retrieved successfully",
  "data": [
    {
      "networkCode": "polygon",
      "networkName": "Polygon",
      "currencies": [{ "name": "USDC" }]
    }
  ]
}

The endpoint returns networks and assets for creating an on-ramp payment. Use the returned asset and network values; do not send an unsupported pair.

POST /api/v1/product-apis/payments
Authorization: Bearer <accessToken>
Content-Type: application/json
Idempotency-Key: order-1002-on-ramp
{
  "amount": 50,
  "currency": "EUR",
  "paymentMethod": "card",
  "cardPaymentType": "on_ramp",
  "useHostedPaymentPage": true,
  "successUrl": "https://merchant.example/payment/success",
  "failureUrl": "https://merchant.example/payment/failure",
  "metadata": {
    "asset": "USDC",
    "network": "polygon",
    "customerName": "FName LName",
    "customerEmail": "<email>"
  }
}

For on-ramp payments, Idempotency-Key, metadata.asset, and metadata.network are required. The selected payment currency and amount must be supported by the configured provider.

Native On-Ramp HPP

Use the native on-ramp flow when BXNK checkout should handle identity verification, card collection, and the on-ramp payment flow. Ask BXNK to enable native on-ramp for your account before creating a payment.

Use GET /api/v1/product-apis/on-ramp-networks to retrieve supported asset and network values, then create the payment with cardPaymentType: "native_on_ramp".

POST /api/v1/product-apis/payments
Authorization: Bearer <accessToken>
Content-Type: application/json
Idempotency-Key: order-1003-native-on-ramp
{
  "amount": 30,
  "currency": "EUR",
  "paymentMethod": "card",
  "cardPaymentType": "native_on_ramp",
  "useHostedPaymentPage": true,
  "customerReference": "customer-123",
  "successUrl": "https://example.com/success",
  "failureUrl": "https://example.com/failure",
  "redirectUrl": "https://example.com",
  "metadata": {
    "asset": "USDC",
    "network": "eth",
    "paymentMethodId": "debit-credit-card",
    "customerEmail": "[email protected]",
    "customerName": "FName LName",
    "customerBirthDate": "1990-05-21",
    "country": "AE",
    "billingStreet1": "Sheikh Zayed Road 21",
    "billingCity": "Dubai",
    "billingPostcode": "00000",
    "billingCountry": "AE"
  }
}

To let the customer pay with Apple Pay, set metadata.paymentMethodId to apple-pay; all other request fields stay the same. Apple Pay is available in Safari on iPhone, iPad, or Mac with a card in Apple Wallet; otherwise checkout shows a message asking the customer to switch device or browser. Identity verification works the same as for card payments.

"metadata": {
  "asset": "USDC",
  "network": "eth",
  "paymentMethodId": "apple-pay",
  "customerEmail": "[email protected]",
  "customerName": "FName LName",
  "customerBirthDate": "1990-05-21",
  "country": "AE",
  "billingStreet1": "Sheikh Zayed Road 21",
  "billingCity": "Dubai",
  "billingPostcode": "00000",
  "billingCountry": "AE"
}

For native on-ramp payments, Idempotency-Key, metadata.asset, metadata.network, metadata.customerEmail, metadata.customerName, metadata.customerBirthDate, metadata.country, and the customer's address (metadata.billingStreet1, metadata.billingCity, metadata.billingPostcode) are required. metadata.country is the customer's 2-letter ISO 3166-1 country code (for example AE); metadata.shippingCountry is accepted instead, and metadata.country is used if both are sent. metadata.customerBirthDate is the customer's date of birth in YYYY-MM-DD format and must be a past date. The address can be sent as metadata.shippingStreet1, metadata.shippingCity, and metadata.shippingPostcode instead; metadata.billingCountry or metadata.shippingCountry, if sent, must match metadata.country. For customers in the US, metadata.state (2-letter state code, for example CA) is also required. A request missing a required field, or with an invalid country or state, is rejected with a 400 error that names the field. Do not send card number, expiry date, CVV, card brand, attemptThreeD, or onRampExperience.

The customer starts identity verification in BXNK Checkout and is redirected to Sumsub to submit their details. When they return, the checkout waits for the review result and, if the payment eligibility requires more information, asks only for the missing details or supporting documents, such as proof of address, an identity document, or a selfie. After identity and eligibility checks are complete, the customer enters their card details in the embedded payment form; BXNK then confirms the payment result, shows the final status, and redirects the customer to the configured merchant URL when the payment completes.

Redirect the customer to data.hostedPaymentUrl from the create-payment response. Confirm the final result through BXNK webhooks or GET /api/v1/product-apis/payments/{paymentId}; returning to the success URL does not confirm completion.

Crypto HPP Request

Crypto HPP creation validates metadata.asset, metadata.network, and PSP wallet configuration before returning the hosted page URL. BXNK also enforces a minimum deposit amount, converted to USD using the current exchange rate for the requested asset; requests below that minimum return 400.

{
  "amount": 500,
  "currency": "USDT",
  "paymentMethod": "crypto",
  "useHostedPaymentPage": true,
  "successUrl": "https://merchant.example/payment/success",
  "failureUrl": "https://merchant.example/payment/failure",
  "metadata": {
    "m_id": "MID-ABCDEFGHIJ",
    "asset": "USDT",
    "network": "ethereum"
  }
}

Crypto HPP Response 201

{
  "message": "Payment created successfully",
  "data": {
    "paymentId": "PAY-x9y8z7w6v5u4",
    "status": "created",
    "amount": 500,
    "currency": "USDT",
    "paymentMethod": "crypto",
    "paymentFlow": "HPP",
    "orderReference": null,
    "customerReference": null,
    "hostedPaymentUrl": "https://pay.bxnk.example/UEFZLXg5eTh6N3c2djV1NA.signature",
    "expiresAt": null,
    "instructions": null,
    "transactionId": "tx_abc123def456",
    "mId": "MID-ABCDEFGHIJ",
    "walletAddress": "0x11d94ac1d603c28c03de643e5e67e66408f3ee89",
    "qrCodeUrl": "data:image/png;base64,iVBORw0KGgo...",
    "customerName": null,
    "customerEmail": null,
    "customerWallet": null,
    "createdAt": "2026-03-20T10:05:00.000Z",
    "successUrl": "https://merchant.example/payment/success",
    "failureUrl": "https://merchant.example/payment/failure",
    "redirectUrl": null,
    "declineReason": null
  }
}

The crypto engine allocates a real vault deposit address for every request (test and live), so walletAddress and qrCodeUrl are populated immediately on create, and instructions is null until the deposit is indexed. Once BXNK indexes an on-chain transfer to walletAddress, instructions is populated with the indexed transfer event (see the Verify Payment Status example below) and the payment transitions out of created.

SEPA HPP Request

For HPP SEPA, the create request stores the payment and returns the hosted page URL. The hosted page collects SEPA details and submits them before bank-transfer instructions are generated.

{
  "amount": 150.5,
  "currency": "EUR",
  "paymentMethod": "bank_transfer",
  "useHostedPaymentPage": true,
  "orderReference": "INV-1001",
  "customerReference": "CUSTOMER-42",
  "successUrl": "https://merchant.example/payment/success",
  "failureUrl": "https://merchant.example/payment/failure",
  "metadata": {
    "m_id": "MID-ABCDEFGHIJ"
  }
}

SEPA HPP Response 201

{
  "message": "Payment created successfully",
  "data": {
    "paymentId": "PAY-m3n4o5p6q7r8",
    "status": "created",
    "amount": 150.5,
    "currency": "EUR",
    "paymentMethod": "bank_transfer",
    "paymentFlow": "HPP",
    "orderReference": "INV-1001",
    "customerReference": "CUSTOMER-42",
    "hostedPaymentUrl": "https://pay.bxnk.example/UEFZLW0zbjRvNXA2cTdyOA.signature",
    "expiresAt": null,
    "instructions": null,
    "transactionId": null,
    "mId": "MID-ABCDEFGHIJ",
    "walletAddress": null,
    "qrCodeUrl": null,
    "customerName": null,
    "customerEmail": null,
    "customerWallet": null,
    "createdAt": "2026-03-20T10:05:00.000Z",
    "successUrl": "https://merchant.example/payment/success",
    "failureUrl": "https://merchant.example/payment/failure",
    "redirectUrl": null,
    "declineReason": null
  }
}

SEPA HPP payments are only supported in sandbox (TEST mode) today. Live SEPA S2S/HPP submission is not yet available; submitting a SEPA payment for a LIVE-mode API key fails with 400.


Redirect the Customer

After create payment succeeds, redirect the browser to data.hostedPaymentUrl.

window.location.href = response.data.hostedPaymentUrl;

Do not embed the hosted page in an iframe, and do not derive the URL from paymentId. The URL contains a signed token.

After payment completion, cancellation, failure, or expiry, the hosted flow uses the stored successUrl or failureUrl where applicable. Treat redirects as a user-experience signal only; verify final state with webhooks or GET /api/v1/product-apis/payments/{paymentId}.


Verify Payment Status

Returns payment details by ID.

GET /api/v1/product-apis/payments/{paymentId}
Authorization: Bearer <accessToken>

The response uses the same payment object shape returned by create payment.

Payment retrieval and status-check endpoints are each limited to 5 requests per second. For provider reconciliation, use GET /api/v1/product-apis/payments/{paymentId}/status-check for unfinished, failed, or expired payments when applicable; it may update the stored status.

{
  "message": "Payment retrieved successfully",
  "data": {
    "paymentId": "PAY-x9y8z7w6v5u4",
    "status": "processing",
    "amount": 500,
    "currency": "USDT",
    "paymentMethod": "crypto",
    "paymentFlow": "HPP",
    "orderReference": null,
    "customerReference": null,
    "hostedPaymentUrl": "https://pay.bxnk.example/UEFZLXg5eTh6N3c2djV1NA.signature",
    "expiresAt": "2026-03-20T10:35:00.000Z",
    "instructions": {
      "event_id": "evt_abc123def4567890",
      "event_type": "crypto.transfer.indexed",
      "network": "ethereum",
      "asset": "USDT",
      "timestamp": "2026-03-20T10:05:00.000Z",
      "amount": "500.00",
      "amount_usd": "500.00",
      "decimals": 6,
      "metadata": {
        "merchant_id": "mrc_abc123",
        "payment_id": "PAY-x9y8z7w6v5u4"
      },
      "expiry_time": "2026-03-20T10:35:00.000Z"
    },
    "transactionId": "tx_abc123def456",
    "mId": "MID-ABCDEFGHIJ",
    "walletAddress": "0x11d94ac1d603c28c03de643e5e67e66408f3ee89",
    "qrCodeUrl": "data:image/png;base64,iVBORw0KGgo...",
    "customerName": null,
    "customerEmail": null,
    "customerWallet": null,
    "createdAt": "2026-03-20T10:05:00.000Z",
    "successUrl": "https://merchant.example/payment/success",
    "failureUrl": "https://merchant.example/payment/failure",
    "redirectUrl": null,
    "declineReason": null
  }
}

Status Values

StatusDescription
createdPayment record has been created.
awaiting_otpCard 3DS challenge exists and waits for OTP verification.
processingPayment is being processed.
completedPayment completed.
failedPayment failed. declineReason may be populated.
expiredPayment expired before completion.
refundedPayment was fully refunded.
cancelledPayment was cancelled.

Refund a Payment

Refunds a completed payment. Both full and partial refunds are supported.

Sandbox limitation: Partial refunds are not supported in the sandbox environment. In sandbox, refund the full payment amount only. Partial refunds will work in production.

POST /api/v1/product-apis/payments/{paymentId}/refund
Authorization: Bearer <accessToken>
Content-Type: application/json
Idempotency-Key: order-1001-refund
NameTypeRequiredDescription
refundAmountnumberYesMust be at least 0.01, have no more than 8 decimal places, and less or equal to the original payment amount.
reasonstringNoRefund reason.
{
  "refundAmount": 49.99,
  "reason": "Customer requested refund"
}
{
  "message": "Refund processed successfully",
  "data": {
    "refundId": "REF-XYZ123ABC",
    "paymentId": "PAY-a1b2c3d4e5f6",
    "refundAmount": 49.99,
    "refundStatus": "completed",
    "reason": "Customer requested refund",
    "createdAt": "2026-03-20T11:00:00.000Z",
    "refundedAmount": 49.99,
    "remainingRefundableAmount": 0,
    "isFullyRefunded": true
  }
}

refundStatus is one of processing, completed, or failed. The cumulative fields show the total completed refund amount, the amount still refundable, and whether the payment is fully refunded.

Use GET /api/v1/product-apis/payments/{paymentId}/refund/{refundId} to retrieve the current status of a refund. This endpoint is limited to 5 requests per second.


Webhooks

Webhook requests are JSON POST requests. BXNK signs the exact JSON string with HMAC-SHA256 and sends the signature in x-psp-signature when a signing secret exists.

const express = require('express');
const crypto = require('crypto');

const app = express();

app.post('/bxnk/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-psp-signature'];
  if (!signature) {
    return res.status(401).send('Missing signature');
  }

  const expectedSignature = crypto
    .createHmac('sha256', process.env.BXNK_WEBHOOK_SECRET)
    .update(req.body) // pass the Buffer directly, no need to .toString() first
    .digest('hex');

  const expectedBuf = Buffer.from(expectedSignature, 'hex');
  const receivedBuf = Buffer.from(signature, 'hex');

  if (
    expectedBuf.length !== receivedBuf.length ||
    !crypto.timingSafeEqual(expectedBuf, receivedBuf)
  ) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(req.body.toString('utf8'));
  return res.sendStatus(200);
});

Payment events include payment.created, payment.awaiting_otp, payment.processing, payment.completed, payment.failed, payment.expired, payment.refunded, and payment.cancelled.

For non-crypto payments, webhook payloads include paymentId, status, amount, currency, paymentMethod, and declineReason when present. For crypto payments, the payload includes paymentId, status, the indexed crypto transfer fields, and (on the payment.created event only) transaction_id, wallet_address, vault_account_id, and vault_account_name.

Registered active endpoints for the payment MID are used first. If none exist and DEFAULT_WEBHOOK_URL is configured, BXNK delivers to that fallback URL and signs with the PSP signing secret.


Sandbox Testing

Sandbox outcomes for SEPA are driven by the debtor IBAN entered on the hosted page (or submitted via S2S). Use one of the following sandbox debtor IBANs:

Debtor IBANFinal statusDecline reason
DE89370400440532013000completed—
DE91370400440532013000failedinsufficient_funds
DE12500105170648489890failediban_invalid

Any other debtor IBAN stays in processing until another status check changes it.

For crypto, the outcome always depends on the actual on-chain deposit indexed against the generated wallet address, compared against the expected amount.


Common Errors

StatusWhen it happens
400Request validation fails, no MID can be resolved from the token or metadata.m_id, paymentMethod and paymentMethods are both omitted, expiryTime is invalid or not in the future, or payment method requirements are not met.
400On-ramp is not a hosted card payment, its idempotency key or asset/network is missing, the amount is outside the supported range, or the configured provider does not support on-ramp for the selected currency.
400Crypto request omits metadata.network or metadata.asset, uses an unsupported asset/network, the deposit amount converts to less than the configured USD minimum, or the PSP has no settlement wallet configured for the asset.
400Refund is attempted on a non-completed payment, the payment has already been fully refunded, or the requested amount exceeds the remaining refundable amount.
400SEPA payment is submitted for a LIVE-mode API key (live SEPA is not yet supported).
401Bearer token is missing, expired, or invalid.
403Payment MID does not match the authenticated token where ownership is checked.
404Payment or webhook endpoint is not found.
429Polling rate limit exceeded. Payment retrieval, status-check, and refund-status endpoints allow up to 5 requests per second.
503Crypto payment creation has been disabled for the environment. This gate applies only to crypto; there is no equivalent disable switch for card or SEPA creation.

Product API Quick Reference

MethodEndpointDescription
POST/api/v1/product-apis/auth/tokenGenerate a Product API bearer token.
POST/api/v1/product-apis/paymentsCreate an HPP or S2S payment.
GET/api/v1/product-apis/on-ramp-networksList supported on-ramp network and asset pairs.
GET/api/v1/product-apis/paymentsList payments for the authenticated MID.
GET/api/v1/product-apis/payments/{paymentId}Retrieve a payment.
GET/api/v1/product-apis/payments/{paymentId}/status-checkCheck status and resume a non-terminal payment if possible.
POST/api/v1/product-apis/payments/{paymentId}/refundRefund a completed payment.
GET/api/v1/product-apis/payments/{paymentId}/refund/{refundId}Retrieve refund status.
GET/api/v1/payments/hosted/{hostedPaymentToken}Public: retrieve hosted payment details (no auth).
POST/api/v1/product-apis/psp/webhooksCreate a webhook endpoint.
GET/api/v1/product-apis/psp/webhooksList webhook endpoints.
PATCH/api/v1/product-apis/psp/webhooks/{endpointId}/statusEnable or disable a webhook endpoint.
POST/api/v1/product-apis/psp/webhooks/{endpointId}/rotate-secretRotate a webhook signing secret.
GET/api/v1/product-apis/psp/balanceGet PSP balance.
GET/api/v1/product-apis/psp/balances/assetsGet PSP asset balances.
GET/api/v1/product-apis/psp/chargeback-configGet PSP chargeback config.
GET/api/v1/product-apis/payment-methods/activeList active payment methods.
GET/api/v1/product-apis/payment-methods/pspList the authenticated PSP's payment methods.
GET/api/v1/product-apis/payment-methods/psp/{paymentMethodId}/currenciesList currencies assigned to a PSP payment method.
GET/api/v1/product-apis/currenciesList currencies.
GET/api/v1/product-apis/currencies/pspList currencies supported by the authenticated PSP.
POST/api/v1/product-apis/storage/presigned-uploadGenerate a presigned S3 upload URL.
GET/api/v1/product-apis/storage/presigned-download/{key}Generate a presigned S3 download URL.
DELETE/api/v1/product-apis/storage/delete/{key}Delete an S3 object.
GET/api/v1/product-apis/healthzCheck database health.