DarkSpirit.7046:

Looks like some valid item ids are flagged as invalid?

https://api.guildwars2.com/v2/commerce/prices?ids=18753

returns http status of 400 with:

{"text":“all ids provided are invalid”}

This is a valid item id:

https://api.guildwars2.com/v2/items?id=18753

If they are just not being sold on the TP, shouldn’t it be returning 404 instead? Same with these ids around the same range:

https://api.guildwars2.com/v2/commerce/prices?ids=18117,18118,18119,18120,18121,18122,18123,18125,18126,18127,18128,18129,18130,18131,18132,18133,18134,18135,18136,18137,18138,18139,18140,18141,18142,18143,18144,18145,18146,18147,18148,18149,18150,18151,18152,18153,18154,18155,18156,18157,18158,18159,18160,18161,18162,18163,18164,18165,18166,18167,18428,18429,18430,18431,18432,18433,18434,18435,18436,18437,18438,18439,18440,18441,18442,18443,18444,18445,18446,18447,18448,18449,18450,18451,18452,18453,18454,18455,18456,18457,18458,18459,18460,18461,18462,18463,18576,18577,18578,18579,18580,18581,18582,18583,18584,18585,18586,18587,18588,18589,18590,18591,18592,18593,18594,18595,18596,18597,18598,18599,18600,18601,18602,18603,18604,18605,18606,18607,18608,18609,18610,18611,18724,18725,18726,18727,18728,18729,18730,18731,18732,18733,18734,18735,18736,18737,18739,18740,18742,18743,18744,18745,18746,18748,18749,18750,18751,18752,18753,18754,18755

StevenL.3761:

Items that have the “AccountBound” flag can never appear on the trading post, so 404 would be less accurate than 400.

AysonCurrax.3254:

Items that have the “AccountBound” flag can never appear on the trading post, so 404 would be less accurate than 400.

Also, its Dungeon Armor :P

StevenL.3761:

Another thought: the ids returned by /v2/commerce are not item ids, but listing ids that also happen to be item ids. A valid listing id is always a valid item id, but not the other way around.

AysonCurrax.3254:

Another thought: the ids returned by /v2/commerce are not item ids, but listing ids that also happen to be item ids. A valid listing id is always a valid item id, but not the other way around.

also, only items with sell listings can actually be obtained ingame. I would ignore those who only have buy listings.

DarkSpirit.7046:

Items that have the “AccountBound” flag can never appear on the trading post, so 404 would be less accurate than 400.

Items that have the “AccountBound” flag can never appear on the trading post, so 404 would be less accurate than 400.

Also, its Dungeon Armor :P

Then they are “not found” on the trading post and thus should be 404. The item ids are valid, just not traded.

10823567815618, “hello” or even the string “^IFuihrqwudo3”, however, would not be a valid item id and I correctly get 400 back. I just don’t consider 18753 to be of the same category. But since they both return 400, my code has to handle them the same way regardless of whether they are not traded or truly invalid.

StevenL.3761:

HTTP 404 doesn’t exclude the possibility of the item being listed at a later time. Why are you including /v2/item IDs in your request for /v2/commerce endpoints?

There are only two categories:

  • valid: ids returned by the /v2/commerce/prices endpoint
  • invalid: everything else

DarkSpirit.7046:

HTTP 404 doesn’t exclude the possibility of the item being listed at a later time. Why are you including /v2/item IDs in your request for /v2/commerce endpoints?

404 just means that the item is “not found” in the database, in this case the commerce or TP database.

If you don’t include /v2/item IDs then how would your app know the names of the items and their stats just from the /v2/commerce endpoints?

Also, how would you search for the prices of all the armor, for example?

HTTP 404 doesn’t exclude the possibility of the item being listed at a later time. Why are you including /v2/item IDs in your request for /v2/commerce endpoints?

There are only two categories:

  • valid: ids returned by the /v2/commerce/prices endpoint
  • invalid: everything else

With that definition, then /v2/items is returning some invalid item ids as these items are not traded and not returned by /v2/commerce.

