@wokuapp/ai-toolkit 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@
11
11
  "name": "woku",
12
12
  "source": "./",
13
13
  "description": "Design a listening program for your customer journey, run the VoC instruments (NPS, CSAT, CES, wokus), and turn every signal into a support ticket or an action plan, through woku's MCP server.",
14
- "version": "0.2.1",
14
+ "version": "0.3.0",
15
15
  "author": { "name": "woku" },
16
16
  "license": "MIT",
17
17
  "homepage": "https://woku.app",
@@ -1,9 +1,22 @@
1
1
  {
2
2
  "name": "woku",
3
3
  "description": "Voice-of-customer for Claude Code. Design a listening program for your customer journey, run the fast VoC instruments (NPS, CSAT, CES, wokus), and turn every signal into a support ticket or an action plan, through woku's MCP server. Bundles the woku method so the agent acts as a CX consultant.",
4
- "version": "0.2.1",
5
- "author": { "name": "woku" },
4
+ "version": "0.3.0",
5
+ "author": {
6
+ "name": "woku"
7
+ },
6
8
  "homepage": "https://woku.app",
7
9
  "license": "MIT",
8
- "keywords": ["woku", "mcp", "voice-of-customer", "cx", "nps", "csat", "ces", "surveys", "feedback", "sdk"]
10
+ "keywords": [
11
+ "woku",
12
+ "mcp",
13
+ "voice-of-customer",
14
+ "cx",
15
+ "nps",
16
+ "csat",
17
+ "ces",
18
+ "surveys",
19
+ "feedback",
20
+ "sdk"
21
+ ]
9
22
  }
