Close Navigation
Learn more about IBKR accounts

Contract Search

Lesson 3 of 11
Duration 10:37
Level Intermediate
Close Navigation

In this lesson, we will be discussing how contract information is requested from only knowing the contract’s symbol. Following this methodology, you will be able to make requests throughout the series for a variety of contracts using the contract ID. This will cover stock, future, options, and futures options discovery.

Study Notes:

Hello, and welcome to this lesson on the Interactive Brokers Client Portal API. In this lesson, we will be discussing how to find a contract id using the contract symbol, how to pull option chain data, and how to pull future data.

Searching for contract by underlying symbol

To begin, let’s start with searching for a contract by the underlying symbol. We can import the same libraries from the last episode. Now I will create a method for our request, contractSearch() method.

With the framework set, we can go back to the contractSearch() method and add some variables. I will create our base_url variable once again, and an endpoint variable set to “iserver/secdef/search”. This endpoint allows us to search for an underlying symbol or company name and retrieve a relevant contract ID. The contract ID, or conid, is a unique contract identifier that will correspond to a specific symbol, security type, and currency. Every contract at Interactive Brokers will have a unique ID.

Once we have built our URL, we will need to use a JSON body. I will create the variable, ‘json_body’, and set it equal to a set of curly brackets to create an array value. Inside these brackets we need to create a few fields. In this case, we’ll create “symbol”, “secType”, and “name”. For Symbol I will use “ES”, and for secType, I will use “STK”. For the moment, I will set “name” to “false”. This field can be used to search for a company name instead of just the standard symbol.

With the body set, I will create a reference to our coming request. I’ll create the variable ‘contract_req’ and set it equal to requests.post. Here we can set the URL to our base_url+endpoint and verify to False. Then the ‘json’ tag to the variable, json_body.

We can show the response status code in the console by printing our contract_req variable. Before doing so, I will use the json library to help make this more legible. We will print the json-encoded content of the response using json.dumps. Json.dumps function will convert a string into a json dictionary.  The parameters are the contract_req.json() and indent=2. If indent is a non-negative integer, the json array elements will be pretty-printed with that indent level.

Once we have added these initial parameters we can now run this code and view the returned values. Initially our status Response code [200] indicates that the request has succeeded.

In this case there is a long list of values returned. First, we can see the conid we were initially looking for along with the companyHeader, name, description, as well as further information relating to each security type. As this lists all contracts with symbol ES, we can also see further conids and companyNames returned. For example, Eversource Energy and Esso STE in this case.

How to request contract details for Futures

Next, we will be calling the iserver/secdef/info endpoint for more informative Contract Details based on conid. It is important for derivatives to call the /secdef/search endpoint for the underlying contract before calling any other secdef endpoints. We will use the previously obtained conid for ES, or the E-mini S&P 500, in this case.

When requesting contract details for Futures, we can use the same initial python file while then creating our new contract_info.py file.

In this case, the futures_url variable will point to the iserver/secdef/info endpoint and the parameters will contain the conid, sectype, month and exchange values. These details can all be pulled from our prior request.

Parameters are unique from how a json body is constructed. Instead of a comma separated array, we will be appending a question mark, followed by the parameter set equal to our value, and then delimited using an ampersand. So, to construct this, I will create four variables.

  • conid=”conid=11004968″
  • secType=”secType=FUT”
  • month=”month=SEP23″
  • exchange=”exchange=CME”

Then I will create the variable “params” and set it equal to ‘“&”.join([conid,sectype,month,exchange])’. This will concatenate all of my strings with an ampersand between them. We can then follow this by defining request_url and setting that equal to ‘“”.join([base_url, endpoint, “?”, params])’. Now, we have a full url that displays our base url, our endpoint, and then a question mark to signify our parameters are starting. Finally, we end the string with our concatenated parameters string.

While this can certainly all be written in a single string for our example, this is a common structure to help with automating the request flow once you have developed a self-sufficient program.

Now, we can wrap up this program by creating another Get request and assigning it to contract_req. We will use our request_url as the destination to create our request. Now if we print the status value and the json.dumps value of our request, we can see a range of details on our futures contract. If we ever need to double check a derivative conid, review the validExchanges of the contract, or otherwise.