However, with 404, I am saying these item ids are valid because they are returned by /v2/items but they just “not found” in /v2/commerce.

StevenL.3761:

valid ids: https://api.guildwars2.com/v2/commerce/prices
invalid ids: https://api.guildwars2.com/v2/items unless also on the /v2/commerce list

DarkSpirit.7046:

valid ids: https://api.guildwars2.com/v2/commerce/prices
invalid ids: https://api.guildwars2.com/v2/items unless also on the /v2/commerce list

That is one interpretation. My interpretation is that /v2/items defines what a valid item and its id is, not /v2/commerce.

StevenL.3761:

You seem to be under the impression that an item will not appear in /v2/commerce unless it has outstanding buy or sell offers.

DarkSpirit.7046:

You seem to be under the impression that an item will not appear in /v2/commerce unless it has outstanding buy or sell offers.

Nope. My impression is that calling an item id as ‘invalid’ if they are not traded is wrong.

There are many valid items, with valid item ids, that can’t be traded.

Furthermore, a good service conveys as much pertinent information to the client as it can. Differentiating between an invalid item id (e.g. the string “RE78y63”) and a valid item that is not found in the trading post (e.g. the item id string “18753”) would be a start.

StevenL.3761:

Okay, but these are the IDs of the actual buy/sell offers, not the ID of the item being bought/sold. An item does not have to have a listing.

DarkSpirit.7046:

Okay, but these are the IDs of the actual buy/sell offers, not the ID of the item being bought/sold. An item does not have to have a listing.

Whether an item id is valid or not would depend on how you define what a valid or invalid item id is.

I define a valid item id as one that is returned by /v2/items, otherwise it is invalid because it would not represent any known valid item.

Therefore /v2/commerce does not get to contradict /v2/items and redefine that 18753 is not a valid item id when /v2/items already says that it is. /v2/commerce can say that item id 18753 is “not found” (i.e. status 404) in its commerce database.

StevenL.3761:

It doesn’t say that there is no item with id 18753. It says that there is no listing with id 18753. Just forget that they are using item ids as listing ids. They could have picked any other number.

DarkSpirit.7046:

It doesn’t say that there is no item with id 18753. It says that there is no listing with id 18753. Just forget that they are using item ids as listing ids. They could have picked any other number.

No it says that item id 18753 is invalid:

https://api.guildwars2.com/v2/commerce/prices?ids=18753
returns http status of 400 with:
{"text":“all ids provided are invalid”}

But if you ask /v2/items, 18753 is a valid item id. The 2 services shouldn’t contradict each other and there should be a distinction between items “not found” (status 404) and invalid item ids.

https://api.guildwars2.com/v2/items?ids=18753

StevenL.3761:

Your argument is based on the assumption that the listing service knows (or should know) about both listings and items. It doesn’t know about items, in the exact same way that the quaggans service doesn’t know about items either.

https://api.guildwars2.com/v2/quaggans?ids=18753

At the risk of sounding like a broken record, the commerce service uses LISTING ids, not item ids. (and definitely not quaggan ids)

DarkSpirit.7046:

Your argument is based on the assumption that the listing service knows (or should know) about both listings and items. It doesn’t know about items,

Then it should know about items which is what the API documentation on the wiki depicts. Otherwise, API documentation wouldn’t match behavior.

Dr Ishmael.9685:

The wiki documentation was written players/users, not by Pat or Stefan or anyone else at Anet. If it’s wrong, change it (if you’re not in the API user group, then post on the talk page and ask for someone else to change it).

DarkSpirit.7046:

The wiki documentation was written players/users, not by Pat or Stefan or anyone else at Anet. If it’s wrong, change it (if you’re not in the API user group, then post on the talk page and ask for someone else to change it).

What would you decide to change? The documentations or the API? What is a bug and what is a feature?

Doesn’t someone in Anet review the documentations depicting how their APIs should behave in their official wiki? What is the expectation Anet has for developers to learn to use their APIs correctly, if not from the API documentation in their official wiki?

