Unofficial Python primitives for automating a small, explicit set of Canva account and team administration flows with Camoufox and Playwright.
This repository is not affiliated with, endorsed by, or sponsored by Canva. Use it only with accounts and teams you are authorized to administer, and review Canva's current terms before running it. The library does not solve or bypass CAPTCHA, MFA, consent, re-authentication, or risk challenges.
- Persistent, headful Camoufox sessions with optional proxy, locale, and timezone configuration.
- Exact-account login and saved-session verification.
- Read-only account-plan and team-membership observation.
- Invite, role-update, and removal flows with precondition and postcondition checks.
- Fail-closed challenge, origin, identity, and ambiguous-UI handling.
- Optional screenshots with page text and images redacted.
This is an automation library, not a service. It intentionally contains no HTTP API, database, job queue, scheduler, credential vault, or web UI.
- Python 3.11 or newer. The current compatibility baseline was tested on Python 3.14.
- A graphical desktop or display server: sessions are headful by design.
- A Canva account you are authorized to use.
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
python -m camoufox fetchCamoufox supplies its own Firefox build. python -m camoufox fetch downloads
that browser after the Python package is installed.
Set credentials in the environment so they do not appear in shell history:
export CANVA_EMAIL='owner@example.com'
export CANVA_PASSWORD='...'
python examples/account_check.pyThe example creates a persistent profile under profiles/default and writes
redacted screenshots under captures/. If Canva presents CAPTCHA, MFA,
consent, re-authentication, or a risk checkpoint, the run stops with a stable
error code instead of attempting a bypass.
from pathlib import Path
from canva_automation.browser.flows.team_sync import sync_team
from canva_automation.browser.session import CamoufoxSession, LaunchOptions
from canva_automation.browser.steps import StepRecorder
async def observe_team(email: str, password: str):
options = LaunchOptions(Path("profiles/default"))
recorder = StepRecorder(Path("captures"))
async with CamoufoxSession(options) as context:
page = context.pages[0] if context.pages else await context.new_page()
return await sync_team(page, email, lambda: password, recorder)Keep the load_password callback narrow: flows call it only when a verified
saved session cannot be reused. Do not log its return value.
- Architecture and trust boundaries
- Flow API and contracts
- Error codes
- Security and operating guidance
- Compatibility and troubleshooting
python -m pytest -qThe tests use fake Playwright pages and responses. They do not contact Canva or require a downloaded browser.
The project is alpha software. Canva can change visible labels, page structure, URLs, or internal response envelopes without notice. A selector mismatch is treated as an error; the library does not guess when a mutation target is ambiguous.
MIT. See LICENSE.