Working with the Usage Groups API

A full guide to programmatically creating and managing Usage Groups in Snowflake using the SELECT Usage Groups API, with examples, best practices, and troubleshooting tips.

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:

  1. Navigate to your Usage Groups page in the SELECT app
  2. Click "Create Usage Group" or edit an existing one
  3. Build your filter expression using the interactive filter builder
  4. Click the "Interactive" toggle and switch to "JSON" mode
  5. 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_nameuser_namerole_name
  • warehouse_tagsuser_tagsrole_tagsdatabase_tags
  • resource_typedatabase_schema_name
  • And many more...

Organization-Scoped Dimensions:

  • account_nameregionservice_levelusage_type
  • account_name_and_usage_typeaccount_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

  1. Start with the UI: The interactive filter builder shows all available dimensions for your specific setup
  2. Use Terraform docs: Browse real-world examples at registry.terraform.io/providers/get-select/select
  3. Check your data: Look at your Snowflake INFORMATION_SCHEMA to understand your warehouse names, user patterns, etc.
  4. 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

  1. 🎯 Start Simple: Begin with basic warehouse or user-based filters before adding complexity
  2. 🧪 Test in UI First: Always prototype your filters in the SELECT interface before coding
  3. 📖 Use Terraform Docs: Reference our provider docs for proven filter patterns
  4. 🔄 Handle Existing Data: Check for existing usage groups to avoid duplicates
  5. 📊 Monitor Results: Use the SELECT dashboard to verify your usage groups are working as expected
  6. ⚡ 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.