Lawton Campbell.8517:

We’ve just turned on our second authenticated endpoint! It allows players to delegate access to their current and historical Black Lion Trading Post transactions (basically everything that’s shown in the “My Transactions” tab of the in-game Trading Post). There’s more details available in the CDI thread, but for posterity I’ll post some example request/responses.

It’s important to note that all URLs provided by this endpoint require an API key with the “tradingpost” permission.

The first two levels of the URL basically just point to what’s available on lower levels (for self-discovery purposes):

    GET /v2/commerce/transactions HTTP/1.1
    Authorization: Bearer insert-token-here

    HTTP/1.1 200 OK
    Content-Type: application/json

    [
      "current",
      "history"
    ]

Both “current” and “history” endpoints provide separate lists for “buys” and “sells” — due to technical constraints it’s infeasible for us to collate them meaningfully.

    GET /v2/commerce/transactions/current HTTP/1.1
    Authorization: Bearer insert-token-here

    HTTP/1.1 200 OK
    Content-Type: application/json

    [
      "buys",
      "sells"
    ]

Finally, the meat of the endpoint is a paginated list of the last 90 days of transactions (unfortunately, older transactions aren’t available). In the response headers there’s data about the total result set, as well as an RFC5988 Link header. As usual, pagination is controlled via the page and page_size URL parameters.

    GET /v2/commerce/transactions/history/buys?page_size=2 HTTP/1.1
    Authorization: Bearer insert-token-here

    HTTP/1.1 200 OK
    Content-Type: application/json
    X-Page-Size: 2
    X-Page-Total: 143
    X-Result-Count: 2
    X-Result-Total: 286
    Link: , </v2/commerce/transactions/history/sells?page=0&page_size=2>; rel=self, </v2/commerce/transactions/history/sells?page=0&page_size=2>; rel=first, </v2/commerce/transactions/history/sells?page=142&page_size=2>; rel=last

    [
      {
        "id": 2757359846,
        "item_id": 44971,
        "price": 19998,
        "quantity": 1,
        "created": "2015-05-12T06:36:12+00:00",
        "purchased": "2015-05-12T16:55:14+00:00"
      },
      {
        "id": 2756695824,
        "item_id": 24713,
        "price": 425,
        "quantity": 1,
        "created": "2015-05-12T06:35:33+00:00",
        "purchased": "2015-05-12T08:36:50+00:00"
      }
    ]

In the actual body, it’s important to note that the id field does not necessarily correspond when an order is filled (and thus moves from “current” to “history”). This is mostly because for e.g. a sale of 50, there may be multiple buy orders at different dates.

Another constraint to be aware of is that cancelled orders are basically removed from the list. There’s not a clean way right now to discern between a cancelled and filled order, but since only commodities can be traded, it likely isn’t a huge deal.

Finally, the “purchased” field is omitted for the “current” endpoint, since those orders haven’t yet been filled.

Anyway, if you’ve got any questions/concerns post ‘em here and I’ll do my best to address ’em.

EDIT: Also, there’s a 5 minute cache on responses, so you don’t need to poll it that often.

Tiscan.8345:

Edit: Looks like the TP is bugged at the moment (2015-05-13, 11:00 GMT) and its not a problem with my code.


I’ve got some problems accessing some endpoints… if i use https://api.guildwars2.com/v2/commerce/transactions or https://api.guildwars2.com/v2/commerce/transactions/current I get the same results as shown in your posting.

But using https://api.guildwars2.com/v2/commerce/transactions/history/buys?page_size=2 or https://api.guildwars2.com/v2/commerce/transactions/history/buys (or anything else i tried) returns either a 502-HTML Error-Page or a JSON-Object stating “ErrTimeout”.

My very simple PHP-Code:

$token = ‘INSERT TOKEN!!!’;

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,“https://api.guildwars2.com/v2/commerce/transactions/history/buys?page_size=2”);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$headers = array();
$headers[] = ’Authorization: Bearer ’.$token;

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$server_output = curl_exec ($ch);

curl_close ($ch);

if (is_json($server_output)) {
print_r(json_decode($server_output));
} else {
var_dump($server_output);
}

function is_json($str){
return json_decode($str) != null;
}

Did I mess up or is there a problem with the API?

AllIsVain.6409:

EDIT: Also, there’s a 5 minute cache on responses, so you don’t need to poll it that often.

Will this be getting reduced in the future, or is this a “take as given” limitation on the API (30 seconds was more what I was hoping for)

