Configuring your API
After creating an API, you can make updates to it (e.g., its name, API credentials, documentation, earning details, etc):
- Enter the API portal.
- Link the wallet that owns your API.
- Click "My APIs".
- Click the API you want to update.
- Click "Edit" and follow the dialogs (this stage requires re-authorisation).
Setting your earnings rate
Dhali currently supports setting your earnings on a per request or per second basis. HTTPS APIs support both per request and per second charging, meaning that a single complete HTTPS request is charged as one unit. In contrast, WebSocket APIs only allow per request charging. Additionally, WebSocket APIs charge on both the upstream (client-to-server) and the downstream (server-to-client) flows, whereas HTTPS APIs charge for the complete request as a single unit. Because of this bidirectional charging, you may consider setting the per request rate for WebSocket APIs at approximately half the rate of an equivalent HTTPS API.
Surcharging
Dhali allows HTTPS and Websocket API providers to apply dynamic pricing in addition to the base per-second and per-request earning types. A basic example can be found here. To enable surcharging, edit your API and select a non-zero maximum surcharge value. The general flow of surcharging is:
- A user accesses your surcharge-enabled API through Dhali.
- Dhali forwards the request, adding the header
X-Payment-Claim-Surcharge-Currency
, which is a base 64 encoded string taking the decoded form:
{
"schema": (string) A version,
"networkType": (string) The payment network type, e.g., XRPL,
"networkID": (int, required) For XRPL-like networks, we use these IDs: [https://docs.xahau.network/technical/protocol-reference/transactions/transaction-common-fields#networkid-field](https://docs.xahau.network/technical/protocol-reference/transactions/transaction-common-fields#networkid-field),
"code" : (string) The currency code the API earns, e.g., XRP,
"scale": (int) The currency's scale, e.g., 6,
"maxAmount": (int) The maximum amount this API allows to be surcharged,
"issuer": (string, optional) The identifier of a token issuer,
}
-
The linked API optionally adds an extra charge by responding to Dhali with the header
X-Payment-Claim-Surcharge
. -
For HTTPS APIs, send
X-Payment-Claim-Surcharge
as a standard HTTP header whose value is a base 64 encoded string taking the decoded form:
{
"schema": (string, required) A version,
"amount": (unsigned int) The amount to surcharged, measured in the code/scale pair from 2.
}
-
For WebSocket APIs, embed the surcharge object into the payload itself. To do this, prepend each downstream frame with a small wrapper:
- Base64-encode a JSON object of the form:
{"X-Payment-Claim-Surcharge": base64_encoded_surcharge_string}
- Wrap it between
<JSONHDR>
and</JSONHDR>
. - Immediately follow with the actual JSON response.
In other words, the server’s reply might look like this (as a single text frame):
<JSONHDR>BASE64_ENCODED_HEADER</JSONHDR>{"id":1,"result":"ok","otherField":42}
where
BASE64_ENCODED_HEADER
decodes to:{ "X-Payment-Claim-Surcharge": BASE64_ENCODED_SURCHARGE_OBJECT }
and
BASE64_ENCODED_SURCHARGE_OBJECT
decodes to:{ "schema": "0.0.0", "amount": 100000 }
Dhali will strip out the
<JSONHDR>…</JSONHDR>
block, decode and parse it, and then forward only the bare body ({"id":1,"result":"ok","otherField":42}
) to the client. - Base64-encode a JSON object of the form:
Encoding and decoding surcharge headers
Below are JavaScript examples of how the X-Payment-Claim-Surcharge-Currency
and X-Payment-Claim-Surcharge
headers should be encoded when placed into the header or wrapped for WebSocket messages:
const data = { key: "value", number: 123 };
const jsonString = JSON.stringify(data);
const base64EncodedString = Buffer.from(jsonString).toString('base64');
const decodedBytes = Buffer.from(base64EncodedString, 'base64');
const decodedJsonString = decodedBytes.toString('utf-8');
const originalData = JSON.parse(decodedJsonString);
console.log(originalData);
WebSocket-specific frame example
To embed the surcharge header in a downstream WebSocket response:
// 1) Prepare the surcharge header object:
const surchargeAmount = 100000;
const surchargePayload = {
schema: "0.0.0",
amount: surchargeAmount
};
const base64Surcharge = Buffer.from(JSON.stringify(surchargePayload)).toString("base64");
// 2) Wrap it inside another object keyed by "X-Payment-Claim-Surcharge":
const wrappedHeaderJson = JSON.stringify({
"X-Payment-Claim-Surcharge": base64Surcharge
});
const base64WrappedHeader = Buffer.from(wrappedHeaderJson).toString("base64");
// 3) Create the downstream frame with <JSONHDR> prefix:
const startTag = "<JSONHDR>";
const endTag = "</JSONHDR>";
const actualPayload = { id: 1, result: "ok", otherField: 42 };
const finalFrame = `${startTag}${base64WrappedHeader}${endTag}${JSON.stringify(actualPayload)}`;
// Example: "<JSONHDR>eyJYLVBheW1lbnQtQ2xhaW0tU3VyY2hhcmdlIjoiZXlKelkyOXdaWEpoYkY5dVkyOXRJSE5wYjI1eklHNWxaV1FnWVc1bklIQnliMlIxY3lJPSJ9</JSONHDR>{\"id\":1,\"result\":\"ok\",\"otherField\":42}"