# @kentcdodds/canva — agent notes Human setup and intent live in [`README.md`](./README.md). This file is for agents: imports, smoke/dryRun execute snippets, and edge cases. Auth is the saved OAuth integration named **`canva`** — never paste tokens. Do not disable live webhooks or jobs. ## Auth / integration | Item | Value | | --- | --- | | Integration name | `canva` | | Reconnect | `https://kody.codes/connect/oauth?provider=canva` | | API base | `https://api.canva.com/rest` | | Approved hosts | `api.canva.com`, `www.canva.com` | Injected `Authorization` headers on helpers are ignored (integration-managed). ## Import paths | Export | Import | | --- | --- | | overview | `kody:@kentcdodds/canva` | | api (named helpers + default dispatcher) | `kody:@kentcdodds/canva/api` | | operations catalog | `kody:@kentcdodds/canva/operations` | | smoke-test | `kody:@kentcdodds/canva/smoke-test` | Prefer static `kody:@kentcdodds/canva/...` imports from `execute`. Do not lead with `packages.invoke`. Named helpers live on `./api` (for example `listDesigns`, `getDesign`, `createDesign`, `listFolderItems`). The default `./api` export dispatches by lowercase OpenAPI slug (`operation` + `input`). Request shape for named helpers / dispatch `input`: - `params` — path placeholders (`designId`, `folderId`, …) - `query` — filters, pagination, sort, limits - `headers` — operation-specific metadata (not `Authorization`) - `body` — JSON or binary body - `confirm` / `dryRun` — mutation safety ## Smoke test (read-only) ```js import smokeTest from 'kody:@kentcdodds/canva/smoke-test' export default async function main() { return await smokeTest() // => { ok: true, integration: 'canva', checks: { profile, capabilities } } // status + responseType only — no profile PII } ``` Optional discovery (no Canva call beyond local catalog): ```js import operationsCatalog from 'kody:@kentcdodds/canva/operations' export default async function main() { return await operationsCatalog() // => { count, operations: { listdesigns: { method, path, tag, ... }, ... } } } ``` ## dryRun / confirm (writes) Every mutating operation requires `confirm: true` after explicit user approval. Use `dryRun: true` to preview method, path template, and request without contacting Canva. ```js import { createDesign } from 'kody:@kentcdodds/canva/api' export default async function main() { return await createDesign({ body: { design_type: { type: 'preset', name: 'presentation' }, title: 'Quarterly review', }, dryRun: true, }) } ``` Slug dispatcher: ```js import canva from 'kody:@kentcdodds/canva/api' export default async function main() { return await canva({ operation: 'listdesigns', input: { query: { limit: 5 } }, }) } ``` Read-only example: ```js import { getDesign, listDesigns } from 'kody:@kentcdodds/canva/api' export default async function main() { const recent = await listDesigns({ query: { ownership: 'owned', sort_by: 'modified_descending', limit: 10 }, }) const design = await getDesign({ params: { designId: 'DAVZr1z5464' } }) return { recent, design } } ``` ## Edge cases - Preview APIs can change without notice; they are marked `preview` in `./operations` and cannot be used in public Canva integrations under review. - `createComment` is deprecated; prefer `createThread`. - Resize APIs need Canva Pro (or eligible plan). Autofill / some brand-template ops need Canva Enterprise. - Async create ops return job IDs — poll the matching `get*Job` until `success` or `failed`. - Rate limits throw `CanvaApiError` with `status`, `body`, and `retryAfter`. - Never paste Canva OAuth tokens into chat or logs.