Skip to main content

myhamilton311

A Python library for the MyHamilton 311 app API — the City of Hamilton, Ohio's citizen service request platform, backed by SeeClickFix.

Reverse-engineered from mitmproxy captures of the MyHamilton 311 iOS app (build 3884).


Installation

pip install requests          # only runtime dependency
# or, from this repo:
pip install -e .

Quick Start

Unauthenticated — browse public issues

from myhamilton311 import MyHamilton311Client

client = MyHamilton311Client()

# Bounding box roughly covering Hamilton, OH
issues = client.get_issues(
    min_lat=39.368, min_lng=-84.588,
    max_lat=39.432, max_lng=-84.539,
)

print(f"{issues.pagination.entries} total issues found")
for issue in issues.issues:
    print(f"[{issue.status}] #{issue.id} — {issue.summary}")
    print(f"  {issue.address}")

Authenticated — profile, my issues, city notices

from myhamilton311 import MyHamilton311Client, authenticate

# Opens a browser tab for CivicPlus / SeeClickFix login
token = authenticate()

client = MyHamilton311Client(access_token=token)

profile = client.get_profile()
print(f"Logged in as {profile.name} ({profile.email})")

for notice in client.get_notices_iter():
    print(f"[{notice.published_at}] {notice.sender}: {notice.subject}")

If you already have a token (e.g. from a mitmproxy capture), supply it directly:

client = MyHamilton311Client(access_token="FvzaRk7i-HacbIx...")

API Reference

MyHamilton311Client

Method Auth required Description
get_mobile_app_config() No Mobile app feature flags & branding
get_scf_root() No SCF platform root config
get_mobile_strings() No Localised UI strings
get_closest_city(lat, lng) No Nearest SeeClickFix place
get_issues(min_lat, min_lng, max_lat, max_lng, …) No Issues in bounding box
get_issue(issue_id) No Single issue by ID
get_issues_page_iter(…) No Generator over all pages
get_bulletin_boards(lat, lng) No City bulletin boards near point
get_profile() Yes Authenticated user's profile
get_my_issues(…) Yes Issues reported by current user
get_notices(…) Yes City / org notices
get_notices_iter() Yes Generator over all notice pages
build_oauth_url(state, mode) — Build OAuth authorization URL

authenticate(mode, port, timeout)

Opens the system browser to complete the CivicPlus / SeeClickFix OAuth 2.0 implicit flow. Returns the Bearer access token string.


Protocol Notes

Reverse-engineered from 8 mitmproxy capture files covering:

  1. Initial app load — GET /scf/v1/mobile_app_config, GET /api/v3/bulletin_boards
  2. Browse issues — GET /api/v2/issues?…bbox…
  3. Registration — OAuth implicit flow → CivicPlus identity provider (IDS4) → OTP email verification → accept terms
  4. Sign out — GET /oauth/logout → CivicPlus backchannel logout
  5. Sign in — Email-based lookup → CivicPlus password page → OAuth token
  6. Notices — GET /api/v2/profile/notices
  7. View issue (authenticated) — GET /api/v2/issues/{id}?details=true
  8. View issue (unauthenticated) — same endpoint, no Bearer token

Authentication flow

App → GET /oauth/authorize?client_id=zBmhzPX…&response_type=token&scf_login=choose
    ← 302 → /oauth/login

User enters email → POST /oauth/login
    ← 302 → /federated_logins/ids4/1118?email=…  (CivicPlus IDP)

CivicPlus handles password entry → POST /federated_logins/ids4/callback (code + id_token JWT)
    ← 302 → /oauth/authorize  (SCF exchanges code for token)
    ← 302 → com.citysourced.hamiltonoh://oauth/callback#access_token=<BEARER_TOKEN>

Key constants

Constant Value
Base URL https://seeclickfix.com
OAuth Client ID zBmhzPXICuENMfUUhjX2nzvvADnCnuKxLxVPmsk4s_c
OAuth Redirect URI com.citysourced.hamiltonoh://oauth/callback
Hamilton Place ID 16830
Hamilton Org ID 1118
CivicPlus IDP https://cpauthentication.civicplus.com
iOS User-Agent MyHamilton%20311/3884 CFNetwork/3860.600.21 Darwin/25.5.0

This library is for research and personal use only. The SeeClickFix API is proprietary. Be respectful of rate limits and do not use this library for scraping at scale.

Metadata

Release files for myhamilton311 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for myhamilton311 0.1.0
File Size Uploaded
myhamilton311-0.1.0.tar.gz 16.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for myhamilton311 0.1.0
File Interpreter ABI Platform
myhamilton311-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.0 kB

Release files / myhamilton311-0.1.0.tar.gz

Download URL myhamilton311-0.1.0.tar.gz
Size 16.0 kB
Tags Source
SHA-256 checksum
How to use checksums
655b5287912c26c5d152edd275527e3a5ac04de379ca6cfdb7928e01163789ff
BLAKE2b-256 checksum
How to use checksums
f8496d6975320b95e3787e8c2e8f480825be4897ccd72b11bfcb0c05e90a4cd3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.1

Release files / myhamilton311-0.1.0-py3-none-any.whl

Download URL myhamilton311-0.1.0-py3-none-any.whl
Size 16.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8d93f0f5be8170b31a1d80d8c2aefe978dcc0afeb0fa5998592ab9fa1cfdafb8
BLAKE2b-256 checksum
How to use checksums
8585771d98dc5e0924deb07442f15c8f0707e3d9a5d7914864bd5da3d9a0db30
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.1

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page