Skip to main content
The screener is the cross-country analogue of an equity stock screener. Instead of filtering tickers by fundamentals, you filter countries by the latest values of canonical macro indicators: “show me countries with CPI inflation above 3% and unemployment below 5%.” Conduit evaluates the latest public reading of each indicator per country and returns the countries that satisfy every clause.
The screener screens public indicator values only. It reads the latest public observation per canonical indicator and applies your filters to those numbers. It never exposes any internal scoring, and it never touches licensed or internal_only data.

How it works

The HTTP API is read-only and GET-only, so filters arrive as a single compact query parameter, the filter DSL. Each clause is field:operator:value, clauses are comma-separated, and they are AND-ed together. A country qualifies only when every clause matches one of its indicators and that indicator’s latest value satisfies the operator.
filter=cpi_inflation_yoy:gt:3,unemployment_rate:lt:5
This reads as: CPI inflation greater than 3 and unemployment rate less than 5.

The filter DSL

Anatomy of a clause

A clause has three colon-separated parts:
PartExampleNotes
fieldcpi_inflation_yoyA canonical indicator slug. Discover the full list at /v1/public/screener/filters.
operatorgtOne of the operators below.
value3A number. The in operator takes pipe-separated numbers.

Operators

OperatorMeaningExample
gtGreater thancpi_inflation_yoy:gt:3
ltLess thanunemployment_rate:lt:5
gteGreater than or equalpolicy_rate:gte:4
lteLess than or equalgdp_growth_yoy:lte:1
eqEqualpolicy_rate:eq:0
inValue is in a pipe-separated set`policy_rate:in:00.250.5`
The in operator is the only one that takes more than one value. Separate its values with the pipe character |:
filter=policy_rate:in:0|0.25|0.5

AND semantics

Clauses are joined with commas and every clause must hold. There is no OR; build the union you want client-side by issuing separate requests. A country with no reading for a clause’s field, or a null latest value, does not satisfy that clause and is dropped.
# Inflation above 3 AND unemployment below 5 AND policy rate at or above 4
filter=cpi_inflation_yoy:gt:3,unemployment_rate:lt:5,policy_rate:gte:4

Discovering fields

Field names are canonical indicator slugs. The authoritative list, with the operators, the syntax reminder, and an example, lives at GET /v1/public/screener/filters.
curl -s "https://data.quantoraresearch.com/v1/public/screener/filters" \
  -H "x-api-key: $CONDUIT_API_KEY"
The response:
{
  "data": {
    "operators": ["gt", "lt", "gte", "lte", "eq", "in"],
    "syntax": "filter=field:operator:value,field:operator:value (clauses are AND-ed; the 'in' operator takes pipe-separated values)",
    "example": "filter=cpi_inflation_yoy:gt:3,unemployment_rate:lt:5",
    "fields": [
      {
        "field": "cpi_inflation_yoy",
        "indicatorId": "indicator_cpi_inflation_yoy",
        "name": "CPI inflation, year over year",
        "category": "inflation",
        "unit": "percent"
      }
    ]
  }
}
Field matching is forgiving: it accepts the canonical slug, the indicator_-prefixed id, and registered aliases for the same indicator. When in doubt, use the field value exactly as returned by /v1/public/screener/filters.

Running a screen

Send your clauses as the filter parameter to GET /v1/public/screener. The filter parameter is required.
curl -s "https://data.quantoraresearch.com/v1/public/screener?filter=cpi_inflation_yoy:gt:3,unemployment_rate:lt:5" \
  -H "x-api-key: $CONDUIT_API_KEY"

The response

Each result is a country that satisfied every clause, with the matched indicator values inlined so you can see what it scored on without a second call.
{
  "data": [
    {
      "entity": "USA",
      "country": "USA",
      "name": "United States",
      "values": [
        {
          "field": "cpi_inflation_yoy",
          "indicatorId": "cpi_inflation_yoy",
          "indicatorName": "CPI inflation, year over year",
          "value": 3.1,
          "unit": "percent",
          "periodEnd": "2026-05-31",
          "observedAt": "2026-05-31"
        },
        {
          "field": "unemployment_rate",
          "indicatorId": "unemployment_rate",
          "indicatorName": "Unemployment rate",
          "value": 4.2,
          "unit": "percent",
          "periodEnd": "2026-05-31",
          "observedAt": "2026-05-31"
        }
      ]
    }
  ],
  "meta": { "api_version": "v1" },
  "requestId": "0c4f..."
}
entity
string
The matched entity key (the country ISO code).
country
string
ISO alpha-3 country code.
name
string
Country display name.
values
object[]
One entry per clause, showing the indicator value that satisfied it.

Optional parameters

Besides the required filter, the screener accepts three optional parameters.
ParamValuesDescription
countryISO codeRestrict the screen to a single country (useful as a yes/no test).
freshnessfreshOnly consider readings that pass the freshness gate, so stale prints cannot qualify a country.
limit1 to 500, default 100Cap the number of returned countries.
# Same screen, but only over fresh readings, limited to 20 countries
curl -s "https://data.quantoraresearch.com/v1/public/screener?filter=cpi_inflation_yoy:gt:3,unemployment_rate:lt:5&freshness=fresh&limit=20" \
  -H "x-api-key: $CONDUIT_API_KEY"
freshness=fresh is recommended for live decision-making. Without it, a country can qualify on an old print that is past its publication cadence. With it, those stale readings are excluded before filtering.

More examples

# Inflation above target and a tight policy stance
curl -s "https://data.quantoraresearch.com/v1/public/screener?filter=cpi_inflation_yoy:gt:2,policy_rate:gte:4&freshness=fresh" \
  -H "x-api-key: $CONDUIT_API_KEY"

Errors

The screener fails closed and returns a stable error code on bad input.
SituationCodeStatus
filter is missingbad_request400
A clause is malformed (not field:operator:value)bad_request400
An unknown operatorbad_request400
A non-numeric value (or empty in set)bad_request400
limit out of the 1 to 500 rangebad_request400
An unknown query parameterbad_request400
The error message names the offending clause so you can fix it quickly. The @conduit/client SDK throws a ConduitError carrying the code, HTTP status, and requestId:
import { ConduitError } from "@conduit/client";

try {
  await conduit.screen("cpi_inflation_yoy:gt:notanumber");
} catch (error) {
  if (error instanceof ConduitError) {
    console.error(error.code, error.status, error.message);
  }
}

Next steps

Discover fields

The catalog guide covers the full indicator list the screener fields come from.

Pull the values

Once a screen narrows your set, fetch the full point-in-time series with the observations API.