API

Filtering and Querying

Master the filter syntax to efficiently query models, predictions, simulations, and other resources in Alviss AI.

This tutorial covers the filter query syntax used across all list endpoints in the Alviss AI API. Filters allow you to narrow down results, search by specific criteria, and sort data. We'll cover the syntax, available operators, and provide practical examples.

Filter Syntax Overview

Filters are passed as JSON strings in the filters query parameter. The basic structure is:

{"field": [["operator", "value"]]}

For multiple conditions on the same field (AND logic):

{"field": [["operator1", "value1"], ["operator2", "value2"]]}

For multiple filters (OR logic between filters):

filters={"field1": [["=", "A"]]}&filters={"field2": [["=", "B"]]}

Available Operators

OperatorDescriptionExample
=Equals{"Status": [["=", "COMPLETED"]]}
!=Not equals{"Status": [["!=", "FAILED"]]}
>Greater than{"CreatedDate": [[">", "2024-01-01"]]}
>=Greater than or equal{"IId": [[">=", "100"]]}
<Less than{"CreatedDate": [["<", "2024-12-31"]]}
<=Less than or equal{"IId": [["<=", "50"]]}
containsString contains (case-sensitive){"Name": [["contains", "Q4"]]}
startswithString starts with{"Name": [["startswith", "US_"]]}
endswithString ends with{"Name": [["endswith", "_2024"]]}
ilikeCase-insensitive like with wildcards{"Name": [["ilike", "%marketing%"]]}
likeCase-sensitive like with wildcards{"Name": [["like", "Model_%"]]}
inValue in list{"Country": [["in", "[\"US\", \"UK\", \"DE\"]"]]}
notinValue not in list{"Status": [["notin", "[\"FAILED\", \"PENDING\"]"]]}
isIs null/true/false{"Note": [["is", "NULL"]]}
isnotIs not null/true/false{"Note": [["isnot", "NULL"]]}
orderbySort results{"CreatedDate": [["orderby", "desc"]]}

Nested Field Access

Access fields on related objects using dot notation:

# Filter models by their dataset name
filters = '{"DataSet.Name": [["contains", "Marketing"]]}'

# Filter simulations by the model they use
filters = '{"Model.Name": [["=", "US_Q4_Model"]]}'

# Deep nesting: filter datasets by simulations that used their models
filters = '{"Models.SimulationJobs.Name": [["contains", "Scenario"]]}'

Python Examples

Setup

import requests
import json

url = "https://app.alviss.io/api/v1/api"
token = "<your_token>"
team_id = "<team_id>"
project_id = "<project_id>"

headers = {"Authorization": f"Bearer {token}"}
base_url = f"{url}/projects/{team_id}/{project_id}"

Example 1: Find Completed Models for a Specific Country

# Find all completed models for the US market
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={
        "filters": '{"Status": [["=", "COMPLETED"]], "Country": [["=", "US"]]}'
    }
)
models = response.json()["items"]

Example 2: Find Recent Predictions Within a Date Range

# Find predictions created in Q4 2024
response = requests.get(
    f"{base_url}/predictions",
    headers=headers,
    params={
        "filters": json.dumps({
            "Date": [
                [">=", "2024-10-01T00:00:00"],
                ["<=", "2024-12-31T23:59:59"]
            ]
        })
    }
)
predictions = response.json()["items"]

Example 3: Search by Name Pattern

# Find models whose name contains "Marketing" (case-insensitive)
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={
        "filters": '{"Name": [["ilike", "%marketing%"]]}'
    }
)
# Find simulations that used a specific model
response = requests.get(
    f"{base_url}/simulations",
    headers=headers,
    params={
        "filters": '{"Model.IId": [["=", "42"]]}'
    }
)

# Find predictions using models trained on a specific dataset
response = requests.get(
    f"{base_url}/predictions",
    headers=headers,
    params={
        "filters": '{"Model.DataSet.Name": [["contains", "2024"]]}'
    }
)

Example 5: Using IN Operator for Multiple Values

# Find models for multiple countries
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={
        "filters": json.dumps({
            "Country": [["in", '["US", "UK", "DE", "FR"]']]
        })
    }
)

