Part Query API

The part query API is a low level API that returns actual components that meet the specified criteria.

We recommend using the Higher level Part Query accessors to query for parts.

The JITX database currently supports 4 categories. Detailed information on how to query each category can be found at:

The API queries the JITX database containing millions of parts and supports:

  • filtering on attributes by equality, inequality or set of values,
  • optimizing on an attribute (for example smallest area or price),
  • querying for a specific number of parts
  • requiring some attributes to exist in the resulting parts (for example tolerance)
  • listing the available values for an attribute after filtering on other query parameters
  • integrate real-time sourcing data to the query

Part query results are cached in memory for future use. This can be particularly useful when using the jitx repl. The cache is lost when a jitx program exits.

Caching

Internet is required to perform the part queries the first time. All results are then cached to disk to be reused across sessions. To query fresh parts, clear the cache with:

stanza> import jitx/commands
stanza> clear-dbquery-cache()

Accessors

The part query API is imported from the package jitx/commands. Here are the accessors:

public defn dbquery (params: Tuple<KeyValue<String, Tuple<String>|Tuple<Double>|String|Double|Int>>, limit: Int) -> Tuple<JSON>

The maximum number of components that can be queried at a time by dbquery is 1000. Any value of limit in dbquery above 1000 will throw an error.

public defn dbquery-all (params: Tuple<KeyValue<String, Tuple<String>|Tuple<Double>|String|Double|Int>>) -> Tuple<JSON>

dbquery-all calls dbquery with a limit of 25. As our part database contains millions of resistors and hundreds of thousands of inductors and capacitors, dbquery-all cannot return all components that meet the query.

public defn dbquery-first (args: Tuple<KeyValue<String, Tuple<String>|Tuple<Double>|String|Double|Int>>) -> JSON

dbquery-first calls dbquery with a limit of 1, if no component is found, it throws a NoComponentMeetingRequirements

Examples

Querying the smallest 1Ω resistor:

stanza> import jitx/commands
stanza> val resistor-json = dbquery-first(["category" => "resistor", "resistance" => 1.0, "_sort" => ["area"]])
stanza> println(resistor-json)
JObject(entries = ["_id" => "0f3e3eeb6393f83d591a03c3" "trust" => "low" "category" => "resistor" "mpn" => "CRCW01001R00FYEL" "mounting" => "smd" "manufacturer" => "Vishay Dale" "type" => "chip" "dimensions" => JObject(entries = ["x" => 0.4 "y" => 0.2 "z" => 0.15 "area" => 0.08]) "stock" => 9355.0 "minimum_quantity" => 1.0 "metadata" => JObject(entries = ["datasheets" => "https://www.vishay.com/docs/20056/crcw01005e3.pdf" "image" => "//media.digikey.com/Renders/Vishay%20Dale%20Renders/CRCW-01005-(0402metric).jpg" "digi-key-part-number" => "541-4281-6-ND" "description" => "RES SMD 1 OHM 1% 1/32W 01005" "factory-stock" => 0.0 "unit-price" => "Digi-Reel" "qty" => 0.0 "packaging" => "Digi-Reel®" "series" => "CRCW" "supplier-device-package" => 1005.0 "number-of-terminations" => 2.0]) "tolerance" => JObject(entries = ["min" => -0.01 "max" => 0.01]) "resistance" => 1.0 "rated-power" => 0.03 "composition" => "thick-film" "tcr" => JObject(entries = ["pos" => -0.0002 "neg" => 0.0006]) "rated-temperature" => JObject(entries = ["min" => -55.0 "max" => 125.0]) "case" => "01005" "update_date" => "2021-09-04T01:35:34.335000"])
stanza> import ocdb/utils/db-parts
stanza> import json
stanza> println $ Resistor(resistor-json as JObject)
Resistor(
  mpn = CRCW01001R00FYEL
  trust = low
  (x, y, z) = (0.4, 0.2, 0.15)
  mounting = smd
  rated-temperature = MinMaxRange(min=-55.0, max=125.0)
  case = 01005
  type = chip
  tolerance = MinMaxRange(min=-0.01, max=0.01)
  resistance = 1.0
  composition = thick-film
  rated-power = 0.03
  TCR = TCR(positive=-0.0002, negative=0.0006)
  sourcing = ESR(price=false, minimum-quantity=1, stock=9355)
  metadata =
    "datasheets" => "https://www.vishay.com/docs/20056/crcw01005e3.pdf"
    "image" => "//media.digikey.com/Renders/Vishay%20Dale%20Renders/CRCW-01005-(0402metric).jpg"
    "digi-key-part-number" => "541-4281-6-ND"
    "description" => "RES SMD 1 OHM 1% 1/32W 01005"
    "factory-stock" => 0.0
    "unit-price" => "Digi-Reel"
    "qty" => 0.0
    "packaging" => "Digi-Reel®"
    "series" => "CRCW"
    "supplier-device-package" => 1005.0
    "number-of-terminations" => 2.0)

