Simplify ESI Queries By Using /search/
This blog post is part of a series of blogs examining best practices for ESI development. Each blog will be published on the 8th of each month during the journey towards XML API and CREST’s termination date. The legacy APIs will be terminated on May 8th, 2018, or earlier if metrics signal a trivial level of usage.
How would you find the type ID of a Rifter using ESI?
It is easy for a new ESI developer to feel overwhelmed by this simple question. How should it be solved? It's likely that the solution an ESI novice would come up with would be to:
- Get all types using /universe/types/.
- Feed each type into /universe/type/{type_id}/ until you find what you are looking for.
However, that would be ridiculous! ESI supplies an endpoint for just such a case: /search/.
What is /search/?
/search/ is a public endpoint that allows you to enter a search string and will return a list of IDs containing the given string in a given category. The following categories can be selected and are passed in as a query parameter (categories that require further explanation are followed by a "-"):
- agent - Used to find NPC characters that give out missions.
- alliance
- character
- constellation
- corporation
- faction - Used to find NPC factions.
- inventory_type - Used to find the type ID of any entity in the game that could be considered an "item" (e.g. ships, blueprints, modules, etc.).
- region
- solar_system
- station - This doesn't cover POS's or citadels.
There is also an authenticated search endpoint: /characters/{character_id}/search/. This authenticated endpoint adds one more category named structure
and will allow you to search for upwell structures your character has access to.
Now let's look at an example of using /search/ to answer the question posed at the beginning of this blog.
Getting a Rifter's type ID using /search/
Which of the search categories would be best to use when searching for a Rifter's type ID? Looking at the list of categories it's apparent that we should search using the inventory_type
category. Let's make a request to /search/ by using curl
with the query parameters categories=inventory_type
and search=Rifter
.
$ curl "https://esi.tech.ccp.is/v2/search/?categories=inventory_type&search=Rifter"
This request returns:
{
"inventory_type":[
587,
691,
33664,
33666,
34748,
34749,
35493,
35494,
35495,
35496,
35497,
35498,
35499,
35500,
36411,
36754,
36801,
36992,
36993,
40470,
44166,
45554,
45936
]
}
All the IDs returned have the word "Rifter" in them and we can check what they are by dropping them into /universe/types/{type_id}/. Let's take a look
at type ID 587
using curl
:
$ curl "https://esi.tech.ccp.is/v3/universe/types/587/"
which returns:
{
"type_id": 587,
"name": "Rifter",
"description": "The Rifter is a very powerful combat frigate and can easily tackle the best frigates out there. It has gone through many radical design phases since its inauguration during the Minmatar Rebellion. The Rifter has a wide variety of offensive capabilities, making it an unpredictable and deadly adversary.",
"published": true,
"group_id": 25,
"market_group_id": 64,
"radius": 31,
"volume": 27289,
"packaged_volume": 2500,
"capacity": 140,
"portion_size": 1,
"mass": 1067000,
"graphic_id": 46,
"dogma_attributes": [
... // Denotes that there is content but it is being reduced for example's sake.
]
"dogma_effects": [
...
]
}
This is exactly what we were looking for! So what are the other type IDs? 681
is a "Rifter Blueprint", 33664
is a "Rifter Nefantar Edition Blueprint" and the rest are left up to the reader to look into if they feel so compelled. As you can see, any type ID that has the word "Rifter" is shown. How would we restrict this search to only return type ID 587
? By passing in strict=true
as a query parameter! The strict
query parameter will look for exact matches only, let's try it:
$ curl "https://esi.tech.ccp.is/v2/search/?categories=inventory_type&search=Rifter&strict=true"
which returns:
{
"inventory_type": [
587
]
}
Using multiple categories at a time
It is possible to pass up to 10 categories at once by using a comma (",") separated list as the value of the categories
query parameter. Let's do a search for the word "Awesome" in all categories:
$ curl "https://esi.tech.ccp.is/v2/search/?search=Awesome&categories=agent,alliance,character,constellation,corporation,faction,inventory_type,region,solar_system,station"
This returns (edited for length):
{
"character":[
...452 character IDs...
],
"corporation":[
...47 corporation IDs...
]
"station":[
61000138
]
}
There are 452 characters, 47 corporations and 1 station that contain the word "Awesome" (as of the writing of this blog). You can get more info on the characters returned by dropping their IDs into the /characters/{character_id}/ endpoint. You can drop the corporation IDs into /corporation/{corporation_id/} and you can drop the station ID into /universe/stations/{station_id}/.
Conclusion
The /search/ endpoint can simplify your queries and will save you the pain of iterating through thousands of IDs until you find the one you want. Go forth and search!
As always, you can discuss all things ESI on the tweetfleet slack (use this link to join) in the #esi channel.
o7
-- Team Tech Co.
Appendix
The following paths have been added or updated in ESI since the previous blog:
- GET /latest/characters/{character_id}/bookmarks/ (v2)
- GET /latest/characters/{character_id}/bookmarks/folders/ (v2)
- GET /latest/alliances/{alliance_id}/contacts/ (v1)
- GET /latest/characters/{character_id}/fw/stats/ (v1)
- GET /latest/characters/{character_id}/mining/ (v1)
- GET /latest/characters/{character_id}/titles/ (v1)
- GET /latest/characters/{character_id}/wallet/journal/ (v3)
- GET /latest/corporations/{corporation_id}/bookmarks/ (v1)
- GET /latest/corporations/{corporation_id}/bookmarks/folders/ (v1)
- GET /latest/corporations/{corporation_id}/containers/logs/ (v1)
- GET /latest/corporations/{corporation_id}/contracts/ (v1)
- GET /latest/corporations/{corporation_id}/contracts/{contract_id}/bids/ (v1)
- GET /latest/corporations/{corporation_id}/contracts/{contract_id}/items/ (v1)
- GET /latest/corporations/{corporation_id}/customs_offices/ (v1)
- GET /latest/corporations/{corporation_id}/facilities/ (v1)
- GET /latest/corporations/{corporation_id}/fw/stats/ (v1)
- GET /latest/corporations/{corporation_id}/industry/jobs/ (v1)
- GET /latest/corporations/{corporation_id}/medals/ (v1)
- GET /latest/corporations/{corporation_id}/medals/issued/ (v1)
- GET /latest/corporations/{corporation_id}/members/titles/ (v1)
- GET /latest/corporation/{corporation_id}/mining/observers/ (v1)
- GET /latest/corporation/{corporation_id}/mining/observers/{observer_id}/ (v1)
- GET /latest/corporations/{corporation_id}/orders/ (v1)
- GET /latest/corporations/{corporation_id}/roles/history/ (v1)
- GET /latest/corporations/{corporation_id}/standings/ (v1)
- GET /latest/corporations/{corporation_id}/starbases/ (v1)
- GET /latest/corporations/{corporation_id}/starbases/{starbase_id}/ (v1)
- GET /latest/corporations/{corporation_id}/wallets/{division}/journal/ (v2)
- GET /latest/universe/factions/ (v2)
- POST /latest/corporations/{corporation_id}/assets/locations/ (v1)
- POST /latest/corporations/{corporation_id}/assets/names/ (v1)
Get a sneak peek at what's coming to ESI by watching our deployment timeline
Migrating from the XML API? Find equivalent ESI endpoints to the XML API.
Migrating from CREST? Find Equivalent ESI endpoints to CREST