Skip to main content

Partner Back-Office: User Management

Running a complex energy optimization over large device fleets requires good tooling. Our utility back-office web app is designed to help Partners manage the connected fleet of their end-users’ devices, provide customer support, and coordinate within their team. End-user-related actions such as modifying users and devices individually or in bulk can be done via dedicated endpoints.
Administrative functions like Partner user account management are largely done via the Podero utility back-office web app.

List All Users

Get a dashboard overview of all users in your organization:
curl -X GET \
  'https://app.podero.com/api/partners/v2.0/org/{org_id}/users' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {auth_token}'
Implement filtering on your end to find specific users:
def filter_users(users, role=None, search_term=None):
    """
    Filter users by role or search term
    """
    filtered = users

    if role:
        filtered = [u for u in filtered if u['role'] == role]

    if search_term:
        term = search_term.lower()
        filtered = [
            u for u in filtered
            if term in u['email'].lower()
            or term in u.get('first_name', '').lower()
            or term in u.get('last_name', '').lower()
            or term in u.get('external_user_id', '').lower()
        ]

    return filtered

# Example usage
all_users = get_all_users(org_id)
end_users = filter_users(all_users, role='user')
search_results = filter_users(all_users, search_term='john')

Create New User

Add a new end-user to your organization:
curl -X POST \
  'https://app.podero.com/api/partners/v2.0/org/{org_id}/users' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {auth_token}' \
  -d '{
    "role": "user",
    "email": "[email protected]",
    "external_user_id": "customer_12345",
    "first_name": "John",
    "last_name": "Doe"
  }'
Use the external_user_id field to link Podero users with your internal customer IDs.

Update User Data

Modify existing user information:
curl -X PUT \
  'https://app.podero.com/api/partners/v2.0/org/{org_id}/users/{user_id}' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer {auth_token}' \
  -d '{
    "first_name": "Peter",
    "last_name": "Schmidt",
    "street_and_number": "Main Street 123",
    "zip_code": "10115",
    "town": "Berlin",
    "country_iso2": "DE"
  }'

Bulk Operations

Update Multiple Users

Process multiple user updates efficiently:
def bulk_update_users(org_id, auth_token, updates):
    """
    Update multiple users with different data

    Args:
        updates: List of dicts with 'user_id' and update fields
    """
    results = []

    for update in updates:
        user_id = update.pop('user_id')
        try:
            response = requests.put(
                f'https://app.podero.com/api/partners/v2.0/org/{org_id}/users/{user_id}',
                headers={
                    'Authorization': f'Bearer {auth_token}',
                    'Content-Type': 'application/json'
                },
                json=update
            )
            results.append({
                'user_id': user_id,
                'status': 'success',
                'data': response.json()
            })
        except Exception as e:
            results.append({
                'user_id': user_id,
                'status': 'error',
                'error': str(e)
            })

    return results

# Example usage
updates = [
    {'user_id': 'user-1', 'external_user_id': 'cust_001'},
    {'user_id': 'user-2', 'external_user_id': 'cust_002'},
    {'user_id': 'user-3', 'external_user_id': 'cust_003'}
]

results = bulk_update_users(org_id, auth_token, updates)

Get User Details

Retrieve complete information for a specific user:
curl -X GET \
  'https://app.podero.com/api/partners/v2.0/org/{org_id}/users/{user_id}' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {auth_token}'

Get User’s Devices

Retrieve all devices associated with a user:
def get_user_devices(org_id, user_id, auth_token):
    """
    Get all devices for a user across all types
    """
    base_url = f'https://app.podero.com/api/partners/v2.0/org/{org_id}/users/{user_id}'
    headers = {
        'accept': 'application/json',
        'Authorization': f'Bearer {auth_token}'
    }

    devices = {
        'heat_pumps': requests.get(f'{base_url}/heat-pumps', headers=headers).json(),
        'electric_vehicles': requests.get(f'{base_url}/electric-vehicles', headers=headers).json(),
        'inverters': requests.get(f'{base_url}/inverters', headers=headers).json()
    }

    total_devices = sum(len(v) for v in devices.values())

    return {
        'total': total_devices,
        'devices': devices
    }

