0x Mesh
Search…
GraphQL API documentation

0x Mesh GraphQL API Documentation

The GraphQL API is intended to be a private API. The API should only be accessible to the developers running the Mesh node and should not be exposed to the public. The API runs on a separate port from the peer-to-peer protocols and access to it can be controlled via a firewall.
Peers in the network do not use the GraphQL API and instead use a peer-to-peer PubSub mechanism (usually this is not something you need to worry about).

About GraphQL

GraphQL is a structured query language for APIs. It:
  • Is transport layer agnostic (e.g. HTTP, WebSockets, or calling a function).
  • Is type-safe and uses well-structured schemas.
  • Has wide support across many programming languages.
  • Has great tooling (including automatic doc generation and playground environments).
  • Features built-in support for subscriptions.
  • Allows clients to only receive the data that they need in the format that they need it.

Playground Environment

We have deployed a public playground environment for exploring the GraphQL API. You can access the playground at https://meshmock.spaceship.0x.org/. It supports auto-completion, syntax highlighting, and subscriptions. In addition, interactive documentation for the API can be found by clicking the "docs" button on the righthand side of the screen. See the Example Queries section below for some queries to try.
If you prefer, you can also send requests directly over HTTP without using a dedicated client.

Example Queries

This section includes some example queries which you can copy and paste in the playground. Of course, you would typically write queries programmatically with a GraphQL client, not by manually writing them. This is just for illustrative purposes.

Getting a Specific Order

You can get the details for any order by its hash:
1
{
2
order(hash: "0x38c1b56f95bf168b303e4b62d64f7f475f2ac34124e9678f0bd852f95a4ca377") {
3
hash
4
chainId
5
exchangeAddress
6
makerAddress
7
makerAssetData
8
makerAssetAmount
9
makerFeeAssetData
10
makerFee
11
takerAddress
12
takerAssetData
13
takerAssetAmount
14
takerFeeAssetData
15
takerFee
16
senderAddress
17
feeRecipientAddress
18
expirationTimeSeconds
19
salt
20
signature
21
remainingFillableTakerAssetAmount
22
}
23
}
Copied!

Querying and Filtering Orders

You can get all orders via the orders query. By default, it will return up to 100 orders at a time sorted by their hash. You can also change the number of orders returned via the limit argument.
1
{
2
orders {
3
hash
4
chainId
5
exchangeAddress
6
makerAddress
7
makerAssetData
8
makerAssetAmount
9
makerFeeAssetData
10
makerFee
11
takerAddress
12
takerAssetData
13
takerAssetAmount
14
takerFeeAssetData
15
takerFee
16
senderAddress
17
feeRecipientAddress
18
expirationTimeSeconds
19
salt
20
signature
21
remainingFillableTakerAssetAmount
22
}
23
}
Copied!
The orders query supports many different options. Here's an example of how to get orders with a minimum expirationTimeSeconds and minimum remainingFillableAssetAmount. You can use this to exclude dust orders and orders which may expire too soon.
1
{
2
orders(
3
filters: [
4
{ field: remainingFillableTakerAssetAmount, kind: GREATER_OR_EQUAL, value: "150000" }
5
{ field: expirationTimeSeconds, kind: GREATER_OR_EQUAL, value: "1598733429" }
6
]
7
) {
8
hash
9
makerAddress
10
makerAssetData
11
makerAssetAmount
12
takerAddress
13
takerAssetData
14
takerAssetAmount
15
expirationTimeSeconds
16
remainingFillableTakerAssetAmount
17
}
18
}
Copied!
Here's an example of sorting orders by the remainingFillableAssetAmount. You can combine any number of filters and sorts in an orders query.
1
{
2
orders(sort: [{ field: remainingFillableTakerAssetAmount, direction: DESC }]) {
3
hash
4
makerAddress
5
makerAssetData
6
makerAssetAmount
7
takerAddress
8
takerAssetData
9
takerAssetAmount
10
expirationTimeSeconds
11
remainingFillableTakerAssetAmount
12
}
13
}
Copied!

Adding Orders