Again, it benefits both parties (ANet and their developers) to have good communications, which should be one of the reasons for this forum to exist in the first place. Distancing themselves from their devs who support their APIs and the people who maintain their API documentations is not a good start.

StevenL.3761:

Let’s do a thought experiment. First, explicitly add the item_id to the output.


{  
   "id":24,
   "item_id":24,
   "buys":{  
      "quantity":1501,
      "unit_price":2144
   },
   "sells":{  
      "quantity":305,
      "unit_price":4598
   }
}

 
This representation more accurately shows how the API is structured internally (primary key == foreign key pointing at item_id).

For the experiment, change the primary key scheme to something more arbitrary. I’ll pick auto-incrementing numbers that start at 1.


{  
   "id":1,
   "item_id":24,
   "buys":{  
      "quantity":1501,
      "unit_price":2144
   },
   "sells":{  
      "quantity":305,
      "unit_price":4598
   }
}

 

Now that the id is no longer equal to the item_id, what should the error code be when all ids are invalid?

/v2/commerce/prices?ids=24

Assume that listing_id 24 does not already exist in the output of /v2/commerce/prices.

DarkSpirit.7046:

I don’t understand your point. Why do you have to add a new property item_id when there is already id? The id property is the item id.

http://wiki.guildwars2.com/wiki/API:2/commerce/prices

Sounds like you are making broad assumptions on how they may have implemented this internally without confirmations from them. Going down this rat hole of assumptions would only lead to more confusion as more broad assumptions are made. Please stick with the facts that we already know so as to not detract this thread.

StevenL.3761:

Everything I’ve said so far is based entirely on observations. The id is NOT the same as the item id. I can explain it to you, but I can’t understand it for you.

StevenL.3761:

Why do you have to add a new property item_id when there is already id?

Just so there are no misunderstandings. This object…


{  
   "id":24,
   "buys":{ ... },
   "sells":{ ... }
}

 
is semantically equal to this object…


{  
   "id":24,
   "item_id":24,
   "buys":{ ... },
   "sells":{ ... }
}
 
This is true no matter how you twist and turn it, because that is how relational databases are designed.

The point of my post was that the primary key (“id”) is not part of the entity. It is simply an implementation detail. Implementation details can be changed without changing the design. In my example, I split the column “id” (PK, FK) into two separate columns “id” (PK) and “item_id” (FK). Just changing the implementation, not the design.

Once you understand all that, try to answer the original (strictly hypothetical) question: if the “id” column is not a foreign key for “item_id”, what should the error code be when all given price ids are non-existent?

StevenL.3761:

Spoiler:
The error should be 400 across all possible implementations. The reasoning is that even though the "id" value right now is implemented as a foreign key for the "item_id", it is not appropriate for the API to return 404, because that would be a design that depends on a specific implementation.

Pat Cavit.9234:

We aren’t going to change this behavior right now, I’m sorry you find it confusing but it’s not something we can easily workaround given that /v2/items and /v2/commerce/prices are going against different systems that have different ideas on what valid items are.

I’m not comfortable with special casing the commerce APIs right now, so they will continue to return the standard error.

Dr Ishmael.9685:

I’ll take a shot at explaining this a different way to try to help DarkSpirit understand.

The /v2/items endpoint tells you that a given number X is a valid item_id. Great, you know a valid item ID in the context of items.

You take this number X and pass it to the /v2/commerce/listings endpoint. It tells you it’s an invalid ID in the context of commerce.

The different endpoints have complete different contexts. Just because X is a valid ID in an item context doesn’t mean it’s also a valid ID in a commerce context. That’s all any endpoint will tell you: whether the ID is valid within the context of that endpoint. These endpoints have no knowledge of each other – commerce is only concerned with its own commerce context, it doesn’t care and it can’t tell you about whether X is valid in an items context.

DarkSpirit.7046:

I’ll take a shot at explaining this a different way to try to help DarkSpirit understand.

The /v2/items endpoint tells you that a given number X is a valid item_id. Great, you know a valid item ID in the context of items.

