API Documentation

Share Rules API

Configure cost sharing rules and split methods. Define how expenses are distributed across units and tenants based on various criteria.

Share Rules

Share Rules define how utility costs are allocated to tenants within a property.

  • GET /v1/properties/:propertyId/sharerules: List all share rules for a property.
  • POST /v1/properties/:propertyId/sharerules: Create a new share rule for a property.
    Request Body
    {
      "utilityType": "string (required, one of: 'ELECTRICITY', 'WATER', 'GAS', 'INTERNET', 'SEWER', 'GARBAGE', 'OTHER')",
      "splitMethod": "string (required, one of: 'EQUAL', 'SQFT', 'OCCUPANTS', 'BEDROOMS', 'PERCENTAGE', 'CUSTOM')",
      "isActive": "boolean (optional, defaults to true)",
      "customWeightsJson": "string (optional, JSON string for custom weights like '{\"Unit A\": 0.3, \"Unit B\": 0.7}')"
    }
  • PATCH /v1/sharerules/:ruleId: Update an existing share rule.
    Request Body
    {
      "splitMethod": "string (optional, one of: 'EQUAL', 'SQFT', 'OCCUPANTS', 'BEDROOMS', 'PERCENTAGE', 'CUSTOM')",
      "isActive": "boolean (optional)",
      "customWeightsJson": "string (optional, JSON string for custom weights)"
    }
  • DELETE /v1/sharerules/:ruleId: Delete a share rule (returns 204 No Content on success).

Note: Each property can have only one active rule per utility type. Creating a rule for an existing utility type will replace the previous rule. Rule changes automatically trigger recalculation of charges for affected months.

Code Examples

Share Rules Management

Comprehensive examples for managing share rules: creating, updating, and deleting allocation rules for different utility types.

import requests
import os
import json

# --- Configuration ---
BASE_URL = "https://app.billgauge.com/api/v1"
API_KEY = os.environ.get("BILLGAUGE_API_KEY", "your_api_key_here")
PROPERTY_ID = "prop_example_123456"  # Replace with a real property ID

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

def get_share_rules(property_id):
    """Get all share rules for a property."""
    print(f"Getting share rules for property {property_id}...")
    response = requests.get(f"{BASE_URL}/properties/{property_id}/sharerules", headers=HEADERS)
    
    if response.status_code == 200:
        rules = response.json()
        print(f"Found {len(rules)} share rules:")
        for rule in rules:
            print(f"  - {rule['utilityType']}: {rule['splitMethod']} ({'Active' if rule['isActive'] else 'Inactive'})")
        return rules
    else:
        print(f"Error: {response.status_code} - {response.text}")
        return None

def create_share_rule(property_id, utility_type, split_method, is_active=True, custom_weights=None):
    """Create a new share rule for a property."""
    print(f"Creating '{utility_type}' rule with '{split_method}' method...")
    
    rule_data = {
        "utilityType": utility_type,  # 'ELECTRICITY', 'WATER', 'GAS', 'INTERNET', 'SEWER', 'GARBAGE', 'OTHER'
        "splitMethod": split_method,  # 'EQUAL', 'SQFT', 'OCCUPANTS', 'BEDROOMS', 'PERCENTAGE', 'CUSTOM'
        "isActive": is_active
    }
    
    if custom_weights:
        rule_data["customWeightsJson"] = json.dumps(custom_weights)
    
    response = requests.post(f"{BASE_URL}/properties/{property_id}/sharerules", headers=HEADERS, json=rule_data)
    
    if response.status_code == 201:
        rule = response.json()
        print(f"Successfully created rule with ID: {rule['id']}")
        return rule
    else:
        print(f"Error: {response.status_code} - {response.text}")
        return None

def update_share_rule(rule_id, split_method=None, is_active=None, custom_weights=None):
    """Update an existing share rule."""
    print(f"Updating rule {rule_id}...")
    
    update_data = {}
    if split_method:
        update_data["splitMethod"] = split_method
    if is_active is not None:
        update_data["isActive"] = is_active
    if custom_weights:
        update_data["customWeightsJson"] = json.dumps(custom_weights)
    
    response = requests.patch(f"{BASE_URL}/sharerules/{rule_id}", headers=HEADERS, json=update_data)
    
    if response.status_code == 200:
        rule = response.json()
        print("Successfully updated rule")
        return rule
    else:
        print(f"Error: {response.status_code} - {response.text}")
        return None

def delete_share_rule(rule_id):
    """Delete a share rule."""
    print(f"Deleting rule {rule_id}...")
    
    response = requests.delete(f"{BASE_URL}/sharerules/{rule_id}", headers=HEADERS)
    
    if response.status_code == 204:
        print("Successfully deleted rule")
        return True
    else:
        print(f"Error: {response.status_code} - {response.text}")
        return False

if __name__ == "__main__":
    # Example 1: Get all rules
    current_rules = get_share_rules(PROPERTY_ID)
    
    # Example 2: Create a new rule with equal split
    new_rule = create_share_rule(PROPERTY_ID, "WATER", "EQUAL")
    
    # Example 3: Create a rule with custom weights
    custom_weights = {"Unit A": 0.4, "Unit B": 0.6}
    custom_rule = create_share_rule(PROPERTY_ID, "ELECTRICITY", "CUSTOM", custom_weights=custom_weights)
    
    # Example 4: Update a rule to use square footage
    if new_rule:
        updated_rule = update_share_rule(new_rule['id'], split_method="SQFT")
    
    # Example 5: Deactivate a rule
    if custom_rule:
        deactivated_rule = update_share_rule(custom_rule['id'], is_active=False)