You can add orders using a mutation.
1
mutation AddOrders {
2
addOrders(
3
orders: [
4
{
5
signature: "0x1c91055b1ce93cdd341c423b889be703ce436e25fe62d94aabbae97528b4d247646c3cd3a20f0566540ac5668336d147d844cf1a7715d700f1a7c3e72f1c60e21502"
6
senderAddress: "0x0000000000000000000000000000000000000000"
7
makerAddress: "0xd965a4f8f5b49dd2f5ba83ef4e61880d0646fd00"
8
takerAddress: "0x0000000000000000000000000000000000000000"
9
makerFee: "1250000000000000"
10
takerFee: "0"
11
makerAssetAmount: "50000000000000000"
12
takerAssetAmount: "10"
13
makerAssetData: "0xf47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
14
takerAssetData: "0xa7cb5fb7000000000000000000000000d4690a51044db77d91d7aa8f7a3a5ad5da331af0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000e3a2a1f2146d86a604adc220b4967a898d7fe0700000000000000000000000009a379ef7218bcfd8913faa8b281ebc5a2e0bc040000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001360000000000000000000000000000000000000000000000000000000000000004"
15
salt: "1584796917698"
16
exchangeAddress: "0x61935cbdd02287b511119ddb11aeb42f1593b7ef"
17
feeRecipientAddress: "0x0d056bb17ad4df5593b93a1efc29cb35ba4aa38d"
18
expirationTimeSeconds: "1595164917"
19
makerFeeAssetData: "0xf47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
20
chainId: 1
21
takerFeeAssetData: "0x"
22
}
23
{
24
signature: "0x1bf931ab06551bbbd3a7e272ca4833503d768caca2cac564b157b46c906c7b41c57fd6146b500e1ad2dac729c351142764cb76efc975c6d7c64aef6cf7930c075d02"
25
senderAddress: "0x0000000000000000000000000000000000000000"
26
makerAddress: "0x0c5fa5fa51d84227bfacdc56b36329286b37d051"
27
takerAddress: "0x0000000000000000000000000000000000000000"
28
makerFee: "0"
29
takerFee: "0"
30
makerAssetAmount: "50911000000000000"
31
takerAssetAmount: "10000000000000000000"
32
makerAssetData: "0xf47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
33
takerAssetData: "0xf47261b000000000000000000000000058b6a8a3302369daec383334672404ee733ab239"
34
salt: "1590244702461"
35
exchangeAddress: "0x61935cbdd02287b511119ddb11aeb42f1593b7ef"
36
feeRecipientAddress: "0xa258b39954cef5cb142fd567a46cddb31a670124"
37
expirationTimeSeconds: "1592663792"
38
makerFeeAssetData: "0x"
39
chainId: 1
40
takerFeeAssetData: "0x"
41
}
42
]
43
) {
44
accepted {
45
order {
46
hash
47
}
48
isNew
49
}
50
rejected {
51
hash
52
code
53
message
54
}
55
}
56
}
Copied!

Subscribing to Order Events

You can subscribe to order events via a subscription.
1
subscription {
2
orderEvents {
3
timestamp
4
endState
5
order {
6
hash
7
remainingFillableTakerAssetAmount
8
}
9
}
10
}
Copied!

Getting Stats

You can get some stats about your Mesh node via the stats query.
1
{
2
stats {
3
version
4
pubSubTopic
5
rendezvous
6
peerID
7
ethereumChainID
8
latestBlock {
9
number
10
hash
11
}
12
numPeers
13
numOrders
14
numOrdersIncludingRemoved
15
startOfCurrentUTCDay
16
ethRPCRequestsSentInCurrentUTCDay
17
ethRPCRateLimitExpiredRequests
18
maxExpirationTime
19
}
20
}
Copied!

Additional Tips

Pagination

We recommend paginating through orders by using filters and limit. So for example, if you want to sort orders by their hash (which is the default), you first send a query without any filters:
1
{
2
orders {
3
hash
4
makerAddress
5
makerAssetData
6
makerAssetAmount
7
takerAddress
8
takerAssetData
9
takerAssetAmount
10
expirationTimeSeconds
11
remainingFillableTakerAssetAmount
12
}
13
}
Copied!
The orders in the response will be sorted by hash (which is the default). Look at the last order you received, which in this case has a hash of 0x75d2b56b11f21235ec8faec8be9d081090678cf62f5c69fa118236d829424719. Send the next request by using the last hash you received in a filter:
1
{
2
orders(
3
filters: [
4
{ field: hash, kind: GREATER, value: "0x75d2b56b11f21235ec8faec8be9d081090678cf62f5c69fa118236d829424719" }
5
]
6
) {
7
hash
8
makerAddress
9
makerAssetData
10
makerAssetAmount
11
takerAddress
12
takerAssetData
13
takerAssetAmount
14
expirationTimeSeconds
15
remainingFillableTakerAssetAmount
16
}
17
}
Copied!
This will return any orders with a hash greater than 0x75d2b56b11f21235ec8faec8be9d081090678cf62f5c69fa118236d829424719. Repeat this process, changing the hash each time, until there are no orders left.
There may be orders added or removed while you are in the process of paginating. Following this method guarantees that:
  1. 1.
    No order will be included more than once.
  2. 2.
    Any order which was present at the start of pagination and at the end of pagination will be included.
  3. 3.
    Any order which was added or removed after pagination started may or may not be included.

Query Fragments

GraphQL requires you to specify all the fields that you want included in the response. However, you can use query fragments to avoid repeating the same fields over and over. Here's an example of a query fragment that includes all the fields of an order.
1
fragment AllOrderFields on OrderWithMetadata {
2
hash
3
chainId
4
exchangeAddress
5
makerAddress
6
makerAssetData
7
makerAssetAmount
8
makerFeeAssetData
9
makerFee
10
takerAddress
11
takerAssetData
12
takerAssetAmount
13
takerFeeAssetData
14
takerFee
15
senderAddress
16
feeRecipientAddress
17
expirationTimeSeconds
18
salt
19
signature
20
remainingFillableTakerAssetAmount
21
}
22
23
{
24
order(hash: "0x06d15403630b6d73fbacbf0864eb76c2db3d6e6fc8adec8a95fc536593f17c54") {
25
...AllOrderFields
26
}
27
}
Copied!