You take this number X and pass it to the /v2/commerce/listings endpoint. It tells you it’s an invalid ID in the context of commerce.

The different endpoints have complete different contexts. Just because X is a valid ID in an item context doesn’t mean it’s also a valid ID in a commerce context. That’s all any endpoint will tell you: whether the ID is valid within the context of that endpoint. These endpoints have no knowledge of each other – commerce is only concerned with its own commerce context, it doesn’t care and it can’t tell you about whether X is valid in an items context.

That is what I fear that the idea of a valid item would have to boil down to the context of the endpoint which would be confusing because an item may be valid in one end point and yet be invalid in another even though it is a valid item in the game. But I would have to live with this.

We aren’t going to change this behavior right now, I’m sorry you find it confusing but it’s not something we can easily workaround given that /v2/items and /v2/commerce/prices are going against different systems that have different ideas on what valid items are.

I’m not comfortable with special casing the commerce APIs right now, so they will continue to return the standard error.

Thanks Pat. I understand that it is difficult to change the APIs right now but it is already special casing what the valid item ids are, based on what endpoints that you query against.

Clarification: By the way, I am not trying to be a “hard-kitten ” demanding a fix, I know you guys have your priorities. I am just stating an opinion.

Illconceived Was Na.9781:

I’ll take a shot at explaining this a different way to try to help DarkSpirit understand.

The /v2/items endpoint tells you that a given number X is a valid item_id. Great, you know a valid item ID in the context of items.

You take this number X and pass it to the /v2/commerce/listings endpoint. It tells you it’s an invalid ID in the context of commerce.

The different endpoints have complete different contexts. Just because X is a valid ID in an item context doesn’t mean it’s also a valid ID in a commerce context. That’s all any endpoint will tell you: whether the ID is valid within the context of that endpoint. These endpoints have no knowledge of each other – commerce is only concerned with its own commerce context, it doesn’t care and it can’t tell you about whether X is valid in an items context.

If I understand you correctly, that would cover items that have appeared in the game, but never been listed or requested on the TP. That is, when item #12345 is first dropped, that number would be a valid v2/items item_id. But until it’s also offered for sale, it would still be an invalid v2/commerce id.

Seems to me that’s reasonable for the API and then it would be up to 3rd party developers how they want to deal with the distinction, as opposed to ANet imposing a solution.

Dr Ishmael.9685:

That is what I fear that the idea of a valid item would have to boil down to the context of the endpoint which would be confusing because an item may be valid in one end point and yet be invalid in another even though it is a valid item in the game. But I would have to live with this.

It’s not confusing, at least not to me. Context is supremely important: you shouldn’t “boil down” to it, you should start from it.

The /items endpoint is the only proper place to determine the validity of an item ID precisely because that is this endpoint’s context. The context of the /commerce endpoints is limited to the trading post, and this limitation means that the validity of an ID in this endpoint does not imply the validity of that ID in a general context.

DarkSpirit.7046:

That is what I fear that the idea of a valid item would have to boil down to the context of the endpoint which would be confusing because an item may be valid in one end point and yet be invalid in another even though it is a valid item in the game. But I would have to live with this.

It’s not confusing, at least not to me. Context is supremely important: you shouldn’t “boil down” to it, you should start from it.

The /items endpoint is the only proper place to determine the validity of an item ID precisely because that is this endpoint’s context. The context of the /commerce endpoints is limited to the trading post, and this limitation means that the validity of an ID in this endpoint does not imply the validity of that ID in a general context.

It is confusing because there is no single endpoint that defines what is a valid item and what is not. Each endpoint would have its own definition.

The /items endpoint does not determine the validity of an item id, because the /commerce endpoint can invalidate any of them within its own context (e.g. 18753). I would think that the items listed in the /items endpoint would be the superset of the items listed in the /commerce endpoint such that some item ids are valid in /items and /commerce while others are only valid in /items. But I am even sure if that is the current situation right now as far as the current states of the APIs.

DarkSpirit.7046:

I’ll take a shot at explaining this a different way to try to help DarkSpirit understand.