smiley.1438:

I’ve got some problems accessing some endpoints…
[…]

You need to pass along a few more options to curl to make it work with SSL:


curl_setopt_array($ch, [
	CURLOPT_URL            => $url,
	CURLOPT_SSL_VERIFYPEER => true,
	CURLOPT_SSL_VERIFYHOST => 2,
	CURLOPT_CAINFO         => '/path/to/cacert.pem', // download from: http://curl.haxx.se/ca/cacert.pem
	CURLOPT_RETURNTRANSFER => true,
]);

Tiscan.8345:

If SSL was the problem, none of the requests would work (and I can access everything else just fine – and even if I add the SSL-stuff, i still get the same errors).

But it looks like the Trading Post is bugged right now… according to the german and english bug-forums, people can’t access it.

AllIsVain.6409:

If SSL was the problem, none of the requests would work (and I can access everything else just fine – and even if I add the SSL-stuff, i still get the same errors).

But it looks like the Trading Post is bugged right now… according to the german and english bug-forums, people can’t access it.

It’s currently down as far as I can tell. I had it working using similar code to what you had (adapted for my needs).

Lawton Campbell.8517:

Did I mess up or is there a problem with the API?

Yeah there were some unrelated server issues last night; let me know if you’re still experiencing problems.

EDIT: Also, there’s a 5 minute cache on responses, so you don’t need to poll it that often.

Will this be getting reduced in the future, or is this a “take as given” limitation on the API (30 seconds was more what I was hoping for)

5 minutes is our current default; I couldn’t immediately think of any use-cases that would benefit from a reduced TTL so I just left it as default. What did you have in mind?

AfterXII.2761:

Slightly unrelated question, do we know the max character limit on API Keys? (Building a database for accounts and need to know for optimizations)

Nabrok.9023:

Slightly unrelated question, do we know the max character limit on API Keys? (Building a database for accounts and need to know for optimizations)

It’s two GUIDs back-to-back, so char(72) will cover it.

You could get fancy and store it in binary if you really want to. I think this would only require 32 bytes, but you have to write code to handle transferring it back and forth.

AllIsVain.6409:

EDIT: Also, there’s a 5 minute cache on responses, so you don’t need to poll it that often.

Will this be getting reduced in the future, or is this a “take as given” limitation on the API (30 seconds was more what I was hoping for)

5 minutes is our current default; I couldn’t immediately think of any use-cases that would benefit from a reduced TTL so I just left it as default. What did you have in mind?

I was thinking of writing an application that got your recently bought items, extracted the price you bought them for and then gave your a price that would be optimal for resale (a peak price) based on factors. I was planning on integrating this into an overlay, so when you bought an item it ‘immediately’ flashed up showing the best price for flipping. There is no adverse affect for the cache being 5 minutes, it would just make it less streamlined.

Arridath.1087:

EDIT: Also, there’s a 5 minute cache on responses, so you don’t need to poll it that often.

Will this be getting reduced in the future, or is this a “take as given” limitation on the API (30 seconds was more what I was hoping for)

5 minutes is our current default; I couldn’t immediately think of any use-cases that would benefit from a reduced TTL so I just left it as default. What did you have in mind?

I can think of a few scenarios where immediate access would be useful. I can’t really think of a use that wouldn’t be restricted by a 5 minute cache.

Wizeon.3852:

I have a problem using this with jQuery ajax requests. The problem is that there is no
Access-Control-Allow-Headers reported by the server, so the preflight request (method OPTIONS) aborts the whole thing. Or is there another way to add the authorization header to the request that wouldn’t trigger the preflight?

And I’d also like the cache to be reduced from 5 minutes, on this endpoint and prices. I can’t track listing changes reliably with a 5 minute cache, no way to get any idea about the velocity of items if you only get a snapshot every 5 minutes. It was great with the old api when you could do pretty much what you can do in-game, refresh the listings every other second and see what orders get filled and how fast.

For this specific case I’d like to alert the user whether their listing is still the top one, or if the listing was fulfilled without the user camping their TP screen. Even a 1 minute would be more useful than the current 5 minute one.

edit: Temporarily solved the ajax problem by not using headers but get parameters which is obviously not the ideal way to go, but at least it works. And the 5 minute timer pretty much makes the tool un-usable, if I put a buy order up it might take 5 minutes for it to show up, and then when it’s filled it might again take 5 minutes for the program to realise it’s been filled. Current version at http://mayumi.fi/gw2tp/