Querying some capacitors (at most 25 by default):

$ jitx repl
stanza> import jitx/commands
stanza> val capacitor-jsons = dbquery-all(["category" => "capacitor"])

Querying 200 inductors with 1µH inductance:

$ jitx repl
stanza> import jitx/commands
stanza> val inductor-jsons = dbquery(["category" => "inductor", "inductance" => 1.0e-6], 200)

Querying the list of available mcu cores in the JITX database:

$ jitx repl
stanza> import jitx/commands
stanza> val cores = dbquery-all(["category" => "microcontroller", "_distinct" => "core"])
stanza> println(cores)
["ARM Cortex-M0" "ARM Cortex-M0+" "ARM Cortex-M3" "ARM Cortex-M4" "ARM Cortex-M7"]

Querying the list of available packages for smd resistors:

$ jitx repl
stanza> import jitx/commands
stanza> println $ dbquery-all(["category" => "resistor" "mounting" => "smd", "_distinct" => "case"])
[JNull() "009005" "01005" "0201" "02016" "0202" "0302" "0303" "0402" "0404" "0503" "0505" "0603" "0612" "0805" "1206" "1210" "1218" "1812" "2-SMD, J-Lead" "2010" "2010 J-Lead" "2012 J-Lead" "2015" "2512"]

Creating a module with the cheapest smd resistor with a resistance of 1Ω±5%:

#use-added-syntax(jitx)
defpackage my-design :
  import jitx/commands

pcb-module my-module :
  inst resistor : dbquery-first(["resistance" => 10.0 "tolerance" => 0.05 "mounting" => "smd" "_sort" => ["cost"]])

Querying the list of packages available for mcus:

$ jitx repl
stanza> import jitx/commands
stanza> val packages = dbquery-all(["category" => "microcontroller" "_distinct" => "mfg-package"])
stanza> println(length(packages))
28
stanza> println(packages)
["LFBGA100" "LQFP100" "LQFP144" "LQFP176" "LQFP208" "LQFP48" "TFBGA216" "TFBGA225" "TFBGA64" "UFBGA100" "UFBGA132" "UFBGA169" "UFBGA64" "UFQFPN28" "UFQFPN32" "UFQFPN48" "WLCSP100" "WLCSP104" "WLCSP156" "WLCSP168" "WLCSP180" "WLCSP25" "WLCSP36" "WLCSP49" "WLCSP63" "WLCSP64" "WLCSP81" "WLCSP90"]

Querying the list of mcu mpns for package "WLCSP49":

