indodax_client
Python client library for the Indodax - New Trade API V2, generated from
the provided Postman collection. It reproduces the request-signing logic
from the collection's pre-request scripts (HMAC-SHA256 over a canonical,
encodeURIComponent-style query string) so you can call the API directly
from Python without re-implementing the signing by hand.
Requirements
- Python 3.8+
requests
pip install requests
Installation
Just drop indodax_client.py into your project and import it — it's a
single, dependency-light file.
from indodax_client import IndodaxClient
Quick start
from indodax_client import IndodaxClient
client = IndodaxClient(
api_key="YOUR_API_KEY",
api_secret="YOUR_API_SECRET",
base_url="https://your-Indodax-host.example", # the collection's {{IndodaxUrl}}
)
print(client.get_account())
print(client.get_orders(symbol="usdtidr", limit=10))
order = client.create_order_buy(symbol="usdtidr", quantity=3, price=18000)
print(order)
Note:
base_urlis not defined in the Postman collection (it's the{{IndodaxUrl}}environment variable) — set it to your actual API host before using the client.
How signing works
This mirrors the collection's pre-request scripts exactly:
- Build a params dict, in a fixed order.
- Append either:
nonce(current time in ms) — default mode, ortimestamp+recvWindow, if timestamp mode is used.
- URL-encode every key/value the same way JavaScript's
encodeURIComponentdoes, then join askey1=val1&key2=val2&.... This is the canonical string. - Compute
HMAC-SHA256(secret, canonical)as a hex digest → sent as theSignheader. - For
GET/DELETErequests, the canonical string becomes the URL query string. ForPOSTrequests, it becomes the rawapplication/x-www-form-urlencodedbody.
Most endpoints send the key via the X-APIKEY header, but the withdrawal
endpoints (withdraw_coin_username, withdraw_coin_address) use Key
instead — the library already handles this per-endpoint.
Dry-run mode: prevent_execution
Every POST and DELETE method accepts a prevent_execution=True keyword
argument. When set, the client still builds and signs the request exactly
as it normally would, but never actually calls the endpoint. Instead it
returns a JSON string describing the request that would have been sent:
method, path, full URL, headers (including the computed Sign), the params
dict, and the signed body/query string.
This is useful for debugging, unit testing, or previewing a request before firing it for real.
result = client.create_order_buy(
symbol="usdtidr",
quantity=3,
price=18000,
prevent_execution=True,
)
print(result)
{
"preventExecution": true,
"message": "prevent execution with parameter to json from parameter",
"method": "POST",
"path": "/api/v2/order",
"url": "https://your-Indodax-host.example/api/v2/order",
"headers": {
"X-APIKEY": "YOUR_API_KEY",
"Sign": "...",
"Content-Type": "application/x-www-form-urlencoded"
},
"params": {
"symbol": "usdtidr",
"side": "BUY",
"quantity": 3,
"quoteOrderQty": 0,
"type": "LIMIT",
"price": 18000,
"newClientOrderId": "",
"selfTradePreventionMode": "EXPIRE_MAKER",
"timeInForce": ""
},
"body": "symbol=usdtidr&side=BUY&quantity=3&...&nonce=..."
}
The same works for DELETE requests (e.g. cancel_order), where the
returned JSON includes "method": "DELETE" and a query field instead of
body.
Methods that support prevent_execution:
create_ordercreate_order_buycreate_order_sellcancel_orderwithdraw_coin_usernamewithdraw_coin_addresswithdraw_idr
(GET methods always call the endpoint — there's nothing to "prevent".)
API reference
Account & market data
| Method | Endpoint | Description |
|---|---|---|
get_account() |
GET /api/v2/account |
Account balances/info |
get_orders(symbol, start_time=None, end_time=None, limit=10, sort="asc") |
GET /api/v2/order/histories |
Order history |
get_order_detail(symbol, order_id=None, orig_client_order_id=None) |
GET /api/v2/order |
Single order detail |
get_pending_orders(symbol="") |
GET /api/v2/openOrders |
Open/pending orders (empty symbol = all pairs) |
get_trade_history(symbol, order_id=None, client_order_id=None, start_time=None, end_time=None, limit=10, sort="desc") |
GET /api/v2/myTrades |
Executed trade history |
Orders
| Method | Endpoint | Description |
|---|---|---|
create_order(symbol, side, order_type, quantity=None, quote_order_qty=None, price=None, new_client_order_id="", self_trade_prevention_mode="", time_in_force="", prevent_execution=False) |
POST /api/v2/order |
Generic order creation (side: BUY/SELL) |
create_order_buy(symbol, quantity=None, quote_order_qty=None, order_type="LIMIT", price=None, new_client_order_id="", self_trade_prevention_mode="EXPIRE_MAKER", time_in_force="", prevent_execution=False) |
POST /api/v2/order |
Convenience wrapper for a BUY order |
create_order_sell(symbol, quantity=None, quote_order_qty=None, order_type="LIMIT", price=None, new_client_order_id="", self_trade_prevention_mode="", time_in_force="", prevent_execution=False) |
POST /api/v2/order |
Convenience wrapper for a SELL order |
cancel_order(symbol, order_id=None, orig_client_order_id=None, prevent_execution=False) |
DELETE /api/v2/order |
Cancel an order |
order_type: "LIMIT" or "MARKET".
quantity is the coin amount (required for LIMIT); quote_order_qty is the
estimated quote-currency amount and is mutually exclusive with quantity
(MARKET BUY only).
self_trade_prevention_mode: "EXPIRE_MAKER" | "EXPIRE_TAKER" | "EXPIRE_BOTH".
time_in_force: "MOC" | "GTC" (default).
Withdrawals & deposits
| Method | Endpoint | Description |
|---|---|---|
withdraw_coin_username(coin, network, withdraw_username, amount, address_tag="", withdraw_order_id="", address="", prevent_execution=False) |
POST /api/v2/capital/withdraw/apply |
Internal transfer to another user by username |
withdraw_coin_address(coin, network, address, amount, username="", address_tag="", withdraw_order_id="", prevent_execution=False) |
POST /api/v2/capital/withdraw/apply |
On-chain withdrawal to an external address |
withdraw_idr(amount, account_number, bank_code, api_payment_method="bank_transfer", currency="idr", client_request_id="", prevent_execution=False) |
POST /api/v2/fiat/withdraw |
Fiat (IDR) withdrawal |
get_fiat_history(transaction_type, begin_time, end_time) |
GET /api/v2/fiat/orders |
Fiat deposit/withdraw history (transaction_type: 0=deposit, 1=withdraw) |
get_coin_deposit_history(coin="", start_time=None, end_time=None, limit=100, deposit_status="success") |
GET /api/v2/capital/deposit/hisrec |
Coin deposit history |
get_coin_withdraw_history(coin="", start_time=None, end_time=None, limit=100, withdraw_status="") |
GET /api/v2/capital/withdraw/history |
Coin withdrawal history |
get_deposit_address_list(coin, network="") |
GET /api/v2/capital/deposit/address/list |
List deposit addresses for a coin/network |
Withdrawal endpoints send the API key via the Key header (not
X-APIKEY) — this is handled automatically.
Error handling
Any non-2xx HTTP response raises IndodaxAPIError:
from indodax_client import IndodaxClient, IndodaxAPIError
try:
client.cancel_order(symbol="usdtidr", order_id=25184)
except IndodaxAPIError as e:
print(e.status_code, e.payload)
Examples
Place a limit buy order:
client.create_order_buy(symbol="usdtidr", quantity=3, price=18000)
Place a market sell order (by coin quantity):
client.create_order_sell(symbol="usdtidr", quantity=1.5, order_type="MARKET")
Cancel an order:
client.cancel_order(symbol="usdtidr", order_id=25184)
Withdraw USDT to an external address:
client.withdraw_coin_address(
coin="usdt",
network="bep20",
address="0x7adcbb207f76d0fed23ea579e0daa76d8e71c5de",
amount="5",
withdraw_order_id="wd-usdt-3",
)
Withdraw IDR to a bank account:
client.withdraw_idr(
amount="100000",
account_number="6042229896",
bank_code="014",
)
Preview a request without sending it:
preview = client.create_order_buy(
symbol="usdtidr", quantity=3, price=18000, prevent_execution=True,
)
print(preview)
Notes & caveats
base_urlmust be set to the real API host — it isn't hardcoded since the Postman collection only references{{IndodaxUrl}}as an environment variable.- The default time mode is nonce (matches
timeMode: 'nonce'in the original scripts). Timestamp +recvWindowmode isn't currently exposed as a public option but the internal_prepare/_build_canonicalmethods support it if you need to extend the client. - All requests are synchronous (built on
requests). Wrap calls in your own retry/backoff logic if needed.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file indodaxclient-2.0.2.tar.gz.
File metadata
- Download URL: indodaxclient-2.0.2.tar.gz
- Upload date:
- Size: 8.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40c4682c13d40e94dcd0c86d110e5a9a4b1b45b64ecfb16fe177fcc194dea0f0
|
|
| MD5 |
51047cbc52b7fa27d85e21adf23c872b
|
|
| BLAKE2b-256 |
1f32846b3a3cbc70a7efe305f8b820dc4601d1b5843d3e8538c850a1441d0caa
|
File details
Details for the file indodaxclient-2.0.2-py3-none-any.whl.
File metadata
- Download URL: indodaxclient-2.0.2-py3-none-any.whl
- Upload date:
- Size: 9.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c89bd8c40e0efb291e3ea1fa53831bdef63816eda1a16bfe51a638e2884b361
|
|
| MD5 |
63e3456d93c56d4fe946b424a4f401ea
|
|
| BLAKE2b-256 |
781f3c9e3c16d458a9b262c5f7493c0199b6872331877ead8cf690a262f8e170
|