@@ -1,12 +1,24 @@
1
1
  {
2
2
  "name": "woku",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Voice-of-customer for OpenAI Codex. Design a listening program, run the VoC instruments (NPS, CSAT, CES, wokus), and turn every signal into a support ticket or an action plan, through woku's MCP server.",
5
- "author": { "name": "woku" },
6
- "homepage": "https://docs.woku.app/mcp/agent-guide",
5
+ "author": {
6
+ "name": "woku"
7
+ },
8
+ "homepage": "https://woku.app/docs/en/mcp/agent-guide",
7
9
  "repository": "https://github.com/wokuApp/woku-ai-toolkit",
8
10
  "license": "MIT",
9
- "keywords": ["woku", "voice-of-customer", "cx", "nps", "csat", "ces", "surveys", "feedback", "sdk"],
11
+ "keywords": [
12
+ "woku",
13
+ "voice-of-customer",
14
+ "cx",
15
+ "nps",
16
+ "csat",
17
+ "ces",
18
+ "surveys",
19
+ "feedback",
20
+ "sdk"
21
+ ],
10
22
  "skills": "./skills/",
11
23
  "mcpServers": {
12
24
  "woku": {
@@ -20,7 +32,10 @@
20
32
  "longDescription": "Connect your agent to woku, the voice-of-customer platform. Design a listening program for your customer journey, place the fast VoC instruments (NPS, CSAT, CES, wokus) at each moment of truth, and turn every signal into a support ticket or an action plan.",
21
33
  "developerName": "woku",
22
34
  "category": "Productivity",
23
- "capabilities": ["Read", "Write"],
35
+ "capabilities": [
36
+ "Read",
37
+ "Write"
38
+ ],
24
39
  "websiteURL": "https://woku.app",
25
40
  "privacyPolicyURL": "https://woku.app/privacy-policy",
26
41
  "termsOfServiceURL": "https://woku.app/terms-and-conditions",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ Also the per-tool metrics of a folder (`get_folder_tools_metrics`, `folders.metrics`), tracker chips on `search_voc_tools` and `tools.list` (`trackers`) and `integrationProvider` on integration folders.
6
+
7
+ Cover folders and the unified tools view: the woku skill documents the MCP tools
8
+ `search_voc_tools`, `get_voc_tools_stats`, `move_voc_tools`, `update_folder` (also sets the folder's `whatsappAlertRecipients`),
9
+ `delete_folder`, `get_folder_report` (`scope: "all"`, `format: "csv"`), `folderId`
10
+ on `create_nps_tool`, `create_csat_tool` and `create_ces_tool`, and the
11
+ `organize_listening` playbook, flows with ordered steps (`create_flow`, `update_flow`, `get_flow` with `steps`), and journeys in folders (`get_journey_folders_status`, `organize_journey_folders`, `folderId` and `momentFolders` on journeys). The JavaScript and Python SDK skills add the
12
+ `folders` and `tools` resources. Requires the server and SDK releases that ship them. The skills also cover the folder PDF in the SDKs (`folders.pdf`) and the folders paging (`foldersLimit`, `foldersCursor`) of `search_voc_tools` and `tools.list`.
13
+
14
+ ## 0.2.2
15
+
16
+ Reconcile journey/MCP workflows, reviewed proposals, local media, SDK v4 methods,
17
+ retry boundaries and instrument selection in the shipped skills. Correct NPS
18
+ variable examples and public cursor limits.
19
+
3
20
  ## 0.2.1
4
21
 
5
22
  Remove the action-plan external-send example (Jira/Monday/ClickUp/Notion) from the SDK skills: those destinations are not available in production and the SDKs dropped `actionPlans.send`. The skills now show approve plus manage-in-woku.
package/README.md CHANGED
@@ -6,10 +6,12 @@ The toolkit gives your agent woku's full tool catalog through woku's MCP server,
6
6
 
7
7
  It bundles:
8
8
 
9
- - The **woku MCP server** connection (`https://api.woku.app/mcp`), so the agent gets the full catalog (143 tools) with woku's OAuth. No API keys to copy.
9
+ - The **woku MCP server** connection (`https://api.woku.app/mcp`), so the agent gets the live catalog with woku's OAuth. No API keys to copy.
10
10
  - The **woku skill**, which primes the agent with the method and tells it to call `woku_guide` first.
11
11
  - The **woku SDK skills** for JavaScript (`@wokuapp/sdk`) and Python (`woku`), so the agent can build server-side woku integrations in code (create tools, send surveys, read responses, drive tickets and action plans) over the public `/v1` API.
12
12
 
13
+ The live `tools/list` response is authoritative. The catalog focuses on journeys, feedback instruments, clients, trackers, instrument reports and action plans. Data Studio and support tickets are Corporate capabilities.
14
+
13
15
  ## Install
14
16
 
15
17
  ### Claude Code
@@ -81,7 +83,7 @@ These are configured from the app, not from a package. Add a custom connector (c
81
83
 
82
84
  Point it at `https://api.woku.app/mcp` and approve access from your woku account.
83
85
 
84
- See the [connect guide](https://docs.woku.app/mcp/connect-a-client) and the [agent guide](https://docs.woku.app/mcp/agent-guide) for details.
86
+ See the [connect guide](https://woku.app/docs/en/mcp/connect-a-client) and the [agent guide](https://woku.app/docs/en/mcp/agent-guide) for details.
85
87
 
86
88
  ## What you get
87
89
 
@@ -97,3 +99,33 @@ Every connection is bound to one company, chosen when you approve access. Read t
97
99
  ## License
98
100
 
99
101
  MIT. See [LICENSE](./LICENSE).
102
+
103
+ ### Folders and tools update (0.3.0)
104
+
105
+ The skills now cover the folder tree that holds wokus and NPS, CSAT and CES tools:
106
+ the MCP tools `search_voc_tools` (with tracker chips), `get_voc_tools_stats`, `get_folder_tools_metrics`, `move_voc_tools`,
107
+ `update_folder`, `delete_folder`, `get_folder_report` (`scope: "all"`, `format: "csv"`),
108
+ `get_journey_folders_status`, `organize_journey_folders`, flow `steps` in `create_flow` and `update_flow`, `folderId` on the `create_*_tool` tools, the `organize_listening` playbook of
109
+ `woku_guide`, and the SDK `folders` and `tools` resources in JavaScript and Python.
110
+ Verify the installed SDK and server release before using them.
111
+
112
+ ### Journey guidance update (0.2.2)
113
+
114
+ The bundled skills now route coordinated evaluations through journeys, preserve a
115
+ reviewed MCP proposal, explain local media capabilities by host, and cover the v4
116
+ SDK media and enrollment iterators. They distinguish protected retries from other
117
+ writes and use variable fragments for NPS questions. Verify the installed SDK
118
+ release before using journey and media methods.
119
+
120
+ #### Local media by host
121
+
122
+ - Codex and Claude Code upload local files through multipart `POST /v1/woku-media`
123
+ or the backend SDK. The remote MCP tool accepts a public HTTPS URL or a supported
124
+ host-authorized file, never a local path or image bytes pasted as model text.
125
+ Never put a company secret key in frontend code.
126
+ - ChatGPT and Claude web attachment access depends on the host and connector. Use
127
+ only file references that the connected tool can actually read, or a genuinely
128
+ public HTTPS URL. Do not invent a URL for a private attachment or promise that
129
+ every host forwards its uploaded files automatically.
130
+ - Check the live tool schema and the `customer_journeys` playbook before choosing
131
+ the representation. Upload first, then use its `fileId` in the reviewed proposal.
@@ -2,8 +2,10 @@
2
2
  "id": "woku-ai-toolkit",
3
3
  "name": "woku AI Toolkit",
4
4
  "description": "Voice-of-customer for your agent. Design a listening program, run the VoC instruments (NPS, CSAT, CES, wokus), and turn every signal into a support ticket or an action plan, through woku's MCP server.",
5
- "version": "0.2.1",
6
- "skills": ["./skills"],
5
+ "version": "0.3.0",
6
+ "skills": [
7
+ "./skills"
8
+ ],
7
9
  "configSchema": {
8
10
  "type": "object",
9
11
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@wokuapp/ai-toolkit",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "woku AI Toolkit: connect your agent to woku's voice-of-customer platform. Design VoC programs and turn customer feedback into support tickets and action plans, through woku's MCP server.",
5
5
  "author": "woku",
6
6
  "license": "MIT",
7
- "homepage": "https://docs.woku.app/mcp/agent-guide",
7
+ "homepage": "https://woku.app/docs/en/mcp/agent-guide",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "https://github.com/wokuApp/woku-ai-toolkit"
@@ -21,11 +21,59 @@ Every business is a customer journey, and each moment of truth decides whether t
21
21
 
22
22
  ## How to help
23
23
 
24
- 1. To design a program, call `design_voc_program`. Pass what the user knows (business type, channels, their journey moments, how to segment) and it returns a blueprint: the recommended instrument per moment (from the canonical template: sale to CSAT, delivery to woku, support to CES, post-sale to woku, loyalty to NPS), the tracker design, the action wiring, and the ordered `create_*` steps to build it.
24
+ 1. For a coordinated customer journey, use the journey workflow below. For a collection of independent instruments, call `design_voc_program`. Pass what the user knows (business type, channels, their journey moments, how to segment) and it returns a blueprint: the recommended instrument per moment (from the canonical template: sale to CSAT, delivery to woku, support to CES, post-sale to woku, loyalty to NPS), the tracker design, the action wiring, and the ordered `create_*` steps to build it.
25
25
  2. Walk the blueprint with the user and adapt it to their real journey.
26
26
  3. Build it with the `create_*` tools once the user approves, and distribute the instruments with the `send_*` tools. Nothing is created or sent without an explicit confirmation.
27
27
  4. From then on, let every signal trigger its action: tickets for individual attention, plans for systematic improvement.
28
28
 
29
29
  ## Safety
30
30
 
31
- Read tools need no special permission. Write tools require the `mcp:write` scope, and destructive tools (for example `delete_woku`) or sends (for example `send_nps_invitations`, `send_report_now`) require `confirm: true`. The list the server advertises on a live connection (`tools/list`) is always the authoritative answer about what is available.
31
+ Read tools need no special permission. Write tools require the `mcp:write` scope, and destructive tools (for example `delete_woku`) or sends (for example `send_nps_invitations`) require `confirm: true`. The list the server advertises on a live connection (`tools/list`) is always the authoritative answer about what is available.
32
+
33
+ ## Customer journey workflow
34
+
35
+ 1. Call `woku_guide` with topic `customer_journeys`, and use `tools/list` as the live catalog.
36
+ 2. Collect the business experience, ordered moments and what to learn at each one.
37
+ Use `propose_journey` to interpret that brief. One moment gets one tool: Woku for
38
+ multiple facets, CSAT for satisfaction, CES for effort, NPS for recommendation.
39
+ Infer a separate loyalty intent without splitting delivery facets into moments.
40
+ 3. Review the returned draft. Pass that exact draft as `proposal` to
41
+ `create_journey_from_brief` with the authorized confirmation, avoiding a second
42
+ model proposal. `create_journey` accepts an explicit definition instead.
43
+ 4. Use `upload_woku_media` and `set_journey_moment_media` for missing media. Read
44
+ the media section of that journey playbook and the toolkit README for host-specific attachments; do not invent public attachment
45
+ URLs or claim local-file access in a host that does not provide it. `create_woku`
46
+ supports a standalone Woku using the same upload result.
47
+ 5. Keep the draft disabled while configuring. Webhook content requires one tool
48
+ per evaluation. Static content defaults to sharing within that moment. Preview
49
+ conditional descriptions, localized question variables, public image URLs,
50
+ trackers, folders and client fields before activation. HTTP uses sequence;
51
+ MCP uses cadence. Neither accepts secret fields in the definition.
52
+ 6. Configure each moment credential explicitly. Generated URL tokens and sender
53
+ HMAC secrets are separate from the legacy journey signature; never log them.
54
+ Activate with `update_journey` only within the user's authorized intent.
55
+ 7. Use enrollment lists and exact enrollment ids for inspection/stopping. Default
56
+ reminders are enabled; a stopped or completed cycle may be followed by another,
57
+ but never two open evaluations for the same subject in the same journey.
58
+
59
+ ## Flows with steps
60
+
61
+ A flow is an ordered sequence of steps a respondent answers one after another. `create_flow` and `update_flow` take `steps`: 1 to 20 `{ type, toolId }` where `type` is `woku`, `nps`, `csat` or `ces` (each tool once, all of the company; for the company-level NPS use the company id as `toolId`). The older `wokusIds` and `npsId` still work. `get_flow` and `list_flows` return `steps`. Flows live outside folders. Call `woku_guide` with topic `flows`.
62
+
63
+ ## Organize the listening in folders
64
+
65
+ One folder tree holds wokus and NPS, CSAT and CES tools together. Call `woku_guide` with topic `organize_listening` first.
66
+
67
+ - `search_voc_tools` lists a folder level or searches the whole company (any type, case and accent insensitive, cursor paginated) and returns folders with stats, tools with their native-scale headline and counts per type.
68
+ - `search_voc_tools` also takes `trackers` (`"name:value"` chips, up to 10; a tool must have every one; the tracker name is matched exactly and the value partially and ignoring case, so `482` also matches `00482`; company-wide, no folders; a chip without name or value is an error) to find tools by tracker.
69
+ - `get_folder_tools_metrics` gives, for a folder and its subfolders, per-tool figures for 7, 30 (default) or 90 days against the period before (0 = whole history) and the histogram of scores. It returns `toolCount` and the busiest tools (`limit`, default 50); the daily sums only with `includeDaily: true`. Use it for trends and to find the weakest tools; never average across types.
70
+ - `get_voc_tools_stats` gives reviews and the headline of each type (woku stars, NPS score, CSAT satisfied %, CES mean) for the company or one folder. Never average across types: the scales differ.
71
+ - `create_folder`, `update_folder` (rename, recolor, or set `whatsappAlertRecipients`: the WhatsApp numbers alerted when a comment of any tool in the folder is an improvement) and `move_voc_tools` (items of mixed types, `folderId: null` for the root) organize the tree; `create_nps_tool`, `create_csat_tool` and `create_ces_tool` accept `folderId`.
72
+ - `get_folder_report` with `scope: "all"` returns the mixed AI report of a folder and its subfolders, and with `format: "csv"` the responses as CSV text. `search_voc_tools` accepts `foldersLimit` and `foldersCursor` to page the folders ("see more"; `foldersNextCursor` in the result). The folder PDF is binary, so it is only on the API and the SDKs (`GET /v1/folders/{id}/pdf`).
73
+ - Journeys can live in folders (`Viajes > journey > moment`): `get_journey_folders_status` shows whether the company organizes them and what is pending, and `organize_journey_folders` switches it on and runs a background pass that only moves tools without a folder (propose it and wait for approval; it returns a conflict while a pass is running). `get_journey` and `list_journeys` show `folderId` and `momentFolders`, and folders created by woku carry an `origin` (`journeys-root`, `journey`, `journey-moment`, `integration`; integration folders also carry `integrationProvider`, for example `shopify`); read `origin`, `integrationProvider` and the stats of a folder with `search_voc_tools`, not with `get_folder` or `list_folders`, which only count wokus.
74
+ - `delete_folder` needs `confirm: true`; nothing inside is deleted, the content moves up to the parent. Moving or deleting folders is a user decision: propose the new structure and wait for approval.
75
+
76
+ Tickets use email destinations; plans use groups of platform users. Tickets and
77
+ Data Studio are Corporate capabilities. Do not expose retired reports, alerts,
78
+ goals, data-source or data-flow management through examples; instrument reports
79
+ and survey flows remain available.
@@ -8,7 +8,7 @@ description: "Build a server-side woku integration in JavaScript or TypeScript w
8
8
  `@wokuapp/sdk` is the official **server-side** client for the woku management API
9
9
  (`/v1`). Use it when the user wants woku operations in their Node.js backend
10
10
  instead of raw HTTP. It is typed, retries transient failures, makes creates
11
- idempotent, and auto-paginates lists.
11
+ safe for protected writes, and supports pagination.
12
12
 
13
13
  **Server-only.** The company secret key grants full management access. Keep it on
14
14
  the backend, never in a browser, mobile app or other untrusted client. For
@@ -33,8 +33,9 @@ const woku = new Woku({ apiKey: process.env.WOKU_API_KEY });
33
33
 
34
34
  ## Core operations
35
35
 
36
- Creates are idempotent (auto `Idempotency-Key`); actions (send, test, reply) are
37
- never auto-retried.
36
+ GETs and protected writes retry with a stable key: tracker/VoC definitions,
37
+ invitations, and journey create/enroll/stop/mint-URL/event operations. Other writes
38
+ and uploads are attempted once. A key alone does not make a write idempotent.
38
39
 
39
40
  ```ts
40
41
  // Tracker definitions and values (wire your CRM/ERP ids to feedback tools).
@@ -44,7 +45,8 @@ await woku.trackers.assignToWoku('woku_123', { name: 'Store #1', value: 'TX-42'
44
45
  // VoC tools: npsTools / csatTools / cesTools (create/list/get/update/delete).
45
46
  const tool = await woku.npsTools.create({
46
47
  name: 'Post-purchase',
47
- npsMessage: 'How likely are you to recommend us?',
48
+ npsMessage: 'our company',
49
+ audienceType: 'a friend or colleague',
48
50
  });
49
51
 
50
52
  // Send a survey. IMPORTANT: `channel` is required and `recipients` is an array
@@ -69,7 +71,8 @@ await woku.actionPlans.complete('plan_123');
69
71
 
70
72
  Namespaces: `trackers`, `npsTools` / `csatTools` / `cesTools`, `nps` / `csat` /
71
73
  `ces`, `wokus`, `forms`, `flows`, `actionPlans`, `actionPlanGroups`, `tickets`,
72
- `ticketDestinations`, `dispatches`, `reports`, `company`, `quarantines`.
74
+ `ticketDestinations`, `dispatches`, `reports`, `company`, `quarantines`, `journeys`, `media`,
75
+ `folders`, `tools`, `journeyFolders`.
73
76
 
74
77
  ## Pagination, errors, retries
75
78
 
@@ -90,6 +93,76 @@ the old one; store the returned key. `woku.company.revokeKey()` disables the key
90
93
  ## When to reach for the reference
91
94
 
92
95
  For the full method list, request/response shapes and per-call options, point the
93
- user to the SDK page at https://docs.woku.app/development/sdk-javascript and the
94
- API reference at https://docs.woku.app/development/api. There is an equivalent
96
+ user to the SDK page at https://woku.app/docs/en/development/sdk-javascript and the
97
+ API reference at https://woku.app/docs/en/development/api. There is an equivalent
95
98
  Python SDK (`woku`) documented at /development/sdk-python.
99
+
100
+ ## Folders and tools
101
+
102
+ One folder tree holds wokus and NPS, CSAT and CES tools. Needs the SDK release that ships `folders` and `tools`; verify the installed version.
103
+
104
+ ```ts
105
+ const folder = await woku.folders.create({ name: 'Post-sale' });
106
+ await woku.csatTools.create({ name: 'Delivery', question: 'How satisfied are you?', folderId: folder.id });
107
+
108
+ for await (const tool of await woku.tools.list({ folderId: folder.id, types: ['csat', 'nps'] })) {
109
+ console.log(tool.type, tool.name, tool.headline.value);
110
+ }
111
+ const stats = await woku.tools.stats({ folderId: folder.id }); // native scales, never averaged across types
112
+ const tagged = await woku.tools.list({ trackers: ['TRR:00482'] }); // tracker chips 'name:value', company-wide
113
+ const metrics = await woku.folders.metrics(folder.id, { days: 30 }); // per tool, period vs the previous one; 0 = all history
114
+ await woku.tools.move({ items: [{ type: 'csat', id: toolId }], folderId: null }); // null = root
115
+ const csv: string = await woku.folders.csv(folder.id);
116
+ const pdf: Uint8Array = await woku.folders.pdf(folder.id, { lang: 'en' }); // folder report as PDF bytes
117
+ await woku.folders.delete(folder.id); // content moves up to the parent, nothing is deleted
118
+ ```
119
+
120
+ Journeys in folders: `await woku.journeyFolders.status()` and `await woku.journeyFolders.organize()` (background pass, 409 while running); `journeys.get` returns `folderId` and `momentFolders`, and folders expose `origin`.
121
+
122
+ `folders`: `list`, `get`, `create`, `update`, `move`, `delete`, `report`, `csv`, `pdf`. `tools`: `list` (cursor iterable; `foldersLimit` pages the folders with `page.hasMoreFolders()` / `page.getMoreFolders()`), `stats`, `move`. `npsTools` / `csatTools` / `cesTools` accept `folderId` on `create` and have `move(id, { folderId })`.
123
+
124
+ ## Flows
125
+
126
+ ```ts
127
+ const flow = await woku.flows.create({
128
+ name: 'Post-sale',
129
+ steps: [{ type: 'nps', toolId: npsToolId }, { type: 'csat', toolId: csatToolId }, { type: 'woku', toolId: wokuId }],
130
+ });
131
+ await woku.flows.update(flow._id, { steps: [{ type: 'csat', toolId: csatToolId }] });
132
+ await woku.flows.delete(flow._id); // its tools and responses stay
133
+ ```
134
+
135
+ `flows`: `list`, `get`, `create`, `update`, `delete`. 1 to 20 steps, each tool once; for an `nps` step the company id as `toolId` is the company-level NPS. Needs the SDK release that ships flow writes.
136
+
137
+ ## Customer journeys and media
138
+
139
+ Prefer an actual journey when the task coordinates several business moments.
140
+ One moment has one tool: several facets use Woku, satisfaction CSAT, effort CES,
141
+ recommendation NPS. A separate loyalty intention can add a moment; several facets
142
+ of delivery must not become several delivery moments. Journey response tools are
143
+ identified. Operator sends start immediately; opening a QR/link waits for a saved
144
+ first response. Later moments wait or use their webhook, optionally with a backup.
145
+ Default wait is ten days; zero means one hour. Keep reminders enabled unless asked.
146
+
147
+ The SDK exposes 17 journey methods, plus lazy enrollment iteration. Public cursor
148
+ pages allow 100 items (default 20); the Admin page endpoint is separate and uses 50.
149
+ Use the exact enrollment id to stop one case. Editing creates a new definition
150
+ version; running cases keep their snapshot. A cycle finishes on its last response
151
+ or 30 days from the first send of the last moment.
152
+
153
+ Media uploads use multipart and return fileId for moment.toolSpec.fileId. They do
154
+ not retry automatically; 413 is PayloadTooLargeError. Company keys remain on the
155
+ backend; minted webhook URLs use a separate HTTP transport without that key.
156
+ Keep request/idempotency ids stable during uncertain retries. Deduplication lasts
157
+ 24 hours; inspect the outcome before submitting with a new key.
158
+
159
+ Journey and media methods require SDK version 0.3.0 or later. Verify the installed
160
+ version and changelog when upgrading an existing integration.
161
+
162
+ ```ts
163
+ const media = await woku.media.upload({ file: imageBytes, filename: 'delivery.jpg', contentType: 'image/jpeg' });
164
+ for await (const enrollment of woku.journeys.iterEnrollments(journeyId, { limit: 100 })) {
165
+ console.log(enrollment.id, enrollment.lifecycle);
166
+ }
167
+ await woku.journeys.previewMoment(journeyId, 'delivery', { order: 'case-123', late: true });
168
+ ```
@@ -9,7 +9,7 @@ The `woku` package is the official **server-side** client for the woku
9
9
  management API (`/v1`), over `httpx`. Use it when the user wants woku operations
10
10
  in their Python backend instead of raw HTTP. It offers a synchronous client
11
11
  (`Woku`) and an asynchronous twin (`AsyncWoku`), typed request models, automatic
12
- retries, idempotent creates and auto-pagination. It is the counterpart of the
12
+ protected write retries and pagination. It is the counterpart of the
13
13
  JavaScript SDK (`@wokuapp/sdk`), with the same surface.
14
14
 
15
15
  **Server-only.** The company secret key grants full management access. Keep it on
@@ -35,8 +35,9 @@ woku = Woku(api_key="sk_...") # or set WOKU_API_KEY and call Woku()
35
35
 
36
36
  ## Core operations
37
37
 
38
- Creates are idempotent (auto `Idempotency-Key`); actions (send, test, reply) are
39
- never auto-retried.
38
+ GETs and protected writes retry with a stable key: tracker/VoC definitions,
39
+ invitations, and journey create/enroll/stop/mint-URL/event operations. Other writes
40
+ and uploads are attempted once. A key alone does not make a write idempotent.
40
41
 
41
42
  ```python
42
43
  # Tracker definitions and values (wire your CRM/ERP ids to feedback tools).
@@ -45,7 +46,8 @@ woku.trackers.assign_to_woku("woku_123", {"name": "Store #1", "value": "TX-42"})
45
46
 
46
47
  # VoC tools: nps_tools / csat_tools / ces_tools (create/list/get/update/delete).
47
48
  tool = woku.nps_tools.create(
48
- {"name": "Post-purchase", "npsMessage": "How likely are you to recommend us?"}
49
+ {"name": "Post-purchase", "npsMessage": "our company",
50
+ "audienceType": "a friend or colleague"}
49
51
  )
50
52
 
51
53
  # Send a survey. IMPORTANT: `channel` is required and `recipients` is a list of
@@ -71,7 +73,7 @@ woku.action_plans.complete("plan_123")
71
73
  Namespaces: `trackers`, `nps_tools` / `csat_tools` / `ces_tools`, `nps` / `csat`
72
74
  / `ces`, `wokus`, `forms`, `flows`, `action_plans`, `action_plan_groups`,
73
75
  `tickets`, `ticket_destinations`, `dispatches`, `reports`, `company`,
74
- `quarantines`.
76
+ `quarantines`, `folders`, `tools`, `journey_folders`.
75
77
 
76
78
  ## Async
77
79
 
@@ -113,6 +115,77 @@ the key.
113
115
  ## When to reach for the reference
114
116
 
115
117
  For the full method list, request/response shapes and per-call options, point the
116
- user to the SDK page at https://docs.woku.app/development/sdk-python and the API
117
- reference at https://docs.woku.app/development/api. There is an equivalent
118
+ user to the SDK page at https://woku.app/docs/en/development/sdk-python and the API
119
+ reference at https://woku.app/docs/en/development/api. There is an equivalent
118
120
  JavaScript SDK (`@wokuapp/sdk`) documented at /development/sdk-javascript.
121
+
122
+ ## Folders and tools
123
+
124
+ One folder tree holds wokus and NPS, CSAT and CES tools. Needs the SDK release that ships `folders` and `tools`; verify the installed version.
125
+
126
+ ```python
127
+ folder = woku.folders.create({"name": "Post-sale"})
128
+ woku.csat_tools.create({"name": "Delivery", "question": "How satisfied are you?", "folderId": folder["id"]})
129
+
130
+ for tool in woku.tools.list({"folderId": folder["id"], "types": ["csat", "nps"]}):
131
+ print(tool["type"], tool["name"], tool["headline"]["value"])
132
+ stats = woku.tools.stats({"folderId": folder["id"]}) # native scales, never averaged across types
133
+ tagged = woku.tools.list({"trackers": ["TRR:00482"]}) # tracker chips "name:value", company-wide
134
+ metrics = woku.folders.metrics(folder["id"], {"days": 30}) # per tool, period vs the previous one; 0 = all history
135
+ woku.tools.move({"items": [{"type": "csat", "id": tool_id}], "folderId": None}) # None = root
136
+ csv_text = woku.folders.csv(folder["id"])
137
+ pdf_bytes = woku.folders.pdf(folder["id"], {"lang": "en"}) # folder report as PDF bytes
138
+ woku.folders.delete(folder["id"]) # content moves up to the parent, nothing is deleted
139
+ ```
140
+
141
+ Journeys in folders: `woku.journey_folders.status()` and `woku.journey_folders.organize()` (background pass, `ConflictError` while running); `journeys.get` returns `folderId` and `momentFolders`, and folders expose `origin`.
142
+
143
+ `folders`: `list`, `get`, `create`, `update`, `move`, `delete`, `report`, `csv`, `pdf`. `tools`: `list` (iterates across cursor pages; `foldersLimit` pages the folders with `has_more_folders()` / `get_more_folders()`), `stats`, `move`. `nps_tools` / `csat_tools` / `ces_tools` accept `folderId` on `create` and have `move(tool_id, {"folderId": ...})`. `AsyncWoku` mirrors all of it.
144
+
145
+ ## Flows
146
+
147
+ ```python
148
+ flow = woku.flows.create({
149
+ "name": "Post-sale",
150
+ "steps": [{"type": "nps", "toolId": nps_tool_id}, {"type": "csat", "toolId": csat_tool_id}, {"type": "woku", "toolId": woku_id}],
151
+ })
152
+ woku.flows.update(flow["_id"], {"steps": [{"type": "csat", "toolId": csat_tool_id}]})
153
+ woku.flows.delete(flow["_id"]) # its tools and responses stay
154
+ ```
155
+
156
+ `flows`: `list`, `get`, `create`, `update`, `delete`. 1 to 20 steps, each tool once; for an `nps` step the company id as `toolId` is the company-level NPS. `AsyncWoku` mirrors it. Needs the SDK release that ships flow writes.
157
+
158
+ ## Customer journeys and media
159
+
160
+ Prefer an actual journey when the task coordinates several business moments.
161
+ One moment has one tool: several facets use Woku, satisfaction CSAT, effort CES,
162
+ recommendation NPS. A separate loyalty intention can add a moment; several facets
163
+ of delivery must not become several delivery moments. Journey response tools are
164
+ identified. Operator sends start immediately; opening a QR/link waits for a saved
165
+ first response. Later moments wait or use their webhook, optionally with a backup.
166
+ Default wait is ten days; zero means one hour. Keep reminders enabled unless asked.
167
+
168
+ The SDK exposes 17 journey methods, plus lazy enrollment iteration. Public cursor
169
+ pages allow 100 items (default 20); the Admin page endpoint is separate and uses 50.
170
+ Use the exact enrollment id to stop one case. Editing creates a new definition
171
+ version; running cases keep their snapshot. A cycle finishes on its last response
172
+ or 30 days from the first send of the last moment.
173
+
174
+ Media uploads use multipart and return fileId for moment.toolSpec.fileId. They do
175
+ not retry automatically; 413 is PayloadTooLargeError. Company keys remain on the
176
+ backend; minted webhook URLs use a separate HTTP transport without that key.
177
+ Keep request/idempotency ids stable during uncertain retries. Deduplication lasts
178
+ 24 hours; inspect the outcome before submitting with a new key.
179
+
180
+ Journey and media methods require SDK version 0.3.0 or later. Verify the installed
181
+ version and changelog when upgrading an existing integration.
182
+
183
+ ```python
184
+ with open("delivery.jpg", "rb") as image:
185
+ media = woku.media.upload(image, filename="delivery.jpg", content_type="image/jpeg")
186
+ for enrollment in woku.journeys.iter_enrollments(journey_id, {"limit": 100}):
187
+ print(enrollment["id"], enrollment["lifecycle"])
188
+ woku.journeys.preview_moment(journey_id, "delivery", {"order": "case-123", "late": True})
189
+ ```
190
+
191
+ AsyncWoku provides the corresponding awaitable methods and async iterators.