$ jitx repl
stanza> import jitx/commands
stanza> val mpns = dbquery(["category" => "microcontroller" "mfg-package" => "WLCSP49" "_distinct" => "mpn"], 500)
stanza> println(length(mpns))
21
stanza> println(mpns)
["STM32F071CBY6" "STM32F071CBY7" "STM32F072CBY6" "STM32F072CBY7" "STM32F078CBY6" "STM32F303C8Y6" "STM32F318C8Y6" "STM32F334C8Y6" "STM32F334C8Y7" "STM32F411CCY6" "STM32F411CCY7" "STM32F411CEY6" "STM32F411CEY7" "STM32L071CBY6" "STM32L071CBY7" "STM32L071CZY6" "STM32L071CZY7" "STM32L073CZY6" "STM32L073CZY7" "STM32L082CZY6" "STM32L082CZY7"]

Querying the list for all bundles for all mcus with the package "WLCSP49":

$ jitx repl
stanza> import jitx/commands
stanza> val mcus = dbquery(["category" => "microcontroller" "mfg-package" => "WLCSP49"], 500)
stanza> println(length(mcus))
21
stanza> import json
stanza> println $ to-tuple $ to-hashset<String> $ for mcu in (mcus as Tuple<JObject>) seq-cat : mcu["bundles"] as Tuple<String>
["RCC_OSC32_OUT" "USART3_RTS" "I2S1_CK" "SPI1_SCK" "RCC_OSC_OUT" "USART4_RTS" "LPUART1_DE" "LPUART1_CTS" "SPI2_SCK" "USART5_RTS" "SPI3_SCK" "SPI4_SCK" "LPUART1_TX" "SPI5_SCK" "SYS_JTDO-SWO" "I2S5_SD" "LPUART1_RX" "I2S4_SD" "I2S3_SD" "I2C1_SDA" "I2S2_SD" "I2C2_SDA" "I2S1_SD" "I2C3_SDA" "SYS_SWCLK" "SYS_JTDO-TRACESWO" "SPI5_MISO" "SPI5_MOSI" "SPI4_MISO" "SPI4_MOSI" "USART1_CTS" "USART5_DE" "SPI3_MISO" "SPI3_MOSI" "USART2_CTS" "I2S5_WS" "LPUART1_RTS" "USART4_DE" "SPI2_MISO" "SPI2_MOSI" "USART3_CTS" "I2S4_WS" "USART3_DE" "USART6_TX" "SPI1_MISO" "SPI1_MOSI" "USART4_CTS" "RCC_OSC_IN" "I2S3_WS" "USART2_DE" "USART5_TX" "RCC_OSC32_IN" "I2S2_WS" "CAN_TX" "SPI1_NSS" "USART1_DE" "USART4_TX" "USART6_RX" "SYS_SWDIO" "I2C1_SCL" "I2S1_WS" "SPI2_NSS" "USART3_TX" "USART5_RX" "SYS_JTCK-SWCLK" "I2C2_SCL" "CAN_RX" "SPI3_NSS" "USART2_TX" "USART4_RX" "I2C3_SCL" "SPI4_NSS" "USART1_TX" "USART3_RX" "USART5_CK" "SPI5_NSS" "USART2_RX" "USART1_RX" "USART3_CK" "USART2_CK" "SYS_JTMS-SWDIO" "USART1_CK" "I2S5_CK" "I2S1_MCK" "I2S4_CK" "I2S2_MCK" "USART1_RTS" "I2S3_CK" "I2S3_MCK" "USART2_RTS" "I2S2_CK"]

Supported parameters

The supported special query parameters are:

  • _exist : List of attributes that the returned documents must contain.
  • _sort : The returned documents will be sort according to the list of attributes specified by this parameter, applied in the order they appear. Sorting in descending fashion can be obtained by starting a sorting attribute by a minus sign "−". This can take 2 additional value besides the list of existing properties: area is an alias for dimensions.area and cost is an alias for price.
  • _distinct : If this parameter exist, it must be an attribute string, the query will return the set of available values for the specified attribute in the list of documents that meet all the query constraints.