We can now run this code and see the futures contract details returned as expected.

How to request contract info for options

Requesting Options or Futures Options are quite similar. In the case of options or futures options, we must request the secdef/search endpoint, followed by the secdef/strikes endpoint before requesting the info or rules endpoint. Regardless of whether you have the contract ID beforehand or not, these endpoints must be called first.

Now can create a new file for the strikes endpoint to represent this. I will use the same framework we have been operating with, and create a new method called strikeSearch(). I will create and endpoint variable referencing the iserver/secdef/strikes string. Just like my secdef/info endpoint, I will create a conid, sectype, month, and exchange variable. I will set the conid to the underlying contract ID field, secType to “FOP”, month to “JUL23” to review the July 23 futures option, and finally in the case of Futures Options, I will define the exchange as CME. It is important to note that for standard options, you may leave out the Exchange value, as SMART is set by default.

Maintaining the other formatting as I had before, when I call this endpoint, I will see a huge range of all potential strikes a contract could use. With my knowledge of my current expiry and strike information, I will make a call to the info endpoint for my futures option. I can maintain all the same parameters as with my prior call to /info, but now include both a strike, which I will set to ‘4800’, and right, which I will set to C for ‘Call’. With my derivative contract IDs found, I can now proceed to request market data, place orders, and more.

Thank you for watching this lesson on Contract Details in the Client Portal API. If you find this lesson helpful, please check out our other lessons in the Client Portal API tutorial series.

Code Snippet – contractDetails.py

import requests
import json

# Disable SSL Warnings
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# reauthenticate
def contractSearch():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "iserver/secdef/search"

    json_body = {"symbol" : "ES", "secType": "STK", "name": False}

    contract_req = requests.post(url=base_url+endpoint, verify=False, json=json_body)

    contract_json = json.dumps(contract_req.json(), indent=2)
    print(contract_json)

if __name__ == "__main__":
    contractSearch()

Code Snippet – contractInfo.py

import requests
import json

# Disable SSL Warnings
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# reauthenticate
def contractInfo():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "iserver/secdef/info"

    conid="conid=11004968"
    secType = "secType=FOP"
    month = "month=JUL23"
    exchange = "exchange=CME"
    strike = "strike=4800"
    right = "right=C"

    params = "&".join([conid, secType, month, exchange, strike, right])
    request_url = "".join([base_url, endpoint, "?", params])

    contract_req = requests.get(url=request_url, verify=False)
    contract_json = json.dumps(contract_req.json(), indent=2)

    print(contract_req)
    print(contract_json)

if __name__ == "__main__":
    contractInfo()

contractStrikes.py

import requests
import json

# Disable SSL Warnings
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# reauthenticate
def contractStrikes():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "iserver/secdef/strikes"

    conid = "conid=11004968"
    secType = "secType=FOP"
    month = "month=JUL23"
    exchange = "exchange=CME"

    params = "&".join([conid, secType, month, exchange])
    request_url = "".join([base_url, endpoint, "?", params])

    strikes_req = requests.get(url=request_url, verify=False)
    strikes_json = json.dumps(strikes_req.json(), indent=2)

    print(strikes_req)
    print(strikes_json)

if __name__ == "__main__":
    contractStrikes()

Join The Conversation

If you have a general question, it may already be covered in our FAQs. If you have an account-specific question or concern, please reach out to Client Services.