The /v2/items endpoint tells you that a given number X is a valid item_id. Great, you know a valid item ID in the context of items.

You take this number X and pass it to the /v2/commerce/listings endpoint. It tells you it’s an invalid ID in the context of commerce.

The different endpoints have complete different contexts. Just because X is a valid ID in an item context doesn’t mean it’s also a valid ID in a commerce context. That’s all any endpoint will tell you: whether the ID is valid within the context of that endpoint. These endpoints have no knowledge of each other – commerce is only concerned with its own commerce context, it doesn’t care and it can’t tell you about whether X is valid in an items context.

If I understand you correctly, that would cover items that have appeared in the game, but never been listed or requested on the TP. That is, when item #12345 is first dropped, that number would be a valid v2/items item_id. But until it’s also offered for sale, it would still be an invalid v2/commerce id.

Seems to me that’s reasonable for the API and then it would be up to 3rd party developers how they want to deal with the distinction, as opposed to ANet imposing a solution.

Precisely why that is confusing. I don’t know how 3rd party apps can know the difference between an item that has not been offered for sale and an item that can never be sold (e.g. item id 123456 or account-bound items), since I would imagine that they return the same error code in both situations.

+15 agony infusion should be tradeable but at this point in time, none are being sold. They give the same 400 http error code.

https://api.guildwars2.com/v2/items?ids=49438

https://api.guildwars2.com/v2/commerce/prices?ids=49438

Perhaps the way to tell these cases apart is to also check against /items and see if the item exists. If it exists in /items and not in /commerce and it is not soulbound or accountbound, then maybe it is just not sold. If it doesn’t exist in /items and doesn’t exist in /commerce then it is an invalid item or an old item that was removed from the game. If it doesn’t exist in /items but it exists in /commerce then it is a bug maybe?

StevenL.3761:

So the commerce back-end does not have any record of items up until the first time that they are offered for sale by a player? I think that’s the real problem.

I don’t know how item “discovery” works exactly, but that same mechanism should probably create an empty price listing for the newly discovered item.

DarkSpirit.7046:

I had a hunch that the items, prices, listings endpoints were implemented similarly right down to their error-handling.

https://api.guildwars2.com/v2/items
https://api.guildwars2.com/v2/commerce/prices
https://api.guildwars2.com/v2/commerce/listings

They each have their own set of valid item ids. These sets are not static, items ids are added as they are discovered and can also be removed. I assume that the discovery process is different between /items and /prices (they better be!).

For the /items endpoint if the provided item id does not exist within its set of item ids, it is regarded as an invalid item id. That makes sense for /items, since it defines the set of valid items in the game.

On the other hand, the /prices endpoint may be implemented in a similar way: If the provided item id, given to /prices, does not exist within its set of valid item ids, it is regarded as an invalid item id. This is confusing. Classifying an item id as invalid because the item is not being sold maybe counter intuitive to customers which is the point of this thread.

This is not optimal but there are two options for app developers to workaround this:

1. Show a generic error message (e.g. “item not in trading post”) and let the customer figure it out whether it does not exist in the game, it can’t be traded, it is removed, or it is simply not sold. Most apps would probably take this option. Pro: Fast and simple, Con: May confuse newer players.

Or alternatively,

2. Do a second web search on /items to determine why the item is not in /prices or /listings. Pro: Able to offer a more informative message Con: Slower

Dr Ishmael.9685:

On the other hand, the /prices endpoint may be implemented in a similar way: If the provided item id, given to /prices, does not exist within its set of valid item ids, it is regarded as an invalid item id. This is confusing. Classifying an item id as invalid because the item is not being sold maybe counter intuitive to customers which is the point of this thread.

Wrong. That is NOT what the /prices endpoint is telling you – that’s the whole point of what I’ve been trying to say. Instead, it’s telling you that it’s an invalid Trading Post ID, because that’s the limit of what /prices knows about.

DarkSpirit.7046:

