Making an API: The Steam WebAPI Proposal

Steam WebAPI Proposal

Steam WebAPI Proposal by Seg

Developing my updated portfolio, I realized I had a lot of API development experience that was internal and can’t be disclosed in the public. While I’m accomplished in interactive narratives, I needed to supplement my portfolio with my technical design aspect background.

I decided to make a proposal to extend the Steam WebAPI with information missing from the current offerings. I’ve worked with WebAPI and Steamworks with Telltale Games; Particularly the global statistical displays for Jurassic Park and Puzzle Agent 2. Recently I started contributing to Steam Condenser and discovered the Groups info was still in an XML format announced as deprecated by Valve. Yet there was no WebAPI method to fill the gap. I decided to dust off my API design skills and get to work!

I’ll go though some of the more detailed background of certain decisions, but do take a look at the docs!

Rules to Propose By

Setting some guidelines for myself helps my focus. The proposal is building upon an existing API in production, so the additions needed to make sense in the existing environment. At large, these guidelines were:

  • Use same variable names for exactly similar types.
  • Use existing Interfaces & Methods when logical.
  • Outputs should be similar to existing WebAPI returns in JSON, XML, & VDF.
  • Don’t be afraid to create new interfaces, methods, and variable types when justifiable.

ISteamHub

Creating a way to obtain information from the communities around Steam. Until recently, these were called Groups in the Steam Community system. As this proposal is looking forward to the future of the platform, I decided using the new moniker of “Hubs” was more appropriate.

Official Game Hubs vs. Community Hubs

Steam Community Hubs fall into two board categories. Hubs created officially for specific products, and all other hubs anyone can create. I wanted to treat each type equally while allowing the unique attributes to be searched for and exposed.

Searching for a Hub

When searching for a hub, there are a few use cases I planned for:

  • ISteamHub::ResolveVanityURL
    • Specific Group request via the vanity URL.
  • ISteamHub::ResolveAppID
    • Any group related to a specific AppID.
    • The official game group of a specific AppID.

The method ISteamHub::ResolveVanityURL is a direct carbon copy of the existing method, ISteamUser::ResolveVanityURL.

For searching based on AppID, I found ResolveVanityURL too confusing to roll in. I could use the same method but a different input parameter for an AppID and official flag, but that’s overcrowding the function’s purpose. The method ISteamUser::ResolveAppID allows searching based on AppID. An optional official flag filters if the request wants to include unofficial hubs.

Hub Information

ISteamHub::GetSummaries is the workhorse of ISteamHub. The method contains all other information I didn’t push out to other methods. Most information is straight forward, but some decisions are made for ease of use for WebAPI users.

The inputs will take either a full Hub ID number — known as guid — or an AppID number. Adding the AppID number allows for instant pull of the official hub without adding the extra ::ResolveAppID call.

Regardless of input, the output is the same information as applicable. Some fields like `avatar` include entries that are for both Game hubs and community. Since the expectation of image sizes are different, the same field didn’t make sense. It’s a different image size, thus a different expectation of behavior. A “NULL” is much easier to work with than an image sized incorrectly than expected.

Hub Announcements

ISteamHub::GetAnnouncements is patterned directly after ISteamNews::GetNewsForApp as both offer similar returns of data. The unique aspect with Announcements is the privacy settings for groups. I made an assumption that one can make a WebAPI Key show or hide announcements based on the settings made.

Hub Events

I feel the event system needs a bit of tweaking in general and used the proposal to outline issues around event types. The existing ones feel irrelevant or even condescending.

As part of the spec, I included a rewrite of the type’s description text and added a new “OnlineEvent” title. “OnlineEvent” allows for events that refer to a URL for video streaming or other type of online event. For example, The International event for DOTA2 can be included as an event with a direct link to the online stream. This type also opens the ‘eventurl’ field for the event creator to include a URL.

Hub Member Status ISteamHub::GetStatus

The old Community XML stats included the number of members who were online, playing a game, and total membership. The refresh rate for this information is a lot more in flux than ISteamHub::GetSummaries information, so a new method made sense.

I also included playeroftheweek. While not as frequently changed as the other bits of info, Player of the Week is more frequently updated than summary info.

ISteamApps

The next phase was developing out information from the Steam store. There isn’t a way for applications to procedurally work with applications available on the platform. I would love to see various widgets and other fun things with this information!

Same Interface, New Methods

The ISteamApps interface already exists, so adding a few new methods to it seemed appropriate. I also didn’t have a previous method to base my designs on, so I went and made something new. I also threw every bit of information possible with a Steam App having filled out most of this information before for many Telltale Games titles.

Separating Media

I pulled media related to a call out from the omnibus that is ISteamApps::GetAppData, besides image URLs. Calling for screenshots and trailers of a project is a lot more request heavy, so pulling it out to a different method made sense.

Movies were a bit of a mystery as far as what data is available to share, so the given information is a bit basic but would function.

Pricing not included.

I’m not knowledgeable enough of the Steam platform to make a decent specification for pricing. While I could have made something, I like making a specification that closely pairs the existing implementation of pricing. I don’t have visibility on how Steam runs pricing so it’s a method I had to skip… FOR NOW.