12 thoughts on “Contract Search”

  • Al-Sheikh Muhammad bin Abdulaziz al-Saud bin Abdulrahman bin Faisal bin Turki bin Abdullah bin Muhammad bin Saud says:

    Hello – the video linked here seems to be the same video that’s linked in the next lesson for market data.

    • Hello, thank you for bringing this to our attention. The Contract Search video has been posted. We hope you continue to engage with our lessons!

    • Hello Andy, thank you for bringing this to our attention. The Contract Search video has been posted. We hope you continue to engage with our lessons!

  • hello, very instreseting. Howeve when I run Code Snippet – contractDetails.py I got th is erro
    {
    “error”: “Init session first”,
    “statusCode”: 400
    }

    • Hello Adam, thank you for reaching out. It looks like your session is not initialized. We would recommend reviewing Lesson 2: Launching and Authenticating the Gateway. If you have any other questions or concerns on this topic, we recommend contacting Client Services for further troubleshooting.

  • Please confirm, if I want to simply get the conid for a STK = MSFT, is there a way to just get the search to return it rather than the whole JSON object. I am having trouble searching the JSON as it has multiple objects with secType = STK and in those records sometimes there are no connid’s. here is the object for MSFT

    [
    {
    “conid”: “272093”,
    “companyHeader”: “MICROSOFT CORP – NASDAQ”,
    “companyName”: “MICROSOFT CORP”,
    “symbol”: “MSFT”,
    “description”: “NASDAQ”,
    “restricted”: null,
    “fop”: null,
    “opt”: “20240105;20240112;20240119;20240126;20240202;20240209;20240216;20240315;20240419;20240517;20240621;20240719;20240816;20240920;20241220;20250117;20250620;20251219;20260116”,
    “war”: “20231130;20231201;20231205;20231206;20231207;20231208;20231211;20231212;20231213;20231214;20231215;20231219;20231220;20231221;20231222;20231227;20231228;20231229;20240104;20240105;20240111;20240112;20240116;20240117;20240118;20240119;20240126;20240209;20240213;20240214;20240215;20240216;20240308;20240312;20240313;20240314;20240315;20240417;20240418;20240419;20240515;20240516;20240517;20240614;20240618;20240619;20240620;20240621;20240718;20240917;20240918;20240919;20240920;20241217;20241218;20241219;20241220;20250114;20250115;20250116;20250117;20250318;20250319;20250320;20250321;20250617;20250618;20250619;20250620;20250918;20250919;20251216;20251218;20251219;20260113;20260114;20260115;20260116;20260319;20260616;20260618;20261217;20270114”,
    “sections”: [
    {
    “secType”: “STK”
    },
    {
    “secType”: “OPT”,
    “months”: “JAN24;FEB24;MAR24;APR24;MAY24;JUN24;JUL24;AUG24;SEP24;DEC24;JAN25;JUN25;DEC25;JAN26”,
    “exchange”: “SMART;AMEX;BATS;BOX;CBOE;CBOE2;EDGX;EMERALD;GEMINI;IBUSOPT;ISE;MERCURY;MIAX;NASDAQBX;NASDAQOM;PEARL;PHLX;PSE”
    },
    {
    “secType”: “WAR”,
    “months”: “NOV23;DEC23;JAN24;FEB24;MAR24;APR24;MAY24;JUN24;JUL24;SEP24;DEC24;JAN25;MAR25;JUN25;SEP25;DEC25;JAN26;MAR26;JUN26;DEC26;JAN27”,
    “exchange”: “BVME;EBS;FWB;GETTEX;SBF;SWB”
    },
    {
    “secType”: “IOPT”
    },
    {
    “secType”: “CFD”,
    “exchange”: “SMART”,
    “conid”: “118239139”
    },
    {
    “secType”: “BAG”
    }
    ]
    },
    {
    “conid”: “38708990”,
    “companyHeader”: “MICROSOFT CORP – MEXI”,
    “companyName”: “MICROSOFT CORP”,
    “symbol”: “MSFT”,
    “description”: “MEXI”,
    “restricted”: null,
    “fop”: null,
    “opt”: null,
    “war”: null,
    “sections”: [
    {
    “secType”: “STK”,
    “exchange”: “MEXI;”
    }
    ]
    },
    {
    “conid”: “518938052”,
    “companyHeader”: “MICROSOFT CORP-CDR – AEQLIT”,
    “companyName”: “MICROSOFT CORP-CDR”,
    “symbol”: “MSFT”,
    “description”: “AEQLIT”,
    “restricted”: null,
    “fop”: null,
    “opt”: null,
    “war”: null,
    “sections”: [
    {
    “secType”: “STK”
    }
    ]
    },
    {
    “conid”: “415569505”,
    “companyHeader”: “MICROSOFT CORP – EBS”,
    “companyName”: “MICROSOFT CORP”,
    “symbol”: “MSFT”,
    “description”: “EBS”,
    “restricted”: null,
    “fop”: null,
    “opt”: null,
    “war”: null,
    “sections”: [
    {
    “secType”: “STK”
    }
    ]
    },
    {
    “conid”: “493546075”,
    “companyHeader”: “LS 1X MSFT – LSEETF”,
    “companyName”: “LS 1X MSFT”,
    “symbol”: “MSFT”,
    “description”: “LSEETF”,
    “restricted”: null,
    “fop”: null,
    “opt”: null,
    “war”: null,
    “sections”: [
    {
    “secType”: “STK”
    }
    ]
    },
    {
    “issuers”: [
    {
    “id”: “e1393444”,
    “name”: “Microsoft Corp”
    }
    ],
    “bondid”: 5,
    “conid”: “2147483647”,
    “companyHeader”: “Corporate Fixed Income”,
    “companyName”: null,
    “symbol”: “MSFT”,
    “description”: null,
    “restricted”: null,
    “fop”: null,
    “opt”: null,
    “war”: null,
    “sections”: [
    {
    “secType”: “BOND”
    }
    ]
    }
    ]

    • Hello, thank you for reaching out. As you indicated, there are several instruments returned related to MSFT and return STK values. As such, you would need to filter the return details locally. Assuming you are looking to trade the U.S. Microsoft Corporation, you can use the “description” tag from each object to identify the exchange. So using python we can implement something like:

      for i in contract_req.json():

      if i[‘description’] == ‘NASDAQ’:

      print(i[‘conid’])

      Please reach back out with any more questions. We are here to help!

  • Hello, thank you for these instructional videos. It appears my contractDetails is working successfully, but when I attempt to run contractInfo or contractStrikes using the exact same code, I get ” no contracts received”, and an empty options chain, respectively. I have confirmed with my auth_status that my session is still enabled. Appreciate any thoughts.

    • Hello, thank you for reaching out. The typical reason that empty strikes may be retrieved, or an empty /info response is returned is because the underlying contract was not first requested through the /secdef/search endpoint. We would recommend double-checking that the underlying was requested with /secdef/search first, followed by /secdef/strikes, and finally /secdef/info when requesting options. If you have any additional questions or concerns, please contact our Customer Service team: https://www.interactivebrokers.com/en/support/customer-service.php

      We hope this helps!

  • Hello.
    Very grateful for the tutorials. Despite not being sure if this is what I’m looking for.
    My specific idea is to use the IBKR API to retrieve data from my portfolio, such as:
    Instruments I currently own.
    Date of purchase.
    Date of sale.
    Profits or losses in the trade.
    Transaction history of my portfolio.

    Then, I want to dump all this data into an Excel spreadsheet and analyze it separately.
    Are there endpoints available to make all the necessary requests?

Leave a Reply

Your email address will not be published. Required fields are marked *

Disclosure: Interactive Brokers

The analysis in this material is provided for information only and is not and should not be construed as an offer to sell or the solicitation of an offer to buy any security. To the extent that this material discusses general market activity, industry or sector trends or other broad-based economic or political conditions, it should not be construed as research or investment advice. To the extent that it includes references to specific securities, commodities, currencies, or other instruments, those references do not constitute a recommendation by IBKR to buy, sell or hold such investments. This material does not and is not intended to take into account the particular financial conditions, investment objectives or requirements of individual customers. Before acting on this material, you should consider whether it is suitable for your particular circumstances and, as necessary, seek professional advice.

The views and opinions expressed herein are those of the author and do not necessarily reflect the views of Interactive Brokers, its affiliates, or its employees.

Disclosure: API Examples Discussed

Throughout the lesson, please keep in mind that the examples discussed are purely for technical demonstration purposes, and do not constitute trading advice. Also, it is important to remember that placing trades in a paper account is recommended before any live trading.

IBKR Campus Newsletters

This website uses cookies to collect usage information in order to offer a better browsing experience. By browsing this site or by clicking on the "ACCEPT COOKIES" button you accept our Cookie Policy.