Example 6: Exclude Certain Values

# Find all simulations except failed ones
response = requests.get(
    f"{base_url}/simulations",
    headers=headers,
    params={
        "filters": '{"Status": [["notin", "[\\"FAILED\\", \\"PENDING\\"]"]]}'
    }
)

Example 7: Sorting Results

# Get models sorted by creation date (newest first)
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={
        "filters": '{"CreatedDate": [["orderby", "desc"]]}'
    }
)

# Sort by name alphabetically
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={
        "filters": '{"Name": [["orderby", "asc"]]}'
    }
)

Example 8: Combining Multiple Conditions (AND)

# Find completed US models created after a specific date
filters = json.dumps({
    "Status": [["=", "COMPLETED"]],
    "Country": [["=", "US"]],
    "CreatedDate": [[">=", "2024-06-01"]]
})

response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={"filters": filters}
)

Example 9: OR Logic with Multiple Filter Parameters

# Find models that are either from US OR have "Global" in the name
# Pass multiple filters parameters for OR logic
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params=[
        ("filters", '{"Country": [["=", "US"]]}'),
        ("filters", '{"Name": [["contains", "Global"]]}')
    ]
)

Example 10: Check for Null Values

# Find models without a note
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={
        "filters": '{"Note": [["is", "NULL"]]}'
    }
)

# Find models that have a note
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={
        "filters": '{"Note": [["isnot", "NULL"]]}'
    }
)

Result Filters for Data Downloads

When downloading data (predictions, simulations, attributions), use result_filters to filter the actual data rows:

# Download prediction results for a specific country and variable
response = requests.get(
    f"{base_url}/predictions/{prediction_id}/data",
    headers=headers,
    params={
        "result_filters": json.dumps({
            "Country": [["=", "US"]],
            "Variable": [["contains", "sales"]]
        })
    }
)

Common Filterable Fields by Endpoint

Models (/models)

  • IId, Name, Note, Status, Country, Region, Grouping
  • CreatedDate, Selected, DataSet.Name, DataSet.IId

Predictions (/predictions)

  • IId, Name, Note, Status, Date, StartDate, EndDate
  • Model.Name, Model.IId, DataSet.Name

Simulations (/simulations)

  • IId, Name, Note, Status, Date
  • ScenarioStartDate, ScenarioEndDate
  • Model.Name, Model.IId, DataSet.Name

Optimizations (/optimizations)

  • IId, Name, Note, Status, Date
  • Model.Name, Model.IId, TargetResult, Improvement

Attribution Sets (/attributionset)

  • IId, Name, Note, Status, Selected, CreatedDate
  • DataSet.Name, Attributions.Name

Advanced: Combining Filters with Ordering

You can combine filtering and ordering in a single request. The UI uses this pattern extensively:

# Filter for completed US models AND sort by creation date (newest first)
# Note: ordering is a separate filter object to achieve AND logic
filters_list = [
    # First filter: the actual conditions (merged into AND)
    json.dumps({
        "Status": [["=", "COMPLETED"]],
        "Country": [["=", "US"]]
    }),
    # Second filter: the ordering
    json.dumps({
        "CreatedDate": [["orderby", "desc"]]
    })
]

response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params=[("filters", f) for f in filters_list]
)

Advanced: Filtering by Modelling Combination

A common pattern is filtering by market segments (Country/Region/Grouping):

# Filter for models in multiple countries
def build_modelling_combination_filter(
    countries: list[str] = None,
    regions: list[str] = None,
    groupings: list[str] = None,
    prefix: str = ""  # Use "Model." when filtering via related objects
) -> dict:
    """Build a filter dict for modelling combinations."""
    filters = {}
    if countries:
        key = f"{prefix}Country" if prefix else "Country"
        filters[key] = [["in", json.dumps(countries)]]
    if regions:
        key = f"{prefix}Region" if prefix else "Region"
        filters[key] = [["in", json.dumps(regions)]]
    if groupings:
        key = f"{prefix}Grouping" if prefix else "Grouping"
        filters[key] = [["in", json.dumps(groupings)]]
    return filters