# Example usage
user_devices = get_user_devices(org_id, user_id, auth_token)
print(f"Total devices: {user_devices['total']}")
print(f"Heat pumps: {len(user_devices['devices']['heat_pumps'])}")

Customer Support Workflows

Troubleshoot Device Connection

Check device authentication status and provide reconnection URL:
def troubleshoot_device_connection(device):
    """
    Check device connection and provide resolution steps
    """
    if not device['is_authenticated']:
        if device.get('authorization_url'):
            return {
                'issue': 'Device requires re-authentication',
                'resolution': 'User needs to reconnect device',
                'action_url': device['authorization_url'],
                'instructions': 'Send the authorization_url to the user to reconnect their device'
            }
        else:
            return {
                'issue': 'Device not authenticated',
                'resolution': 'Device may need to be re-added',
                'action': 'Consider creating a new device onboarding session'
            }

    # Check data freshness
    last_update = datetime.fromisoformat(device['current_state_last_updated_at'])
    hours_since_update = (datetime.now() - last_update).total_seconds() / 3600

    if hours_since_update > 2:
        return {
            'issue': 'Data appears stale',
            'last_update': last_update.isoformat(),
            'resolution': 'Monitor for updates or contact manufacturer API support'
        }

    return {'status': 'healthy'}

Reset Device Optimization

Help users who want to restart optimization:
def reset_device_optimization(org_id, user_id, device_id, device_type, auth_token):
    """
    Reset device to default optimization settings
    """
    endpoint = f'https://app.podero.com/api/partners/v2.0/org/{org_id}/users/{user_id}/{device_type}/{device_id}'

    reset_settings = {
        'is_smart_optimization_active': True,
        'pause_power_until': None
    }

    response = requests.put(
        endpoint,
        headers={
            'Authorization': f'Bearer {auth_token}',
            'Content-Type': 'application/json'
        },
        json=reset_settings
    )

    return response.json()

User Analytics

Generate User Summary Report

def generate_user_summary(org_id, user_id, auth_token):
    """
    Generate comprehensive user summary for support or reporting
    """
    # Get user info
    user = get_user(org_id, user_id, auth_token)

    # Get all devices
    devices = get_user_devices(org_id, user_id, auth_token)

    # Get buildings
    buildings = get_user_buildings(org_id, user_id, auth_token)

    # Calculate totals
    total_consumption_day = 0
    total_consumption_month = 0
    devices_optimized = 0

    for device_type in devices['devices'].values():
        for device in device_type:
            total_consumption_day += device.get('consumption_last_day_kwh', 0)
            total_consumption_month += device.get('consumption_last_month_kwh', 0)
            if device.get('is_smart_optimization_active'):
                devices_optimized += 1

    return {
        'user': {
            'id': user['id'],
            'email': user['email'],
            'name': f"{user.get('first_name', '')} {user.get('last_name', '')}".strip(),
            'external_id': user.get('external_user_id'),
            'location': f"{user.get('town', '')}, {user.get('country_iso2', '')}".strip(', ')
        },
        'devices': {
            'total': devices['total'],
            'optimized': devices_optimized,
            'by_type': {
                'heat_pumps': len(devices['devices']['heat_pumps']),
                'electric_vehicles': len(devices['devices']['electric_vehicles']),
                'inverters': len(devices['devices']['inverters'])
            }
        },
        'buildings': len(buildings),
        'consumption': {
            'today': round(total_consumption_day, 2),
            'this_month': round(total_consumption_month, 2)
        }
    }

Best Practices

  • Regularly sync external_user_id with your internal systems
  • Maintain up-to-date contact information for support
  • Use consistent location data for accurate optimization
  • Archive or flag inactive users appropriately
  • Create support tickets linked to user_id
  • Log all API operations for audit trails
  • Implement alerts for device disconnections
  • Provide self-service reconnection options
  • Implement rate limiting and retries
  • Process updates in batches to avoid timeouts
  • Log both successes and failures
  • Provide progress indicators for long operations
  • Restrict user management to authorized staff only
  • Log all user data modifications
  • Implement role-based access control
  • Never expose user credentials or sensitive data

Common Support Scenarios

Steps:
  1. Check is_authenticated status
  2. Look for authorization_url in response
  3. Send reconnection URL to user
  4. Verify connection after user completes flow

Next Steps