MtGox/API

From Bitcoin Wiki
Revision as of 07:59, 26 January 2012 by Seventoes (talk | contribs) (Forgot a parameter)
Jump to navigation Jump to search

The MtGox API provides methods to access information from the market, place orders, and more.

Two APIs are currently available: the HTTP API (available by posting to mtgox.com/code/*) and the websocket API.

Number Formats

In the "old API", currency- and amount-values (price, volume,...) were given as float. These values are likely being deprecated and replaced by fields of the same name with "_int" as suffix. These are fixed-decimal, so you have to move the decimal point yourself (divide). The exponent differs based on the kind of the value.

In order to convert the int to a decimal you can...

kind of field ...divide by ...multiply by
BTC (volume, amount) 1E8 (10,000,000) 0.00000001
USD (price) 1E5 (100,000) 0.00001
JPY (price) 1E3 (1,000) 0.001

Implementation advice: it's probably best to use int or Decimal (if your language/db offers such a type) in your clients. Using float will likely lead to nasty rounding problems.

Currency Symbols

List of the currency symbols available with the API:

USD, AUD, CAD, CHF, CNY, DKK, EUR, GBP, HKD, JPY, NZD, PLN, RUB, SEK, SGD, THB

HTTP API

This API is available in https://mtgox.com/api/*, and provides various informations. It also supports making an order, a withdraw, a deposit, etc. There is also a Ruby gem and Perl module for interacting with the HTTP API.

Authentication

Authentication is performed by signing each request using HMAC-SHA512. The request must contain an extra value "nonce" which must be an always incrementing numeric value. A reference implementation is provided here:

<?php

function mtgox_query($path, array $req = array()) {
	// API settings
	$key = '';
	$secret = '';

	// generate a nonce as microtime, with as-string handling to avoid problems with 32bits systems
	$mt = explode(' ', microtime());
	$req['nonce'] = $mt[1].substr($mt[0], 2, 6);

	// generate the POST data string
	$post_data = http_build_query($req, '', '&');

	// generate the extra headers
	$headers = array(
		'Rest-Key: '.$key,
		'Rest-Sign: '.base64_encode(hash_hmac('sha512', $post_data, base64_decode($secret), true)),
	);

	// our curl handle (initialize if required)
	static $ch = null;
	if (is_null($ch)) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MtGox PHP client; '.php_uname('s').'; PHP/'.phpversion().')');
	}
	curl_setopt($ch, CURLOPT_URL, 'https://mtgox.com/api/'.$path);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

	// run the query
	$res = curl_exec($ch);
	if ($res === false) throw new Exception('Could not get reply: '.curl_error($ch));
	$dec = json_decode($res, true);
	if (!$dec) throw new Exception('Invalid data received, please make sure connection is working and requested API exists');
	return $dec;
}

// example 1: get infos about the account, plus the list of rights we have access to
var_dump(mtgox_query('0/info.php'));

// old api (get funds)
var_dump(mtgox_query('0/getFunds.php'));

// trade example
// var_dump(mtgox_query('0/buyBTC.php', array('amount' => 1, 'price' => 15)));

Python version here: https://bitcointalk.org/index.php?topic=49789.msg592388#msg592388

Cache

All of the API methods below have cached results, ticker, depth . . . have a 10 seconds cache . No need to poll more often, you wont have more results, you could just be blocked by the prolexic anti ddos features.

Methods API version 0

0/data/getTrades.php

This allows retrieving all trades which happened in the last 24 hours. The returned data is cached and may not reflect latest activity.

Parameters:

  • since: Passing a tid in "since" allows retrieving all trades since that trade. The passed id is may not exist. Ie. to get all trades from the very beginning one would just call https://mtgox.com/code/data/getTrades.php?since=0 . since returns only 100 trades, and you can call the method again by passing the latest trade you have imported in since.
  • data is returned in standard json format like :
[
{"date":1279408157,
"price":"0.04951",
"amount":"20",
"price_int":"4951",
"amount_int":"2000000000",
"tid":"1",
"price_currency":"USD",
"item":"BTC",
"trade_type":""
"primary":"Y"
},
{"date":1279424586,"price":"0.05941","amount":"50.01","price_int":"5941","amount_int":"5001000000","tid":"2","price_currency":"USD","item":"BTC","trade_type":""}]

0/getDepth.php

Get the current Market depth

https://mtgox.com/api/0/data/getDepth.php?Currency=PLN

https://mtgox.com/api/0/data/getDepth.php?Currency=AUD

https://mtgox.com/api/0/data/getDepth.php?Currency=USD

0/getFunds.php

Get your current balance

https://mtgox.com/api/0/getFunds.php

getfunds is now deprecated since multi currency, please use info.php

0/buyBTC.php

Place an order to Buy BTC

https://mtgox.com/api/0/buyBTC.php

POST data: amount=#&price=#&Currency=PLN

returns a list of your open orders

you can omit the price to do a market order

0/sellBTC.php

Place an order to Sell BTC

https://mtgox.com/api/0/sellBTC.php

POST data: &amount=#&price=#&Currency=PLN

returns a list of your open orders

you can omit the price to do a market order

0/getOrders.php

Fetch a list of your open Orders

https://mtgox.com/api/0/getOrders.php

oid: Order ID

type: 1 for sell order or 2 for buy order

status: 1 for active, 2 for not enough funds

0/cancelOrder.php

Cancel an order

https://mtgox.com/api/0/cancelOrder.php

POST data: oid=#&type=#

oid: Order ID

type: 1 for sell order or 2 for buy order

0/redeemCode.php

Used to redeem a mtgox coupon code

https://mtgox.com/api/0/redeemCode.php

  • call with a post parameter "code" containing the code to redeem
  • it will return an array with amount (float amount value of code), currency (3 letters, BTC or USD), reference (the transaction id), and status

0/withdraw.php

withdraw / Send BTC

https://mtgox.com/api/0/withdraw.php

POST data: group1=BTC&btca=bitcoin_address_to_send_to&amount=#

  • pass btca parameter to withdraw to a btc adress
  • pass group1 for a coupon : BTC2CODE or USD2CODE
  • pass group1=DWUSD&dwaccount=XXX-XXX-XXXX (no btca=xxxxxxx) for a dwolla withdraw
  • pass green=1 to use the new greenaddress feature ( see GreenAddress )
  • return code and status if successful
To make a withdraw in another Currency , use group1=USD2CODE and add a Currency parameter ( example Currency=EUR to get a mtgox EUR coupon )

0/btcAddress.php

get a bitcoin deposit adress for your account

https://mtgox.com/api/0/btcAddress.php

  • pass POST data "description" to add a description that will appear in your history when this BTC address receive a deposit
  • returns a bitcoin deposit address

0/history_[CUR].csv

Allows downloading your activity history for a given currency (BTC or USD for now).

https://mtgox.com/api/0/history_BTC.csv

https://mtgox.com/api/0/history_USD.csv

encoding is utf-8

0/info.php

https://mtgox.com/api/0/info.php

returns info about your account, funds, fees, API privileges, withdraw limits . . .

0/ticker

http://mtgox.com/api/0/data/ticker.php

returns the current ticker :

{"ticker":
 {
 "high":5.70653,
 "low":5.4145,
 "avg":5.561388723,
 "vwap":5.610932845,
 "vol":55698,
 "last":5.56915,
 "buy":5.51326,
 "sell":5.5672
 }
}
the time frame for high, low, vol, avg, vwap . . . is sliding 24 hours

what is vwap ?

please see http://en.wikipedia.org/wiki/VWAP

API version 0 examples

all api shell type CLI

python : http://www.goxsh.info/

perl : http://pastebin.com/vEpgw5nW

other

https : http://stackoverflow.com/questions/7046370/https-request-with-boost-asio-and-openssl

https://github.com/sje397/mtgox-plasmoid

module perl : http://search.cpan.org/~mndrix/Finance-MtGox-0.02/

gather data

https://github.com/Lexiks/MyBitBoard

gettrade

bash : https://bitcointalk.org/index.php?topic=39402.0

perl : http://pastebin.com/raw.php?i=pmhMXZJu

ticker

http://pastebin.com/pd0ZR4WY

Methods API version 1

Multi Currency Ticker

https://mtgox.com/api/1/BTCUSD/public/ticker
https://mtgox.com/api/1/BTCEUR/public/ticker
returns the current ticker for the selected currency :
{
"result":"success",
"return":
 {
 "high": {"value":"5.70653","value_int":"570653","display":"$5.70653","currency":"USD"},
 "low": {"value":"5.4145","value_int":"541450","display":"$5.41450","currency":"USD"},
 "avg": {"value":"5.561119626","value_int":"556112","display":"$5.56112","currency":"USD"},
 "vwap": {"value":"5.610480461","value_int":"561048","display":"$5.61048","currency":"USD"},
 "vol":
 {
  "value":"55829.58960346",
  "value_int":"5582958960346",
  "display":"55,829.58960346\u00a0BTC",
  "currency":"BTC"
 },
 "last_local":{"value":"5.5594","value_int":"555940","display":"$5.55940","currency":"USD"},
 "last_orig":{"value":"5.5594","value_int":"555940","display":"$5.55940","currency":"USD"},
 "last":{"value":"5.5594","value_int":"555940","display":"$5.55940","currency":"USD"},
 "buy":{"value":"5.53587","value_int":"553587","display":"$5.53587","currency":"USD"},
 "sell":{"value":"5.56031","value_int":"556031","display":"$5.56031","currency":"USD"}
 }

note : last_local include only the last trade in the selected currency, last_orig include data of the original last trade ( currency,price in currency . . . ),last can be a conversion of the last trde in another currency

Multi Currency depth

https://mtgox.com/api/1/BTCPLN/public/depth?raw

https://mtgox.com/api/1/BTCAUD/public/depth?raw

Multi currency trades

https://mtgox.com/api/1/BTCPLN/public/trades?raw

https://mtgox.com/api/1/BTCAUD/public/trades?raw

to get only the trades since a given trade id, you can add the parameter since=<trade_id>

https://mtgox.com/api/1/BTCUSD/public/trades?since=0

https://mtgox.com/api/1/BTCEUR/public/trades?since=1316312781670700

For multi currency,also returns the primary value,"Y" or "N", the primary currency is always the buyers currency

A trade can appear in more than one currency, to ignore duplicates, use only the trades having primary =Y

example of returned data :

{"date":1316312781,
"price":"3.5599",
"amount":"3.6900096",
"price_int":"355990",
"amount_int":"369000960",
"tid":"1316312781670700",
"price_currency":"EUR",
"item":"BTC",
"trade_type":"bid",
"primary":"Y",
"properties":"limit,mixed_currency"
}

Cancelled Trades

https://mtgox.com/api/1/BTCUSD/public/cancelledtrades

returns a list of all the cancelled trades this last month, list of trade ids in json format .

Full Depth

https://mtgox.com/api/1/BTCUSD/public/fulldepth

returns full depth

Private info

https://mtgox.com/api/1/generic/private/info

returns information about your account, funds, fees, API privileges, withdraw limits . . .

Your open orders

https://mtgox.com/api/1/generic/private/orders

returns information about your current open orders

Submit an order

https://mtgox.com/api/1/BTCUSD/private/order/add

parameters:

  • type (bid|ask)
  • amount_int <amount as int>
  • price_int <price as int> (can be omitted to place market order)

submits an order and returns info about success or error

Currency information

https://mtgox.com/api/1/generic/public/currency

pass parameter ?currency=<currency_symbol>

returns information about a currency ( number of decimals . . . )

HOTP key

https://mtgox.com/api/1/generic/public/hotp_gen

used to generate a new HOTP key ( useful for developpers )

Streaming API

Real time streaming data may be obtained over the streaming API, implemented in Socket.io[1]. The original WebSocket API[2] is deprecated as of 11-Nov-2011.

Connecting

The following JavaScript code establishes a connection in the browser:

<script src="https://socketio.mtgox.com/socket.io/socket.io.js"></script>
<script>
    var conn = io.connect('https://socketio.mtgox.com/mtgox');
    conn.on('message', function(data) {
        // Handle incoming data object.
    });
</script>

The session ID expires after 30 seconds

Handling Events

Socket.io exposes a simple interface for handling events. Handling message events is shown above, but there are other events that may be handled:

conn.on('connect',    onConnect);
conn.on('disconnect', onDisconnect);
conn.on('error',      onError);
conn.on('message',    onMessage);

Incoming Data

Data arrives as a full object instead of as JSON text, eliminating the need to parse the data in the JavaScript handler. Messages that come across the socket to trigger the message event will contain the following minimum components:

{
  "op":<OPERATION_TYPE>
}

The OPERATION_TYPE field may take these values:

OPERATION_TYPE Description
subscribe Notification that the user is subscribed to a channel
unsubscribe Messages will no longer arrive over the channel
remark A server message, usually a warning
private The operation for depth, trade, and ticker messages

op:subscribe and op:unsubscribe

The subscribe and unsubscribe message data are very simple, containing the channel and the operation.

{
  "channel":<CHANNEL_ID>,
  "op":"subscribe" OR "unsubscribe"
}

Some of the channels are:

Channel ID Description
dbf1dee9-4f2e-4a08-8cb7-748919a71b21 Trades
d5f06780-30a8-4a48-a2f8-7ed181b4a13f Ticker
24e67e0d-1cad-4cc0-9e7a-f8523ef460fe Depth

op:remark

The remark operation contains message and success fields.

{
  "op":"remark",
  "message":<MESSAGE FROM THE SERVER>,
  "success":<boolean>
}

op:private

The payloads of the op:private messages contain the real time market information. Each message follows this form:

{
  "channel":<CHANNEL_ID>,
  "op":"private",
  "private":<MESSAGE_TYPE>,
  <MESSAGE_TYPE>:<DATA_PAYLOAD>
}

The MESSAGE_TYPE field may take the values:

MESSAGE_TYPE Description
ticker Ticker messages
trade Trades, as they occur
depth Orders placed or removed

Ticker

Ticker messages contain the current inside Bid and Ask as well as daily highs, lows, and volume. The fields contained in the ticker match those defined in the version 1.0 API above. All fields contain currency, display, value, and value_int entries.

{
  "channel":"d5f06780-30a8-4a48-a2f8-7ed181b4a13f",
  "op":"private",
  "origin":"broadcast",
  "private":"ticker",
  "ticker":{
    "avg":{
      "currency":"USD",
      "display":"$2.26847",
      "value":"2.26847",
      "value_int":"226847"
    },
    "buy":{...},
    "high":{...},
    "last":{..},
    "last_local":{...},
    "last_orig":{...},
    "low":{...},
    "sell":{...},
    "vol":{
      "currency":"BTC",
      "display":"118,696.02104208",
      "value":"118696.02104208",
      "value_int":"11869602104208"
    },
    "vwap":{...}
  }
}

Trade

{
  "channel":"dbf1dee9-4f2e-4a08-8cb7-748919a71b21",
  "op":"private",
  "origin":"broadcast",
  "private":"trade",
  "trade":{
    "amount":2.71,
    "amount_int":"271000000",
    "date":1310279340,
    "item":"BTC",
    "price":14.43,
    "price_currency":"USD",
    "price_int":"1443000",
    "primary":"Y",
    "properties":"limit, mixed_currency",
    "tid":"1310279340877902",
    "trade_type":"bid",
    "type":"trade"
  }
}

trade contains the following:

Name Value
amount the traded amount in item (BTC), float, deprecated
amount_int the traded amount * 1E8
date unix timestamp of trade
item What was this trade about
price price per unit, float, deprecated
price_int price in smallest unit as integer (5 decimals of USD, 3 in case of JPY)
price_currency currency in which trade was completed
tid Trade id (big integer, which is in fact trade timestamp in microseconds)
trade_type Did this trade result from the execution of a bid or a ask?

Depth

Changes to the market depth data are broadcast so an up-to-date market depth can be kept by clients.

{
  "channel":"24e67e0d-1cad-4cc0-9e7a-f8523ef460fe",
  "depth":{
    "currency":"USD",
    "item":"BTC",
    "now":"1323644358437819",
    "price":"14.43",
    "price_int":"1443000",
    "total_volume_int":"849766000",
    "type":1,
    "type_str":"ask",
    "volume":"-2.71",
    "volume_int":"-271000000"
  },
  "op":"private",
  "origin":"broadcast",
  "private":"depth"
}

depth contains the following:

Name Value
currency the currency affected
item the item (BTC)
price price as a float, deprecated
price_int the price at which volume change happened (5 decimal for USD, 3 for JPY)
type 1=ask, 2=bid. deprecated, use type_str
type_str type of order at this depth, either "ask" or "bid"
volume the volume change as float, deprecated
volume_int volume change * 1E8

Outgoing commands

Direct commands

Commands that can be sent without authentication

unsubscribe

Stop receiving messages from a channel

{
    "op":"unsubscribe", 
    "channel":<CHANNEL ID>
}

Responds with an identical message to confirm

mtgox.subscribe

Subscribe to a channel to start receiving messages from it.

{
    "op": "mtgox.subscribe",
    "type": "ticker"
}

"type" can be ticker, trades, or depth.

Authenticated commands

These commands require an API key and secret pair to sign requests. Any of the "version 1" requests from the HTTP API can be called.

{
    "op":"call",
    "id":<REQUEST ID>,
    "call":<BASE-64 ENCODED SIGNED REQUEST>,
    "context":"mtgox.com"
}

<REQUEST ID> can be any string, it's used to identify the response as belonging to this request when an answer comes back. md5'ing your nonce is a good way to get an id. "call" must be a base-64 encoded string consisting of, in order: an API key, a signed copy of the response, and the response text itself.

The queries themselves look like:

{
    "id":<REQUEST ID>,
    "call":<HTTP API ENDPOINT>,
    "nonce":<REQUEST NONCE>,
    "params":<REQUEST PARAMETERS>,
    "item":"BTC"
}

<HTTP API ENDPOINT> is the last two path components of any version 1 API endpoint, for example private/info, or public/cancelledtrades.

<REQUEST PARAMETERS> is optional for any request that doesn't have parameters.

The signing process is similar to the HTTP API, but because we can't send headers in an open websocket, the API key and signed request are simply prepended to the actual query data and base64 encoded. Reference implementations are available at https://github.com/MtGox/websocket

Here's a sample of how to create a valid request in PHP 5.3:

$nonce = explode(' ', microtime(false));
$nonce = $nonce[1].substr($nonce[0], 2, 6);
$id = md5($nonce); // id can be anything to recognize this call
$query = array('call' => $call, 'params' => $params, 'item' => $item, 'currency' => $currency, 'id' => $id, 'nonce' => $nonce);
$query = json_encode($query);
// generate signature
$sign = hash_hmac('sha512', $query, base64_decode($apiSecret), true);
// prefix signature to query
$query = pack('H*', str_replace('-','',$apiKey)).$sign.$query;
// send query
$call = array('op' => 'call', 'call' => base64_encode($query), 'id' => $id, 'context' => 'mtgox.com');
// $call can now be pushed out to the websocket

examples

ticker

javascript, using hookio :

http://www.youtube.com/watch?v=KD5ljtNK72U

http://github.com/hookio

http://github.com/cronopio/hook.io-mtgox

Another node.js project, using plain websockets (largely based on cronopio's work) :

https://github.com/dlanod/node-mtgox-websocket-client

arbitrage

https://github.com/goteppo/ArBit

websocket

https://github.com/cronopio/hook.io-ws

https://github.com/dlanod/node-mtgox-websocket-client

References