While we recommend managing Usage Groups on an ongoing basis via our official Terraform provider, we recognize that not all teams use Terraform or there may be use cases where you want to programmatically create Usage Groups as a one-off.
For example, imagine you want to create a Usage Group per department using a series of object tags you have stored in Snowflake. Alternatively, imagine you have a customer-facing product built on top of Snowflake and want to create a Usage Group for each customer.
The guide below shows how you could accomplish that using our official Usage Groups API.
Prerequisites
Step 1: Create an API Key
To interact with the SELECT API, you'll need to generate an API key and get your organization ID from the SELECT app. Follow the API quickstart instructions to get started.
Your API key must have the usage_groups:write
scope and access to the appropriate Snowflake account(s) or organization(s).
Exploring Filter Options
🎯 Before diving into the API, we strongly recommend exploring filter options through the SELECT UI or Terraform documentation:
Option 1: Use the SELECT UI (Recommended)
- Navigate to your Usage Groups page in the SELECT app
- Click "Create Usage Group" or edit an existing one
- Build your filter expression using the interactive filter builder
- Click the "Interactive" toggle and switch to "JSON" mode
- Copy the
filter_expression
field - this is exactly what you'll use in the API!
Option 2: Browse Terraform Examples
Visit our Terraform provider documentation for comprehensive filter examples and available dimensions.
Option 3: Check Available Dimensions
The available filter dimensions depend on whether your usage group set is scoped to an account or organization:
Account-Scoped Dimensions (most common):
warehouse_name
,user_name
,role_name
warehouse_tags
,user_tags
,role_tags
,database_tags
resource_type
,database_schema_name
- And many more...
Organization-Scoped Dimensions:
account_name
,region
,service_level
,usage_type
account_name_and_usage_type
,account_name_and_warehouse
Complete API Workflow
Step 1: Test Your API Credentials
import requests
import json
organization_id = "your_organization_id_here" # Get from SELECT app
api_key = "sl_your_api_key_here" # Generated from SELECT app
url = f"https://api.select.dev/api/{organization_id}/usage-group-sets"
headers = {"x-api-key": api_key}
# Test credentials by listing existing usage group sets
response = requests.get(url, headers=headers)
if response.status_code == 200:
print("✅ API credentials working!")
print("Existing usage group sets:", response.json())
else:
Step 2: Create a Usage Group Set (if needed)
# Create a usage group set scoped to a Snowflake account
usage_group_set_payload = {
"name": "Department Cost Allocation",
"order": 1,
"snowflake_account_uuid": "your_snowflake_account_uuid_here"
# OR use: "snowflake_organization_name": "your_org_name"
}
response = requests.post(url, headers=headers, json=usage_group_set_payload)
if response.status_code == 200:
usage_group_set = response.json()
usage_group_set_id = usage_group_set["id"]
print(f"✅ Created usage group set: {usage_group_set_id}")
else:
print(f"❌ Error creating usage group set: {response.text}")
Step 3: Design Your Usage Group Mappings
Create your mappings based on your business needs:
# Example 1: Department-based allocation using warehouse names
department_mappings = [
{
"name": "Finance Department",
"warehouse_names": ["FINANCE_WH", "FINANCE_ANALYTICS_WH"],
"budget": 5000,
"order": 1
},
{
"name": "Marketing Department",
"warehouse_names": ["MARKETING_WH", "CAMPAIGN_WH"],
"budget": 3000,
"order": 2
}
]
Step 4: Create Filter Expressions
💡 Pro Tip: Build your first filter in the SELECT UI, then copy the JSON structure!
def create_warehouse_filter(warehouse_names):
"""Create a filter for specific warehouse names"""
return {
"operator": "or",
"filters": [
{
"field": "warehouse_name",
"operator": "in",
"values": warehouse_names
}
]
}
def create_database_tag_filter(tag_key, tag_value):
"""Create a filter for database tags"""
Step 5: Create Usage Groups Programmatically
usage_groups_url = f"{url}/{usage_group_set_id}/usage-groups"
def create_usage_group(name, filter_expression, budget, order):
"""Helper function to create a usage group"""
payload = {
"name": name,
"budget": budget,
"order": order,
"usage_group_set_id": usage_group_set_id,
"filter_expression": filter_expression
}
response = requests.post(usage_groups_url, headers=headers, json=payload)
if response.status_code == 200:
Step 6: Managing Existing Usage Groups
Check for existing usage groups before creating new ones:
def get_existing_usage_groups():
"""Get all existing usage groups in the set"""
response = requests.get(usage_groups_url, headers=headers)
if response.status_code == 200:
return {group["name"]: group for group in response.json()}
return {}
def smart_create_usage_groups(mappings, filter_func):
"""Only create usage groups that don't already exist"""
existing = get_existing_usage_groups()
for mapping in mappings:
if mapping["name"] in existing:
print(f"⏭️ Usage group '{mapping['name']}' already exists, skipping")
continue
Real-World Examples
Example 1: Multi-Tenant SaaS Application
# Create usage groups for each customer tenant
def setup_customer_usage_groups(customers_data):
"""
customers_data: List of dicts with customer info from your database
Example: [{"name": "Acme Corp", "schema_prefix": "acme_", "budget": 2000}]
"""
for customer in customers_data:
filter_expr = {
"operator": "or",
"filters": [
{
"field": "database_schema_name",
"operator": "like",
"values": [f"%{customer['schema_prefix']}%"]
}
Example 2: Environment-Based Cost Tracking
environments = [
{"name": "Production", "pattern": "%_prod_%", "budget": 10000, "order": 1},
{"name": "Staging", "pattern": "%_staging_%", "budget": 3000, "order": 2},
{"name": "Development", "pattern": "%_dev_%", "budget": 2000, "order": 3}
]
for env in environments:
filter_expr = {
"operator": "or",
"filters": [
{
"field": "warehouse_name",
"operator": "like",
"values": [env["pattern"]]
}
Filter Discovery Tips
🔍 Finding the Right Filter Dimensions
- Start with the UI: The interactive filter builder shows all available dimensions for your specific setup
- Use Terraform docs: Browse real-world examples at registry.terraform.io/providers/get-select/select
- Check your data: Look at your Snowflake
INFORMATION_SCHEMA
to understand your warehouse names, user patterns, etc. - Test incrementally: Start with simple filters and add complexity as needed
🎛️ Common Filter Patterns
# Pattern 1: Exact matches
{"field": "warehouse_name", "operator": "in", "values": ["WH1", "WH2"]}
# Pattern 2: Pattern matching
{"field": "user_name", "operator": "like", "values": ["analytics_%", "%_admin"]}
# Pattern 3: Tag-based filtering
{"field": "warehouse_tags", "operator": "array_contains", "values": ["team: analytics"]}
# Pattern 4: Multiple criteria (AND)
{
"operator": "and",
"filters": [
{"field": "warehouse_name", "operator": "in", "values": ["PROD_WH"]},
{"field": "user_name", "operator": "like", "values": ["prod_%"]}
Best Practices
- 🎯 Start Simple: Begin with basic warehouse or user-based filters before adding complexity
- 🧪 Test in UI First: Always prototype your filters in the SELECT interface before coding
- 📖 Use Terraform Docs: Reference our provider docs for proven filter patterns
- 🔄 Handle Existing Data: Check for existing usage groups to avoid duplicates
- 📊 Monitor Results: Use the SELECT dashboard to verify your usage groups are working as expected
- ⚡ Order Matters: Lower order values take precedence when filter expressions overlap
Troubleshooting
❌ "Filter expression validation failed"
- Copy a working filter from the UI and modify it incrementally
- Check that field names match available dimensions for your scope (account vs organization)
❌ "Usage group name already exists"
- Use the "get existing usage groups" pattern above to check before creating
❌ "API key doesn't have access"
- Verify your API key has
usage_groups:write
scope - Ensure the key has access to the specific Snowflake account/organization
- Organization access grants access to all accounts as well
For more complex scenarios, consider using our Terraform provider which provides a more robust way to manage usage groups as infrastructure-as-code.