An unofficial Python client for the Cozi Family Organizer API that provides a robust and type-safe interface to the Cozi service.
- Async/await support - Built with
aiohttpfor efficient async operations - Type safety - Full type hints and Pydantic models for all API interactions
- Comprehensive API coverage - Support for lists, calendar, and account management
- Error handling - Custom exception classes for different error scenarios
- Rate limiting - Built-in rate limit handling and retry logic
- Authentication - Secure credential management and session handling
pip install py-cozi-clientFor development:
pip install py-cozi-client[dev]import asyncio
from cozi_client import CoziClient
from models import ListType, ItemStatus
async def main():
async with CoziClient("your_username", "your_password") as client:
# Create a shopping list
shopping_list = await client.create_list("Groceries", ListType.SHOPPING)
# Add items to the list
await client.add_item(shopping_list.id, "Milk")
await client.add_item(shopping_list.id, "Bread")
# Get all lists
lists = await client.get_lists()
for lst in lists:
print(f"List: {lst.title} ({lst.list_type})")
asyncio.run(main())The main client class for interacting with the Cozi API.
# Authentication happens automatically with username/password in constructor
client = CoziClient(username, password)
# Or logout manually
await client.logout()# Create lists
await client.create_list(title: str, list_type: ListType) -> CoziList
# Get lists
await client.get_lists() -> List[CoziList]
await client.get_lists_by_type(list_type: ListType) -> List[CoziList]
# Update lists
await client.update_list(list_obj: CoziList) -> CoziList
# Delete lists
await client.delete_list(list_id: str) -> bool# Add items
await client.add_item(list_id: str, text: str, position: int = 0) -> CoziItem
# Update item text
await client.update_item_text(list_id: str, item_id: str, text: str) -> CoziItem
# Mark item status
await client.mark_item(list_id: str, item_id: str, status: ItemStatus) -> CoziItem
# Remove items
await client.remove_items(list_id: str, item_ids: List[str]) -> bool# Get calendar for a specific month
await client.get_calendar(year: int, month: int) -> List[CoziAppointment]
# Create appointments
await client.create_appointment(appointment: CoziAppointment) -> CoziAppointment
# Update appointments
await client.update_appointment(appointment: CoziAppointment) -> CoziAppointment
# Delete appointments
await client.delete_appointment(appointment_id: str, year: int, month: int) -> bool# Get family members
await client.get_family_members() -> List[CoziPerson]
# Get account information
await client.get_account_info()All models are built with Pydantic for automatic validation, serialization, and type safety.
class CoziList(BaseModel):
id: Optional[str]
title: str
list_type: ListType # Automatically converted to string values
items: List[CoziItem]
owner: Optional[str] = None
version: Optional[int] = None
notes: Optional[str] = None
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = Noneclass CoziItem(BaseModel):
id: Optional[str]
text: str
status: ItemStatus # Automatically converted to string values
position: Optional[int] = None
item_type: Optional[str] = None
due_date: Optional[date] = None
notes: Optional[str] = None
owner: Optional[str] = None
version: Optional[int] = None
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = Noneclass CoziAppointment(BaseModel):
id: Optional[str]
subject: str
start_day: date
start_time: Optional[time]
end_time: Optional[time]
date_span: int = 0
attendees: List[str] = []
location: Optional[str] = None
notes: Optional[str] = None
# ... additional fields for recurrence, item details, etc.class CoziPerson(BaseModel):
id: str
name: str
email: Optional[str] = None
phone: Optional[str] = None
color: Optional[int] = None
# ... additional account fieldsclass ListType(Enum):
SHOPPING = "shopping"
TODO = "todo"
class ItemStatus(Enum):
COMPLETE = "complete"
INCOMPLETE = "incomplete"CoziException- Base exception classAuthenticationError- Authentication failuresValidationError- Request validation errorsRateLimitError- API rate limit exceededAPIError- General API errorsNetworkError- Network connectivity issuesResourceNotFoundError- Resource not found (404)PermissionDeniedError- Access forbidden (403)
git clone <repository-url>
cd py-cozi-client
pip install -e .[dev]End-to-end demo scripts live in examples/ and exercise the client against the
live Cozi API. They prompt for credentials (or read COZI_USERNAME /
COZI_PASSWORD) and require an active Cozi account, so they are not run in CI.
examples/demo_lists.py- List and item managementexamples/demo_calendar.py- Calendar and appointment management
Automated unit tests live in tests/ and run offline (HTTP mocked with
aioresponses):
pip install -e .[dev]
pytest- Python 3.7+
- aiohttp 3.9.2+
- pydantic 2.0+
MIT License
Contributions are welcome! Please feel free to submit a Pull Request.
Matthew Jucius