
Product
Introducing Webhook Events for Alert Changes
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.
@brandcast_app/cozi-api-client
Advanced tools
Unofficial TypeScript/JavaScript client for Cozi Family Organizer API (reverse-engineered)
Unofficial TypeScript/JavaScript client for the Cozi Family Organizer API.
This is an UNOFFICIAL client library. Cozi does not provide a public API, and this library is based on reverse engineering from the py-cozi Python library.
Use at your own risk:
npm install @brandcast_app/cozi-api-client
or
yarn add @brandcast_app/cozi-api-client
import { CoziApiClient } from '@brandcast_app/cozi-api-client';
// Create a client instance
const client = new CoziApiClient({
debug: true, // Optional: enable debug logging
timeout: 30000, // Optional: request timeout in ms (default: 30000)
userAgent: 'my-app', // Optional: custom user agent
});
// Authenticate
const auth = await client.authenticate('your@email.com', 'your-password');
console.log('Authenticated with account:', auth.accountId);
// Get all lists
const lists = await client.getLists();
console.log('Found lists:', lists.length);
// Work with lists
for (const list of lists) {
console.log(`${list.title} (${list.listType}): ${list.items.length} items`);
for (const item of list.items) {
console.log(` - [${item.status}] ${item.text}`);
}
}
authenticate(username: string, password: string): Promise<CoziAuthResponse>Authenticate with Cozi using your email and password.
const auth = await client.authenticate('your@email.com', 'your-password');
// Returns: { accountId, accountPersonId, accessToken, expiresIn }
setSessionToken(token: string, accountId?: string): voidRestore a previous session using a stored access token.
client.setSessionToken(storedToken, storedAccountId);
getLists(): Promise<CoziList[]>Get all lists for the authenticated user.
const lists = await client.getLists();
getList(listId: string): Promise<CoziList>Get a specific list by ID.
const list = await client.getList('list-id');
addList(request: AddListRequest): Promise<string>Create a new list.
const listId = await client.addList({
title: 'Grocery Shopping',
type: 'shopping' // 'shopping' or 'todo'
});
removeList(listId: string): Promise<void>Delete a list.
await client.removeList('list-id');
reorderList(request: ReorderListRequest): Promise<void>Change the order of a list.
await client.reorderList({
listId: 'list-id',
newOrder: 2
});
addItem(request: AddItemRequest): Promise<void>Add an item to a list.
await client.addItem({
listId: 'shopping-list-id',
text: 'Milk'
});
editItem(request: EditItemRequest): Promise<void>Edit an existing item.
await client.editItem({
listId: 'shopping-list-id',
itemId: 'item-id',
text: 'Whole Milk'
});
markItem(request: MarkItemRequest): Promise<void>Mark an item as complete or incomplete.
// Mark as complete
await client.markItem({
listId: 'shopping-list-id',
itemId: 'item-id',
completed: true
});
// Mark as incomplete
await client.markItem({
listId: 'shopping-list-id',
itemId: 'item-id',
completed: false
});
removeItem(request: RemoveItemRequest): Promise<void>Remove an item from a list.
await client.removeItem({
listId: 'shopping-list-id',
itemId: 'item-id'
});
interface CoziList {
listId: string;
title: string;
listType: 'shopping' | 'todo';
items: CoziItem[];
version: number;
notes?: string | null;
owner?: string | null;
}
interface CoziItem {
itemId: string;
text: string;
status: 'incomplete' | 'complete';
itemType?: string | null;
dueDate?: string | null;
notes?: string | null;
owner?: string | null;
version: number;
}
interface CoziAuthResponse {
accountId: string;
accountPersonId: string;
accessToken: string;
expiresIn: number; // seconds
}
import { CoziApiClient } from '@brandcast_app/cozi-api-client';
async function main() {
// Create client with debug logging
const client = new CoziApiClient({ debug: true });
try {
// Authenticate
const auth = await client.authenticate('your@email.com', 'your-password');
console.log('✓ Authenticated successfully');
// Get all lists
const lists = await client.getLists();
console.log(`✓ Found ${lists.length} lists`);
// Find shopping list
const shoppingList = lists.find(l => l.listType === 'shopping');
if (!shoppingList) {
throw new Error('No shopping list found');
}
// Add an item
await client.addItem({
listId: shoppingList.listId,
text: 'Organic Milk'
});
console.log('✓ Added item to shopping list');
// Get updated list
const updatedList = await client.getList(shoppingList.listId);
const newItem = updatedList.items.find(i => i.text === 'Organic Milk');
if (newItem) {
// Mark it as complete
await client.markItem({
listId: shoppingList.listId,
itemId: newItem.itemId,
completed: true
});
console.log('✓ Marked item as complete');
// Remove it
await client.removeItem({
listId: shoppingList.listId,
itemId: newItem.itemId
});
console.log('✓ Removed item from list');
}
} catch (error) {
console.error('Error:', error);
}
}
main();
The client throws errors that conform to the CoziApiError interface:
interface CoziApiError {
code: string;
message: string;
details?: unknown;
}
Example error handling:
try {
await client.addItem({
listId: 'invalid-list-id',
text: 'Test item'
});
} catch (error) {
const coziError = error as CoziApiError;
console.error('Error code:', coziError.code);
console.error('Error message:', coziError.message);
console.error('Error details:', coziError.details);
}
Access tokens expire after a certain period (specified in expiresIn from the auth response). You can store the token and accountId to avoid re-authenticating:
// Initial authentication
const auth = await client.authenticate('your@email.com', 'your-password');
// Store token securely
localStorage.setItem('cozi_token', auth.accessToken);
localStorage.setItem('cozi_account_id', auth.accountId);
// Later, restore session
const storedToken = localStorage.getItem('cozi_token');
const storedAccountId = localStorage.getItem('cozi_account_id');
if (storedToken && storedAccountId) {
client.setSessionToken(storedToken, storedAccountId);
// Now you can make API calls without re-authenticating
}
npm install
npm run build
npm test
This library is based on the excellent reverse engineering work done in the py-cozi Python library.
This is an unofficial library and is not affiliated with, endorsed by, or connected to Cozi. Use at your own risk. The developers of this library are not responsible for any issues that may arise from its use.
MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
FAQs
Unofficial TypeScript/JavaScript client for Cozi Family Organizer API (reverse-engineered)
We found that @brandcast_app/cozi-api-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.

Security News
ENISA has become a CVE Program Root, giving the EU a central authority for coordinating vulnerability reporting, disclosure, and cross-border response.

Product
Socket now scans OpenVSX extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.