Customer Data API — Developer Documentation
Overview
The Walnut Customer Data API gives you programmatic, self-service access to your demo analytics data. Query session-level insights, retrieve engagement metrics, and feed data directly into your CRM, BI tools, internal dashboards, or AI-powered workflows.
The API exposes demo session data, playlist session data, deal room session data, library metadata, per-user activity data, and company seat utilization. The same reads are also available as tools on Walnut's MCP server, so MCP-connected AI clients can pull them directly.
Key Capabilities
- Query individual demo sessions with filtering, pagination, and field selection
- Aggregate session data by date, user type, viewer type, demo, or embed status
- Retrieve pre-built analytics summaries with totals, averages, and top-10 breakdowns
- Integrate demo data into any system that can make HTTP requests
Authentication
All API requests (except the health check endpoint) require authentication via an API key passed in the x-api-key request header.
Making an Authenticated Request
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?limit=10>"
⚠️ You generate and manage your own API key from the Walnut API card on the Integrations page. See Managing your API key. The key is shown exactly once, when you generate it, and can't be recovered if you lose it. Store it somewhere safe.
Managing your API key
API keys are self-serve. You don't need to contact your Walnut account team to get one.
- Go to the Integrations page and open the Walnut API card.
- Click Generate API key.
- Copy the key from the Your API key was created dialog. For your security, it won't be shown again.
Things to know:
- Keys are per-member and member-bound. Any signed-in member can generate a key, and each member has at most one active key. The analytics and user-management endpoints (
/demo-sessions,/demo-sessions/summary,/playlist-sessions,/playlist-sessions/content-items,/deal-room-sessions,/deal-room-sessions/content-items,/users,/seats,/library) require the key's member to be an account owner or company admin — a key minted by an editor, presenter, or viewer will authenticate but return403 Forbiddenon these routes. - Generating a new key revokes your previous one. Use this if you lose your key or need to rotate it.
- Click Revoke on the card to revoke your key. Any client still using it stops working.
- Keys act with your company's permissions, so every key reads data for your whole company. Keep it secret.
- The API is available on Enterprise plans. If the card shows Available on Enterprise plans, contact your account team to enable the API for your company.
Rate Limits
The API enforces the following rate limits per API key:
| Limit | Value |
|---|---|
| Sustained throughput | 50 requests/second |
| Burst allowance | 100 requests/second |
| Max rows per request | 1,000 |
Requests exceeding the rate limit will receive a 429 Too Many Requests response. Implement exponential backoff in your integration.
Endpoints
| Path | Method | Auth | Description |
|---|---|---|---|
/health | GET | None | Health check |
/demo-sessions | GET | x-api-key | Query demo sessions with filtering, pagination, field selection, and aggregation |
/demo-sessions/summary | GET | x-api-key | Pre-built analytics summary (totals, averages, top demos, top countries) |
/users | GET | x-api-key | Per-user activity for your company: email, role, last login, and creation counts (demos, templates, playlists) over a date range. Paginated. |
/seats | GET | x-api-key | Company-wide seat utilization: total, used, remaining, and pending_invites, plus an optional per-role breakdown for plans that enforce seats per role |
/library | GET | x-api-key | Company-wide library metadata — demos, templates, playlists, deal rooms, and folders — in a single paginated read. The MCP library tools return the same data scoped to the calling member; this endpoint returns everything the company owns. Must be enabled for the API key by your Walnut account team. |
/playlist-sessions | GET | x-api-key | Playlist viewing sessions, with the same filtering, pagination, field-selection, and aggregation controls as /demo-sessions. |
/playlist-sessions/content-items | GET | x-api-key | Per-content-item engagement inside playlist sessions (which demos, pages, or sections a viewer opened and for how long). |
/deal-room-sessions | GET | x-api-key | Deal Room viewing sessions, mirroring /playlist-sessions. |
/deal-room-sessions/content-items | GET | x-api-key | Per-content-item engagement inside Deal Room sessions. |
GET /demo-sessions
Retrieve demo session records with support for filtering, pagination, field selection, and aggregation.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
fields | string | (all fields) | Comma-separated list of fields to return |
limit | integer | 100 | Max rows to return (maximum: 1,000) |
offset | integer | 0 | Pagination offset |
start_date | YYYY-MM-DD | (none) | Include sessions from this date (inclusive) |
end_date | YYYY-MM-DD | (none) | Include sessions up to this date (inclusive) |
user_type | string | all | Filter by user type: "external", "internal", or "all" |
demo_id | UUID | (none) | Filter sessions for a specific demo |
group_by | string | (none) | Aggregate results by: date, user_type, viewer_type, demo_id, is_embed , demo_name |
is_bounced | boolean | (none) | Filter by bounce state: "true" or "false" |
is_embed | boolean | (none) | Filter by embedded sessions: "true" or "false" |
Available Fields (29)
Use the fields parameter to select only the data you need. If omitted, all fields are returned.
| Category | Fields |
|---|---|
| Identifiers | id, demo_id, company_id |
| Classification | viewer_type, user_type |
| Timing | started_at, finished_at |
| Session State | is_bounced, is_completed, is_embed, is_offline |
| Engagement | interaction_count, screen_views_count, annotation_views_count, guide_views_count |
| Geography | geo_country_code, geo_country_name, geo_city |
| Context | origin_url, demo_owner_name, demo_name |
| Lead Form | lead_form_exists, lead_form_opened, lead_form_opened_at, lead_form_skipped, lead_form_skipped_at, lead_form_submitted, lead_form_submitted_at |
| Gates | email_gate_exists, access_gate_exists |
| Viewer identifications | user_email, user_anonymous_id |
Aggregation
Pass one or more dimensions to group_by (comma-separated) to receive aggregated counts instead of individual session records. For example, group_by=date,user_type returns session counts grouped by both date and user type.
Response Schema
Standard response (individual sessions):
{
"data": [
{
"id": "7b4ab219-ab64-4ae5-8a96-601237c212c1",
"demo_id": "bacdb032-c3a2-4a38-9b85-a45a5e3639f8",
"company_id": "3003886f-9618-46b9-9baf-dcbba56a891a",
"viewer_type": "prospect",
"user_type": "external",
"started_at": "2026-03-08T10:37:25.286Z",
"finished_at": null,
"is_bounced": false,
"is_completed": false,
"interaction_count": 0,
"screen_views_count": 1,
"geo_country_code": "USA",
"geo_country_name": "United States",
"geo_city": "Dallas",
"is_embed": true,
"is_offline": false,
"origin_url": "<https://app.teamwalnut.com/player/>...",
"demo_owner_name": "Jane Smith",
"lead_form_exists": false,
"lead_form_opened": false,
"lead_form_opened_at": null,
"lead_form_skipped": false,
"lead_form_skipped_at": null,
"lead_form_submitted": false,
"lead_form_submitted_at": null,
"email_gate_exists": false,
"access_gate_exists": false,
"annotation_views_count": 1,
"guide_views_count": 1,
"demo_name": "Product Overview Demo"
}
],
"count": 1,
"total": 253852,
"limit": 1,
"offset": 0
}
count= rows returned in this response page.total= total matching rows across all pages. Use these for pagination logic.
Single-dimension aggregation (group_by=date):
{
"data": {
"2026-03-01": 669,
"2026-03-02": 822,
"2026-03-03": 471
},
"total": 1962,
"group_by": ["date"]
}
Multi-dimension aggregation (group_by=date,user_type):
{
"data": {
"2026-03-01|external": 669,
"2026-03-02|external": 820,
"2026-03-02|internal": 2,
"2026-03-03|external": 471
},
"total": 1962,
"group_by": ["date", "user_type"]
}
Composite keys use the
|(pipe) delimiter. Dimensions with zero sessions are omitted from the response — absence means zero.
Sort Order
Results are returned newest-first (descending by started_at). There is currently no parameter to change sort order.
Field Types, Values & Definitions
Every field returned by /demo-sessions is documented below with its data type, possible values, and what it means in the context of Walnut demo analytics.
| Field | Type | Values / Format | Definition |
|---|---|---|---|
id | UUID | "7b4ab219-ab64-..." | Unique session identifier |
demo_id | UUID | "bacdb032-c3a2-..." | The demo that was viewed |
company_id | UUID | "3003886f-9618-..." | Your Walnut company/account ID |
viewer_type | string | "prospect" | "owner" |
user_type | string | "external" | "internal" |
started_at | ISO 8601 | "2026-03-08T10:37:25.286Z" | When the session began (always present) |
finished_at | ISO 8601 or null | "2026-03-08T10:42:00.000Z" or null | When the session ended. null means the session is still open or was abandoned without a completion event. |
is_bounced | boolean | true / false | The viewer exited after the first screen with no further interaction. Use bounce rate (bounced / total) to measure first-screen effectiveness and gating friction. |
is_completed | boolean | true / false | The viewer reached the end of the demo flow (viewed all screens). Use completion rate (completed / total) to measure narrative quality and content stickiness. |
is_embed | boolean | true / false | true = demo was viewed inside an embedded iframe (e.g., on your website). false = viewed via direct link or Walnut player. |
is_offline | boolean | true / false | Whether the session was an offline/downloaded demo view |
interaction_count | integer | 0+ | Total interactive clicks during the session — includes FAB (Floating Action Button) clicks, annotation clicks, and guide step advances. A proxy for engagement depth. |
screen_views_count | integer | 0+ | Number of demo screens viewed in the session. Compare to total screens in the demo to calculate screens viewed (%). |
annotation_views_count | integer | 0+ | Number of annotation overlays (tooltips, modals, highlights on screens) the viewer saw. Annotations are the individual visual elements placed on screens to explain features. |
guide_views_count | integer | 0+ | Number of guide chapters (not individual steps) viewed. Guides are the structured narrative flows that walk viewers through a demo story. Measured at chapter level, not step level. |
geo_country_code | string | "USA", "GBR", etc. | ISO 3166-1 alpha-3 country code based on viewer IP |
geo_country_name | string | "United States" | Full country name |
geo_city | string or null | "Dallas" or null | City based on IP geolocation. null when unavailable. |
origin_url | string | Full URL | The URL where the demo was loaded from (Walnut player URL, or the page where the embed lives) |
demo_owner_name | string | Display name | The Walnut team member who owns/created this demo |
demo_name | string | Demo title | The name of the demo as set in the Walnut builder |
lead_form_exists | boolean | true / false | Whether this demo has a lead form configured |
lead_form_opened | boolean | true / false | Whether the lead form was displayed to the viewer |
lead_form_opened_at | ISO 8601 or null | Timestamp or null | When the lead form was displayed |
lead_form_skipped | boolean | true / false | Whether the viewer dismissed the form without submitting |
lead_form_skipped_at | ISO 8601 or null | Timestamp or null | When the form was skipped |
lead_form_submitted | boolean | true / false | Whether the viewer submitted the lead form. Calculate lead form conversion as submitted / opened. |
lead_form_submitted_at | ISO 8601 or null | Timestamp or null | When the form was submitted |
email_gate_exists | boolean | true / false | Whether this demo requires an email gate (viewer must enter email before accessing the demo) |
access_gate_exists | boolean | true / false | Whether this demo has an access gate (password or approval required) |
GET /demo-sessions/summary
Returns a pre-built analytics summary with 7 parallel aggregations, giving you a comprehensive snapshot of your demo performance.
Summary Includes
- Period — the date range covered (auto-scopes to last 12 months if no date filters provided)
- Totals — sessions, completed, bounced
- Averages — duration (seconds), interactions, screen views
- By user type — count distribution across user types (
external,internal) - By viewer type — count distribution across viewer types (
prospect,owner,colleague_member,colleague_non_member) - By embed status —
embeddedvs.directsession counts - Top 10 demos — ranked by session count (includes
demo_id,demo_name,sessions) - Top 10 countries — ranked by session count (includes
country,sessions)
Optional Filters
The summary endpoint accepts start_date and end_date query parameters to scope the summary to a specific date range. When omitted, defaults to the last 12 months.
Response Schema
{
"period": {
"start": "2025-03-08",
"end": "2026-03-08"
},
"totals": {
"sessions": 253852,
"completed": 253835,
"bounced": 218118
},
"averages": {
"duration_seconds": 21,
"interactions": 0.4,
"screen_views": 1.7
},
"by_user_type": {
"external": 245083,
"internal": 8769
},
"by_viewer_type": {
"colleague_member": 5298,
"colleague_non_member": 811,
"owner": 2660,
"prospect": 245083
},
"by_embed": {
"direct": 24589,
"embedded": 229263
},
"top_demos": [
{
"demo_id": "4c1e1a49-ba4d-4951-9f6a-6005648e8eea",
"demo_name": "Product Overview Demo",
"sessions": 31668
}
],
"top_countries": [
{
"country": "United States",
"sessions": 107132
}
]
}
Note:
averages.duration_secondsis an integer.averages.interactionsandaverages.screen_viewsare floats.
GET /users
Retrieve per-user activity for your company. For each active member, the response returns their email, role, last browser-session login timestamp, and the number of Demos, Templates, and Playlists they created within the requested date window.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
start_date | YYYY-MM-DD | 90 days before today (UTC) | Inclusive start of the date window for creation counts |
end_date | YYYY-MM-DD | Today (UTC) | Inclusive end of the date window for creation counts |
limit | integer | 100 | Max rows to return. Values above 1,000 are clamped to 1,000 rather than rejected. |
offset | integer | 0 | Rows to skip, for pagination |
start_date and end_date use the same naming and inclusive semantics as /demo-sessions. Creation counts include only non-archived Demos, Templates (Storylines), and Playlists created within [start_date, end_date].
Response Schema
{
"data": [
{
"email": "jane.smith@example.com",
"role": "editor",
"last_login_at": "2026-03-08T10:37:25.286Z",
"creation_counts": {
"demo": 12,
"template": 3,
"playlist": 1
}
}
],
"count": 1,
"total": 42,
"limit": 100,
"offset": 0
}
Field Definitions
| Field | Type | Definition |
|---|---|---|
email | string | The member's email address |
role | string | One of account_owner, company_admin, editor, presenter, viewer |
last_login_at | ISO 8601 or null | The member's most recent authenticated browser session. null if they have never signed in via a browser. Reflects browser session logins only — activity via API keys or MCP bearer tokens is not counted. |
creation_counts.demo | integer | Number of Demos the member created within the window |
creation_counts.template | integer | Number of Templates (Storylines) the member created within the window |
creation_counts.playlist | integer | Number of Playlists (Choose Your Own Adventure, QBR, Product Gallery layouts) the member created within the window. Deal Rooms do not count toward this total. |
count | integer | Number of members returned in data (length of this page) |
total | integer | Total active members for the company, across all pages |
limit | integer | The limit used for this response |
offset | integer | The offset used for this response |
Scope
Only active members of the authenticated company are returned. For companies whose email domain is not walnut.io, any @walnut.io members (typically Walnut support users added to the account) are excluded from the response.
Example
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.teamwalnut.com/api/v1/users?start_date=2026-01-01&end_date=2026-03-31"
GET /library
List every Template, Demo, Playlist, Deal room and Deal room template in your company — company-wide, in a single paginated read. Unlike the MCP library search (which is scoped to what the calling member can see), this REST endpoint returns everything the company owns, including items inside private folders.
The endpoint is gated by a Walnut-managed entitlement in addition to the usual API key auth. If it is not enabled for your API key, every request returns 403 Forbidden with {"error": "Forbidden", "message": "The library endpoint is not enabled for this API key."}. Contact your Walnut account team to enable it.
The API key must belong to an account owner or company admin. Keys minted by editors, presenters, or viewers authenticate but return 403 Forbidden.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
item_types | string | all five | Comma-separated list of item types to include: template, demo, playlist, deal_room, deal_room_template |
item_ids | string | (none) | Comma-separated list of specific item UUIDs to return (max 500) |
owner_ids | string | (none) | Comma-separated list of member UUIDs; return only items owned by these members |
folder_id | UUID | (none) | Return items directly inside this folder |
folder_subtree_id | UUID | (none) | Return items anywhere inside this folder's subtree |
tags | string | (none) | Comma-separated list of tag names; items must carry every listed tag |
name | string | (none) | Case-insensitive substring match on the item's name |
layout | string | (none) | Narrow Playlists by layout: Choose Your Own Adventure, Content Hub, or Customer Hub |
archived | boolean | false | true returns archived items instead of live ones |
created_at_from / created_at_to | ISO 8601 | (none) | Bound creation time |
updated_at_from / updated_at_to | ISO 8601 | (none) | Bound last-updated time |
last_played_from / last_played_to | ISO 8601 | (none) | Bound last-played time (Demos only) |
fields | string | (all row fields) | Comma-separated list of fields to return |
limit | integer | 100 | Max rows to return (clamped to 1,000) |
offset | integer | 0 | Pagination offset |
Available Fields
If fields is omitted, every row field below is returned. Pass a comma-separated subset to narrow the response.
| Field | Type | Definition |
|---|---|---|
item_id | UUID | The item's identifier |
item_type | string | template, demo, playlist, deal_room, or deal_room_template |
name | string | The item's name as shown in the library |
owner | object or null | { member_id, name, email }, or null for an ownerless item |
folder_path | string[] | Root-to-leaf names of the folder the item lives in; [] for an item at the library root |
tags | string[] | Tag names applied to the item |
updated_at | ISO 8601 | When the item was last updated |
inserted_at | ISO 8601 | When the item was created |
last_played | ISO 8601 or null | Last viewer session timestamp (Demos only; null for other item types) |
deal_connection | object or null | { crm, deal_external_id } for a Playlist/Deal room linked to a CRM deal; null otherwise |
sharing | object | The item's current sharing/visibility state |
Response Schema
{
"data": [
{
"item_id": "bacdb032-c3a2-4a38-9b85-a45a5e3639f8",
"item_type": "demo",
"name": "Acme — Product Overview",
"owner": {
"member_id": "7b4ab219-ab64-4ae5-8a96-601237c212c1",
"name": "Jane Smith",
"email": "jane.smith@example.com"
},
"folder_path": ["Sales", "Enterprise"],
"tags": ["q4", "enterprise"],
"updated_at": "2026-03-08T10:37:25.286Z",
"inserted_at": "2026-02-14T09:12:03.112Z",
"last_played": "2026-03-10T18:22:00.000Z",
"deal_connection": null,
"sharing": { "visibility": "private" }
}
],
"count": 1,
"total": 1284,
"limit": 100,
"offset": 0
}
Example
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.teamwalnut.com/api/v1/library?item_types=template,demo&limit=50"
Examples
All examples use the production base URL. Replace YOUR_API_KEY with the key you generated from the Walnut API card on the Integrations page.
Health Check (no authentication required)
curl <https://api.teamwalnut.com/api/v1/health>
Response:
{ "status": "ok" }
Retrieve Last 10 Sessions
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?limit=10>"
Filter by Date Range and User Type
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?start_date=2025-01-01&end_date=2025-12-31&user_type=external&limit=50>"
Select Specific Fields
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?fields=id,demo_id,started_at,is_completed,user_type&limit=20>"
Aggregate by Date
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?start_date=2025-01-01&group_by=date>"
Multi-Dimensional Aggregation
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?group_by=date,user_type>"
Analytics Summary
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions/summary>"
Summary with Date Filter
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions/summary?start_date=2025-01-01>"
Filter by Specific Demo
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?demo_id=YOUR_DEMO_UUID&limit=100>"
Pagination
The /demo-sessions endpoint returns up to limit rows per request (default 100; maximum 1,000). Use the offset parameter to paginate through larger datasets.
Example: Paginating Through Results
# Page 1 (rows 0-99)
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?limit=1000&offset=0>"
# Page 2 (rows 100-199)
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?limit=1000&offset=1000>"
# Page 3 (rows 200-299)
curl -H "x-api-key: YOUR_API_KEY" \\
"<https://api.teamwalnut.com/api/v1/demo-sessions?limit=1000&offset=2000>"
Continue incrementing offset by your limit value until fewer rows than limit are returned, indicating you have reached the end of the dataset.
Error Handling
The API uses standard HTTP status codes. Error responses return a JSON body with a descriptive message.
| Status Code | Meaning | Common Cause |
|---|---|---|
| 200 | Success | Request completed successfully |
| 400 | Bad Request | Invalid date format, unknown field name, or malformed parameter |
| 401 | Unauthorized | Missing or invalid API key |
| 429 | Too Many Requests | Rate limit exceeded; retry with exponential backoff |
| 500 | Internal Server Error | Unexpected server issue; contact support if persistent |
Error response body:
{ "error": "Invalid fields requested" }
ℹ️ Error responses never expose internal details. If you receive a 500 error consistently, contact your Walnut account team with the request URL and timestamp.
What Can You Do With This Data?
The fields returned by the API map directly to actionable metrics. Here are recipes your team can implement immediately.
Key Metrics You Can Calculate
| Metric | Formula | Why It Matters |
|---|---|---|
| Bounce Rate | is_bounced=true count / total sessions | Measures first-screen effectiveness. High bounce = weak opener or too-early gating. |
| Completion Rate | is_completed=true count / total sessions | Measures narrative quality. Higher completion = story resonates and holds attention. |
| Lead Form Conversion | lead_form_submitted / lead_form_opened | Is your form friction too high? Low conversion suggests the form appears too early or asks too much. |
| Engagement Depth | interaction_count • screen_views_count per session | Are prospects exploring or skimming? Higher depth = stronger buying intent. |
| Internal vs External Split | Filter by user_type | High internal usage may mean reps are previewing, not sending to prospects. Track the ratio over time. |
| Embed Performance | Compare is_embed=true vs false sessions | Are website embeds converting better than direct links? Optimize placement accordingly. |
| Identification Coverage | Sessions with email_gate_exists=true or lead_form_exists=true / total | The more viewers you can identify, the more complete your attribution picture becomes. Aim for 70–80% coverage. |
| Top Demos by Engagement | Sort by avg interaction_count, not just session count | Volume ≠ quality. A demo with fewer sessions but high interaction may be your best closer. |
Common Integration Patterns
- CRM sync: Pull sessions daily, match
origin_urlor lead form data to opportunities in Salesforce/HubSpot. Usedemo_nameanddemo_owner_namefor attribution. - BI dashboards: Use
group_by=datefor trend charts,/demo-sessions/summaryfor executive snapshots. Theperiodobject tells you the exact date range covered. - Hot lead alerts: Poll for sessions where
is_completed=trueANDinteraction_count > 5to notify sales of high-intent viewers. - Re-engagement triggers: Flag open deals where recent sessions show
is_bounced=true— send a shorter, more targeted demo or playlist. - Embed optimization: Compare
by_embeddata in the summary to decide whether to invest in more website embeds or direct-link campaigns. - Pagination loop: Increment
offsetby yourlimitvalue untilcount \< limit, indicating you’ve reached the end of the dataset.
Current Limitations
This is the initial release of the Customer Data API. Please note the following current constraints:
- Read-only access: the API supports data retrieval only; there are no write endpoints.
- Maximum of 1,000 rows per request. Use pagination for larger datasets.
- Offset-based pagination only. There is no cursor-based pagination. For very large datasets, offset pagination may slow down at high offsets.
- API key changes (including revocations) may take up to 5 minutes to take effect due to authorization caching.
- Plaintext key shown once. The full API key is shown only when you generate it. If you lose it, generate a new key from the Walnut API card on the Integrations page. This revokes your previous key.
- One active key per member. Each member can hold one active key. Generating a new key revokes only your own previous key, not your teammates' keys.
- Reads only. The API supports data retrieval only; there are no write endpoints. Writes are available on the MCP server (
/mcp). - Fixed sort order. Results are always returned newest-first by
started_at. Custom sorting is not yet supported. - Summary auto-scopes to 12 months. When no
start_date/end_dateis provided,/demo-sessions/summarydefaults to the last 12 months.
Support
If you need assistance with the Customer Data API, your Walnut account team is here to help.
- API key management: Generate and revoke your own API key from the Walnut API card on the Integrations page. See Managing your API key. Contact your account representative only if you need the API enabled for your company or need to troubleshoot an entitlement issue.
- Technical issues: Include the request URL, timestamp, and HTTP status code when reporting problems.
- Feature requests: Let your account team know what additional data or capabilities would be valuable for your use case.