1+ # Boltz API Reference (Source of Truth)
2+
3+ Do not maintain endpoint details manually in this repository.
4+
5+ Always use the live Boltz swagger spec:
6+
7+ - https://api.boltz.exchange/swagger-spec.json
8+
9+ If behavior in code and docs diverge, trust the swagger spec and update code
10+ accordingly.
11+
112# Boltz API Documentation
213
314## Partner Referral Stats Endpoint
415
516### Endpoint
17+
618```
719GET https://api.boltz.exchange/v2/referral/stats
820```
921
1022### Authentication
1123
12- The Boltz API uses ** HMAC-SHA256** signature authentication. Each request must include three headers:
24+ The Boltz API uses ** HMAC-SHA256** signature authentication. Each request must
25+ include three headers:
1326
1427#### Required Headers
28+
1529- ` TS ` - Unix timestamp (seconds since epoch)
1630- ` API-KEY ` - Your Boltz partner API key
1731- ` API-HMAC ` - HMAC signature of the request
@@ -20,44 +34,44 @@ The Boltz API uses **HMAC-SHA256** signature authentication. Each request must i
2034
2135``` javascript
2236// 1. Create the message to sign
23- const timestamp = Math .round (Date .now () / 1000 )
24- const method = ' GET'
25- const path = ' /v2/referral/stats'
26- const message = ` ${ timestamp}${ method}${ path} `
37+ const timestamp = Math .round (Date .now () / 1000 );
38+ const method = " GET" ;
39+ const path = " /v2/referral/stats" ;
40+ const message = ` ${ timestamp}${ method}${ path} ` ;
2741
2842// 2. Generate HMAC-SHA256 signature using your API secret
2943const hmac = crypto
30- .createHmac (' sha256' , API_SECRET )
31- .update (message)
32- .digest (' hex' )
44+ .createHmac (" sha256" , API_SECRET )
45+ .update (message)
46+ .digest (" hex" );
3347
3448// 3. Include in request headers
3549const headers = {
36- ' TS ' : timestamp .toString (),
37- ' API-KEY' : API_KEY ,
38- ' API-HMAC' : hmac
39- }
50+ TS : timestamp .toString (),
51+ " API-KEY" : API_KEY ,
52+ " API-HMAC" : hmac,
53+ };
4054```
4155
4256#### Example in Browser (Web Crypto API)
4357
4458``` typescript
4559async function createHmac(message : string , secret : string ): Promise <string > {
46- const encoder = new TextEncoder ();
47- const keyData = encoder .encode (secret );
48- const messageData = encoder .encode (message );
49-
50- const cryptoKey = await crypto .subtle .importKey (
51- ' raw' ,
52- keyData ,
53- { name: ' HMAC' , hash: ' SHA-256' },
54- false ,
55- [ ' sign' ]
56- );
57-
58- const signature = await crypto .subtle .sign (' HMAC' , cryptoKey , messageData );
59- const hashArray = Array .from (new Uint8Array (signature ));
60- return hashArray .map (b => b .toString (16 ).padStart (2 , ' 0 ' )).join (' ' );
60+ const encoder = new TextEncoder ();
61+ const keyData = encoder .encode (secret );
62+ const messageData = encoder .encode (message );
63+
64+ const cryptoKey = await crypto .subtle .importKey (
65+ " raw" ,
66+ keyData ,
67+ { name: " HMAC" , hash: " SHA-256" },
68+ false ,
69+ [ " sign" ],
70+ );
71+
72+ const signature = await crypto .subtle .sign (" HMAC" , cryptoKey , messageData );
73+ const hashArray = Array .from (new Uint8Array (signature ));
74+ return hashArray .map (( b ) => b .toString (16 ).padStart (2 , " 0 " )).join (" " );
6175}
6276```
6377
@@ -76,119 +90,124 @@ The API returns referral statistics organized by year and month:
7690
7791``` json
7892{
79- "2024" : {
80- "1" : {
81- "volume" : {
82- "total" : " 1.23456789" ,
83- "BTC/BTC" : " 0.5" ,
84- "L-BTC/BTC" : " 0.73456789"
85- },
86- "trades" : {
87- "total" : 150 ,
88- "BTC/BTC" : 75 ,
89- "L-BTC/BTC" : 75
90- },
91- "groups" : {
92- "partner-id-1" : {
93- "volume" : { "total" : " 0.5" },
94- "trades" : { "total" : 50 }
93+ "2024" : {
94+ "1" : {
95+ "volume" : {
96+ "total" : " 1.23456789" ,
97+ "BTC/BTC" : " 0.5" ,
98+ "L-BTC/BTC" : " 0.73456789"
99+ },
100+ "trades" : {
101+ "total" : 150 ,
102+ "BTC/BTC" : 75 ,
103+ "L-BTC/BTC" : 75
104+ },
105+ "groups" : {
106+ "partner-id-1" : {
107+ "volume" : { "total" : " 0.5" },
108+ "trades" : { "total" : 50 }
109+ },
110+ "partner-id-2" : {
111+ "volume" : { "total" : " 0.73456789" },
112+ "trades" : { "total" : 100 }
113+ }
114+ }
95115 },
96- "partner-id-2" : {
97- "volume" : { "total" : " 0.73456789" },
98- "trades" : { "total" : 100 }
116+ "2" : {
117+ "volume" : {
118+ "total" : " 2.5" ,
119+ "BTC/BTC" : " 1.2" ,
120+ "L-BTC/BTC" : " 1.3"
121+ },
122+ "trades" : {
123+ "total" : 200 ,
124+ "BTC/BTC" : 100 ,
125+ "L-BTC/BTC" : 100
126+ },
127+ "groups" : {
128+ "partner-id-1" : {
129+ "volume" : { "total" : " 1.0" },
130+ "trades" : { "total" : 80 }
131+ },
132+ "partner-id-2" : {
133+ "volume" : { "total" : " 1.5" },
134+ "trades" : { "total" : 120 }
135+ }
136+ }
99137 }
100- }
101138 },
102- "2" : {
103- "volume" : {
104- "total" : " 2.5" ,
105- "BTC/BTC" : " 1.2" ,
106- "L-BTC/BTC" : " 1.3"
107- },
108- "trades" : {
109- "total" : 200 ,
110- "BTC/BTC" : 100 ,
111- "L-BTC/BTC" : 100
112- },
113- "groups" : {
114- "partner-id-1" : {
115- "volume" : { "total" : " 1.0" },
116- "trades" : { "total" : 80 }
117- },
118- "partner-id-2" : {
119- "volume" : { "total" : " 1.5" },
120- "trades" : { "total" : 120 }
139+ "2025" : {
140+ "1" : {
141+ "volume" : {
142+ "total" : " 3.14159265" ,
143+ "BTC/BTC" : " 1.5" ,
144+ "L-BTC/BTC" : " 1.64159265"
145+ },
146+ "trades" : {
147+ "total" : 250 ,
148+ "BTC/BTC" : 120 ,
149+ "L-BTC/BTC" : 130
150+ },
151+ "groups" : {
152+ "partner-id-1" : {
153+ "volume" : { "total" : " 1.2" },
154+ "trades" : { "total" : 100 }
155+ },
156+ "partner-id-2" : {
157+ "volume" : { "total" : " 1.94159265" },
158+ "trades" : { "total" : 150 }
159+ }
160+ }
121161 }
122- }
123162 }
124- },
125- "2025" : {
126- "1" : {
127- "volume" : {
128- "total" : " 3.14159265" ,
129- "BTC/BTC" : " 1.5" ,
130- "L-BTC/BTC" : " 1.64159265"
131- },
132- "trades" : {
133- "total" : 250 ,
134- "BTC/BTC" : 120 ,
135- "L-BTC/BTC" : 130
136- },
137- "groups" : {
138- "partner-id-1" : {
139- "volume" : { "total" : " 1.2" },
140- "trades" : { "total" : 100 }
141- },
142- "partner-id-2" : {
143- "volume" : { "total" : " 1.94159265" },
144- "trades" : { "total" : 150 }
145- }
146- }
147- }
148- }
149163}
150164```
151165
152166### Response Fields
153167
154- | Field | Type | Description |
155- | -------| ------| -------------|
156- | ` {year} ` | Object | Container for all months in that year |
157- | ` {year}.{month} ` | Object | Stats for specific month (1-12) |
158- | ` {year}.{month}.volume ` | Object | Volume breakdown by trading pair |
159- | ` {year}.{month}.volume.total ` | String | Total volume in BTC for the month |
160- | ` {year}.{month}.trades ` | Object | Trade count breakdown by trading pair |
161- | ` {year}.{month}.trades.total ` | Number | Total number of swaps for the month |
162- | ` {year}.{month}.groups ` | Object | Sub-partner breakdown (if applicable) |
163- | ` {year}.{month}.groups.{partnerId} ` | Object | Stats for specific sub-partner |
168+ | Field | Type | Description |
169+ | ----------------------------------- | ------ | ------------------------------------- |
170+ | ` {year} ` | Object | Container for all months in that year |
171+ | ` {year}.{month} ` | Object | Stats for specific month (1-12) |
172+ | ` {year}.{month}.volume ` | Object | Volume breakdown by trading pair |
173+ | ` {year}.{month}.volume.total ` | String | Total volume in BTC for the month |
174+ | ` {year}.{month}.trades ` | Object | Trade count breakdown by trading pair |
175+ | ` {year}.{month}.trades.total ` | Number | Total number of swaps for the month |
176+ | ` {year}.{month}.groups ` | Object | Sub-partner breakdown (if applicable) |
177+ | ` {year}.{month}.groups.{partnerId} ` | Object | Stats for specific sub-partner |
164178
165179### Notes
166180
167- 1 . ** Volume Format** : All volume values are in BTC as strings (to preserve precision)
168- 2 . ** Trading Pairs** : The response includes breakdowns by trading pair (e.g., "BTC/BTC", "L-BTC/BTC")
181+ 1 . ** Volume Format** : All volume values are in BTC as strings (to preserve
182+ precision)
183+ 2 . ** Trading Pairs** : The response includes breakdowns by trading pair (e.g.,
184+ "BTC/BTC", "L-BTC/BTC")
1691853 . ** Groups** : Only present if you have sub-partners under your referral program
1701864 . ** Month Numbers** : Months are numbered 1-12 (1 = January, 12 = December)
171187
172188### Error Responses
173189
174190#### 401 Unauthorized
191+
175192``` json
176193{
177- "error" : " Invalid API key or signature"
194+ "error" : " Invalid API key or signature"
178195}
179196```
180197
181198#### 403 Forbidden
199+
182200``` json
183201{
184- "error" : " Access denied"
202+ "error" : " Access denied"
185203}
186204```
187205
188206#### 429 Rate Limited
207+
189208``` json
190209{
191- "error" : " Too many requests"
210+ "error" : " Too many requests"
192211}
193212```
194213
@@ -201,52 +220,59 @@ The API returns referral statistics organized by year and month:
201220
202221``` typescript
203222interface MonthlyStats {
204- month: string ;
205- year: number ;
206- volumeBtc: number ;
207- tradeCount: number ;
208- avgTradeSize: number ;
223+ month: string ;
224+ year: number ;
225+ volumeBtc: number ;
226+ tradeCount: number ;
227+ avgTradeSize: number ;
209228}
210229
211230function processStatsData(data : any ): MonthlyStats [] {
212- const monthly: MonthlyStats [] = [];
213-
214- Object .entries (data ).forEach (([year , yearData ]: [string , any ]) => {
215- Object .entries (yearData ).forEach (([month , monthData ]: [string , any ]) => {
216- const volumeBtc = parseFloat (monthData .volume ?.total || ' 0' );
217- const tradeCount = monthData .trades ?.total || 0 ;
218-
219- monthly .push ({
220- month: getMonthName (parseInt (month )),
221- year: parseInt (year ),
222- volumeBtc ,
223- tradeCount ,
224- avgTradeSize: tradeCount > 0
225- ? Math .round ((volumeBtc * 100_000_000 ) / tradeCount )
226- : 0 ,
227- });
231+ const monthly: MonthlyStats [] = [];
232+
233+ Object .entries (data ).forEach (([year , yearData ]: [string , any ]) => {
234+ Object .entries (yearData ).forEach (
235+ ([month , monthData ]: [string , any ]) => {
236+ const volumeBtc = parseFloat (monthData .volume ?.total || " 0" );
237+ const tradeCount = monthData .trades ?.total || 0 ;
238+
239+ monthly .push ({
240+ month: getMonthName (parseInt (month )),
241+ year: parseInt (year ),
242+ volumeBtc ,
243+ tradeCount ,
244+ avgTradeSize:
245+ tradeCount > 0
246+ ? Math .round ((volumeBtc * 100_000_000 ) / tradeCount )
247+ : 0 ,
248+ });
249+ },
250+ );
251+ });
252+
253+ return monthly .sort ((a , b ) => {
254+ if (a .year !== b .year ) return a .year - b .year ;
255+ return getMonthIndex (a .month ) - getMonthIndex (b .month );
228256 });
229- });
230-
231- return monthly .sort ((a , b ) => {
232- if (a .year !== b .year ) return a .year - b .year ;
233- return getMonthIndex (a .month ) - getMonthIndex (b .month );
234- });
235257}
236258```
237259
238260## Additional Endpoints
239261
240262### Get Partner Fees
263+
241264```
242265GET https://api.boltz.exchange/v2/referral/fees
243266```
267+
244268Returns fee earnings breakdown by currency and time period.
245269
246270### Get Referral Info
271+
247272```
248273GET https://api.boltz.exchange/v2/referral
249274```
275+
250276Returns general information about your referral program.
251277
252278---
0 commit comments