# Example: Find models for US and UK markets
filter_dict = build_modelling_combination_filter(
    countries=["US", "UK"],
    regions=["all"],
    groupings=["retail", "wholesale"]
)

response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={"filters": json.dumps(filter_dict)}
)

Advanced: Similarity Search for Names

The API supports fuzzy/similarity search for finding items by name:

# Find models with names similar to "Marketing" (fuzzy search)
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={
        "filters": '{"Name": [["similarity", "Marketing"]]}'
    }
)

Advanced: Dataset-Specific Data Filtering

When querying data from datasets (Sales, Media, Events, etc.), you can filter by data-specific columns with table prefixes:

# Filter dataset data by product and media attributes
# Note: Use "TableName.Column" format for data-level filtering
filters = json.dumps({
    "Sales.Product": [["=", "Health"]],
    "Sales.Metric": [["in", '["UnitsSold", "Revenue"]']],
    "Country": [["=", "US"]]
})

response = requests.get(
    f"{base_url}/datasets/{dataset_id}/data",
    headers=headers,
    params={"filters": filters}
)

Advanced: Building Complex AND/OR Queries

def build_complex_filter(
    and_conditions: dict,
    or_conditions: list[dict] = None
) -> list[str]:
    """
    Build complex filters combining AND and OR logic.

    - and_conditions: All conditions that must be true
    - or_conditions: List of condition dicts where ANY can be true

    Returns list of filter strings to pass as multiple 'filters' params.
    """
    filters = []

    # AND conditions go in a single filter
    if and_conditions:
        filters.append(json.dumps(and_conditions))

    # OR conditions are separate filters
    if or_conditions:
        for cond in or_conditions:
            filters.append(json.dumps(cond))

    return filters

# Example: Find (COMPLETED OR RUNNING) AND (US OR UK) models
# This finds: COMPLETED US, COMPLETED UK, RUNNING US, RUNNING UK
and_conds = {
    "Country": [["in", '["US", "UK"]']]
}
or_conds = [
    {"Status": [["=", "COMPLETED"]]},
    {"Status": [["=", "RUNNING"]]}
]

filter_strings = build_complex_filter(and_conds, or_conds)
response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params=[("filters", f) for f in filter_strings]
)

Tips and Best Practices

  1. URL Encoding: When using filters in URLs, ensure proper URL encoding of special characters
  2. JSON Escaping: When nesting JSON (like in the in operator), escape inner quotes
  3. Date Format: Use ISO 8601 format for dates: 2024-01-15T10:30:00
  4. Performance: Filter on indexed fields (IId, Status) when possible
  5. Pagination: Filters work with pagination - use page and size parameters alongside filters
  6. Combine ordering with filtering: Use separate filter objects for sorting to ensure proper AND behavior
  7. Use similarity for fuzzy search: The similarity operator is great for user-facing search features
  8. Prefix nested fields: When filtering through relationships, use dot notation like Model.DataSet.Name

Full Example: Find and Process Matching Models

import requests
import json

url = "https://app.alviss.io/api/v1/api"
token = "<your_token>"
team_id = "<team_id>"
project_id = "<project_id>"

headers = {"Authorization": f"Bearer {token}"}
base_url = f"{url}/projects/{team_id}/{project_id}"

# Find all completed US models from Q4 2024
filters = json.dumps({
    "Status": [["=", "COMPLETED"]],
    "Country": [["=", "US"]],
    "CreatedDate": [
        [">=", "2024-10-01"],
        ["<=", "2024-12-31"]
    ]
})

response = requests.get(
    f"{base_url}/models",
    headers=headers,
    params={
        "filters": filters,
        "size": 50  # page size
    }
)

result = response.json()
models = result["items"]
total = result["total"]

print(f"Found {total} matching models")
for model in models:
    print(f"  - {model['Name']} (IId: {model['IId']}, Created: {model['CreatedDate']})")

# If there are more pages, iterate
page = 2
while len(models) < total:
    response = requests.get(
        f"{base_url}/models",
        headers=headers,
        params={
            "filters": filters,
            "size": 50,
            "page": page
        }
    )
    models.extend(response.json()["items"])
    page += 1