Regular filter properties:

  • We can filter on a part attribute : {"category": "resistor"}.
  • We can filter on a capacitance, resistance and inductance, those constraints are replaced by interval allowing for queries with a precision of 0.0005Ω, 0.01A and 0.01F respectively.
  • We can filter on a tolerance : {"tolerance": 0.05} will constrain the tolerance to be an exact match {"tolerance": {"min": -0.05, "max": 0.05}}. Returns 500 Bad Request if this is not a positive double
  • We can filter on a nested parameter using . : {"dimensions.x": 11}
  • We can filter on a list of values giving a list : {"case": ["Axial", "0402"]}
  • We can filter with an inequality prepending min- or max- : {"max−rated-power": 0.05}.
  • max-x, max-y and max-z are shorthands for max-dimensions.x, max-dimensions.y, max-dimensions.z
  • We interpret minimum_quantity as a floor on bulk purchase size; we automatically convert minimum_quantity to max-minimum_quantity.

Typo checker

The typo checker is triggered when an unsupported parameter is used in a query where the "category" parameter is present and amongst ["resistor", "capacitor", "inductor", "microcontroller"]. When the typo checker detects an unsupported parameter, it will throw an error printing the list of supported parameters of the category. Example:

$ jitx repl
stanza> import jitx/commands
stanza> println $ dbquery-all(["category" => "capacitor" "typo" => 1.0e-06])
The invalid attributes ("typo") are used in the query ["category" => "capacitor" "typo" => 1.0e-06].
Valid attributes for category capacitor must be amongst:
  - anode
  - capacitance
  - case
  - category
  - dimensions.area
  - dimensions.x
  - dimensions.y
  - dimensions.z
  - electrolyte
  - esr
  - esr_frequency
  - manufacturer
  - minimum_quantity
  - mounting
  - mpn
  - price
  - rated-current-pk
  - rated-current-rms
  - rated-temperature.max
  - rated-temperature.min
  - rated-voltage
  - rated-voltage-ac
  - stock
  - temperature-coefficient.change
  - temperature-coefficient.code
  - temperature-coefficient.lower-temperature
  - temperature-coefficient.raw_data
  - temperature-coefficient.tolerance
  - temperature-coefficient.upper-temperature
  - temperature-coefficient.value
  - tolerance
  - tolerance.max
  - tolerance.min
  - trust
  - type
  - update_date

Sourcing data

If the request contains the attributes _stock or/and _sellers: more advanced part sourcing data will be independently queried and integrated to the results, disregarding sellers that:

  • are not in the list
  • do not have an inventory level above the queried stock
  • do not have a pricing offering with a minimum quantity lower that the queried stock In this case, any part that does not have sourcing data that meets the criteria above will be ignored.

If _stock is 0 or _sellers is [], then no filtering out is done using those properties. In particular querying with both [_"stock" => 0, "_sellers" => []] will append the whole part sourcing data to the result for any sellers at any inventory stock and with any price offerings.

We recommend to always provide a list of allowed sellers as the part sourcing data contains unverified sellers that may be intermediaries.

A sellers key will be added to the returned json with the sourcing data meeting the request. The best price from each seller is aggregated in the resolved_price key in each seller data. The best price from all qualifying offerings is returned in the resolved_price key at the root of the json.

"sellers": [
    {
        "company_name": ...,
        "resolved_price": ...,
        "offers": [{
                "inventory_level": ...,
                "prices": [{"quantity": ..., "converted_price": ...}]
        },...]
    }
]
"resolved_price": ...

Sorting by price

cost and price can be used used interchangeably. We are using cost in what follows. If _sort is ["cost"] (respectively ["-cost"]), results will be sorted by increasing (respectively decreasing) price.

If neither _stock nor _sellers are parameters of the query, then the price used to sort on for resistors, capacitors and resistors is the price for 1 unit from Digikey (updated every week). For the microcontroller category, no sorting on price will occur, please see the next section.

If _stock or _sellers are parameters of the query, then real-time sourcing data is integrating in the query (see section "Sourcing data" above). At most 1000 parts meeting the query are retrieved from the JITX database, then sourcing data for each part is retrieved, the price used to sort on is the resolved_price attribute.