Oh, and to get both buy and sell orders do I have to make two requests, to /buys and to /sells or is there a combined endpoint somewhere?

Lawton Campbell.8517:

I have a problem using this with jQuery ajax requests. The problem is that there is no
Access-Control-Allow-Headers reported by the server, so the preflight request (method OPTIONS) aborts the whole thing. Or is there another way to add the authorization header to the request that wouldn’t trigger the preflight?

Ah, I forgot to put it in the notes again. You can pass the API key via the ?access_token parameter instead of the Authorization header. By doing that you’ll have a simple request which won’t trigger the preflight (which we don’t support).

And I’d also like the cache to be reduced from 5 minutes, on this endpoint and prices. I can’t track listing changes reliably with a 5 minute cache, no way to get any idea about the velocity of items if you only get a snapshot every 5 minutes.

The /v2/commerce/listings endpoint currently has a 1-second cache. It’s the only one currently that enjoys a non-5-minute cache.

Oh, and to get both buy and sell orders do I have to make two requests, to /buys and to /sells or is there a combined endpoint somewhere?

It’d have to be two requests; I really wanted it to have it the other way but there were some interesting technical constraints.

Wizeon.3852:

Thanks! In the end the get parameter is the only way to go then if I don’t want to send the user API key to my backend first which could handle the authorisation headers without preflight.

I posted about the 1 second cache on the fair-use thread since it doesn’t actually seem to be a 1 second cache.

Is there any chance to drop the cache timer on the transactions endpoint to a more reasonable one? Even 1 minute or the previously requested 30 seconds would be so much more useful in tracking your current orders “live” from outside the game.

Lawton Campbell.8517:

The cache time on /v2/commerce/transactions is going to drop to 1min; just pushed out the config change, it should take effect within the hour.

Ultimately, polling HTTP isn’t a good medium for these use-cases. I mostly intended the endpoint to be used for offline purposes — e.g., export and data analysis. For a real-time dataflow it would be better for all parties if we used a protocol to push data down to the consumer. Unfortunately, our backend isn’t currently designed to support such an access pattern, so I’m not sure if we’ll ever be able to satisfy that use-case.

Not saying that it’ll never happen, just that there’s a lot of work to be done to support real-time notifications e.g., HTTP long polling or websockets or server-sent events or what have you.

rodadams.5963:

I’ll point out that we can overcome not having backend support for this. You could build a single internal scanner, which would poll the backend with as fast an update speed as you can, and then when you notice a change, push that out.

It’s not a perfect solution, but it’s an option.

Wizeon.3852:

I don’t think your API is obeying the config values, but is using some global 5min cache regardless of what’s in the config.

/v2/commerce/transactions still has a 5min delay if I change an order as soon as I see the last change occur, and /v2/commerce/listings is supposed to have 1sec cache but it’s 5min as well.

Lawton Campbell.8517:

I don’t think your API is obeying the config values, but is using some global 5min cache regardless of what’s in the config.

Yeah, I have a feeling that bit is broken. It’s one of the few bits that I don’t have unit tests for. I’ll try to get that fixed.

Pat Cavit.9234:

Found & fixed the cache bug on dev, will try to get it deployed next week.

Wizeon.3852:

Thanks a lot! Nice to know that devs are listening

cephiroth.6182:

One question regarding pagination:
The situation I am thinking of is that the client is iterating over the pages while the data changes. Is this covered by the server in any way (e.g. producing a snapshot on loading page 0) or does the client have to deal with incomplete or duplicate result sets?

Lawton Campbell.8517:

You should probably handle incomplete/duplicate result sets if you care about fidelity.

Most of the unauthenticated endpoints don’t change their data until a patch lands though, so it’s not really that big of a deal. The only place it’ll really bite you (maybe) is the transactions endpoint.

Risingashes.8694:

Would it be possible to expose items waiting in a character’s Delivery Box?

This would be very helpful information personally.

Devilsown.9376:

Only 50 trades are shown over /transactions/current/sells

Arround June, I thought it’s only for the first time, for testing the Api, so I didn’t ask, but in between I think I should:
Is that intentional or is it a mistake?

Eearslya.6309:

You’re hitting the default page limit. Use the ?page and ?page_size request variables (max size of 200 per page) to get more results.

Devilsown.9376:

Ups, I’d forgotten that thing with page.
Thank you for the hint.