On the other hand, the /prices endpoint may be implemented in a similar way: If the provided item id, given to /prices, does not exist within its set of valid item ids, it is regarded as an invalid item id. This is confusing. Classifying an item id as invalid because the item is not being sold maybe counter intuitive to customers which is the point of this thread.

Wrong. That is NOT what the /prices endpoint is telling you – that’s the whole point of what I’ve been trying to say. Instead, it’s telling you that it’s an invalid Trading Post ID, because that’s the limit of what /prices knows about.

You see, now you just threw in a new term, “Trading Post ID” which so happens to be very close to “item id”. So much for confusion…. oh by the way, don’t forget “Listings Trading Post ID” too because they have their own set of ids distinct from prices as it is on a different endpoint but hey they maybe the same but potentially not. I am so glad that everything is much clearer now!

Dr Ishmael.9685:

Oh kitten it, you’re not listening.

DarkSpirit.7046:

Oh kitten it, you’re not listening.

listening doesn’t imply agreeing.

I don’t see how throwing in more new terms is going make this any less messy.

StevenL.3761:

Id for /items has a single meaning: item_id.
Id for /prices has two meanings: listing_id and item_id.

When /prices says “invalid id”, it only refers to one meaning: invalid listing_id. Is everyone 100% clear on these concepts?

There are actually item_ids for which a listing_id is marked invalid when it shouldn’t be. Agony infusion +15 is the perfect example. It is tradeable, so it should have a listing_id. Even if that listing has no current offers, and thus a price of 0 gold.

StevenL.3761:

I assume that the discovery process is different between /items and /prices (they better be!).

I’m starting to believe that when a tradeable item is first discovered, the game should immediately make that item known to the commerce back-end in addition to the items back-end.

Pat Cavit.9234:

If an item doesn’t exist in the commerce systems, then it has never had a sell order placed for it.

This is to prevent people from placing buy orders for items before there are any being sold and thus influencing markets that don’t exist yet.

StevenL.3761:

Wouldn’t you be able to implement that restriction as an extra boolean flag “has_had_sell_orders” for each record on the database itself?

The in-game trading post would then filter records where
(has_had_sell_orders = true) to prevent abuse. The public API would not have the same restriction.

Pat Cavit.9234:

That’s not how it is currently implemented, and changing core tenants of the commerce systems solely to tweak API behavior is incredibly unlikely to happen.

StevenL.3761:

Yeah. It’s easy enough to just catch the error and assume that the price is 0 gold, since that’s what the return value would have been. Still, it’s fun to think about these things.

StevenL.3761:

Suppose that I’m the first and only person to offer +15 agony infusion for sale. That would open up bidding for everyone, right? Considering that there is only a single object for sale, it would probably be gone within minutes, but bidding continues. Did the system succeed in preventing people from influencing the market?

StevenL.3761:

If anyone else wants to have some fun with this, I compiled a list of all discovered, tradeable items that have never been offered for sale: http://pastebin.com/fnztsawL (132 items at the time of writing)

https://api.guildwars2.com/v2/items?ids=8481,9012,9017,9225,9650,9691,9694,9701,9748,9755,9763,9776,9778,9780,9788,9789,9794,9796,9798,9803,9805,9973,9976,9978,9981,9994,9997,9999,10003,10005,10016,10017,10018,10021,10022,10091,10092,10093,10094,10097,10098,10100,10101,10102,10117,10121,10127,10128,10172,10180,10181,10186,10190,10192,10193,10198,10200,10204,10210,10211,10212,10213,10214,10217,10218,10220,10226,10227,10228,10229,10231,10232,12610,12623,12646,12658,12662,12663,12665,12688,12689,12697,12703,12706,21269,21270,21271,21309,21310,21311,21320,21321,21322,21323,21324,21325,35531,35534,35539,35540,35541,35545,35546,35548,35549,36332,37192,37194,37196,38073,38088,38470,39414,39415,39422,39430,39432,39433,39435,39446,39451,39452,39456,39457,44849,44910,45248,49438,49439,49451,64197,66243

edit: I forgot to filter out PvP items. Sorry.