The complete reference for the Guidez REST API, JavaScript SDK, CLI, and MCP server. Build programmatic onboarding flows, identify users, track analytics, and automate everything.
The Guidez API is organized around REST. All requests must be made over HTTPS. Responses are returned as JSON. We also offer a native JavaScript SDK, a CLI for terminal workflows, and an MCP server so Claude, Cursor, and Windsurf can call Guidez tools natively.
https://api.guidez.io/v1 — All REST endpoints are prefixed with this URL.Guidez content (tours, checklists, banners, NPS surveys) is unified under the /v1/content resource. Filter by type to work with specific content types.
# REST API base https://api.guidez.io/v1 # JavaScript SDK npm install @guidez/sdk # CLI npm install -g @guidez/cli # MCP Server npm install @guidez/mcp
// JavaScript / TypeScript import Guidez from '@guidez/sdk'; # Python (pip) pip install guidez-sdk # Ruby (gem) gem install guidez # Go go get github.com/guidez/guidez-go
Get from zero to your first user identified and tour triggered in five steps.
Go to Dashboard → Settings → Environments → API Keys. Create a secret key. It looks like env_live_xxxxxxxx. Store it securely — never expose it in client-side code.
Also on the Environments page, copy your Environment ID. It looks like cm9cs634h00001mp50l45n7kz. Pass it as the x-environment-id header with every request.
Call POST /v1/users with the user's external ID from your database. You can include attributes like name and email for targeting.
Add @guidez/sdk to your frontend. Call Guidez.identify() on sign-in. Guidez will automatically evaluate targeting rules and show the right content.
Query GET /v1/content-sessions or open the Dashboard → Analytics to see real-time completion data.
# 1. Identify a user curl -X POST https://api.guidez.io/v1/users \ -H "Authorization: Bearer env_live_xxxx" \ -H "x-environment-id: cm9cs634h..." \ -H "Content-Type: application/json" \ -d '{ "id": "user_123", "attributes": { "name": "Jane Smith", "email": "jane@acme.com", "plan": "pro" } }' # 2. List content to find tour ID curl https://api.guidez.io/v1/content \ -H "Authorization: Bearer env_live_xxxx" \ -H "x-environment-id: cm9cs634h..."
const headers = { 'Authorization': 'Bearer env_live_xxxx', 'x-environment-id': 'cm9cs634h...', 'Content-Type': 'application/json', }; // 1. Identify a user await fetch('https://api.guidez.io/v1/users', { method: 'POST', headers, body: JSON.stringify({ id: 'user_123', attributes: { name: 'Jane Smith', email: 'jane@acme.com' } }) }); // 2. List content const content = await fetch( 'https://api.guidez.io/v1/content', { headers } ).then(r => r.json());
import requests headers = { "Authorization": "Bearer env_live_xxxx", "x-environment-id": "cm9cs634h...", } # 1. Identify a user requests.post( "https://api.guidez.io/v1/users", headers=headers, json={ "id": "user_123", "attributes": {"name": "Jane Smith"} } ) # 2. List content resp = requests.get( "https://api.guidez.io/v1/content", headers=headers ) content = resp.json()
Guidez uses Bearer token authentication. Pass your API key in the Authorization header with every request.
| Type | Prefix | Use case |
|---|---|---|
| Secret key | env_live_ | Server-side API calls only. Full read/write access. Never expose in browsers or mobile apps. |
| Test key | env_test_ | Development & staging. Same permissions but operates against your test environment. |
Every request must also include the environment ID header. This scopes all data to a specific environment (production, staging, development).
Rotate keys any time from Dashboard → Settings → Environments → API Keys. Old keys are invalidated immediately. Keep your keys in environment variables or a secrets manager — never hardcode them.
curl https://api.guidez.io/v1/users \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const BASE = 'https://api.guidez.io/v1'; const headers = { 'Authorization': `Bearer ${process.env.GUIDEZ_API_KEY}`, 'x-environment-id': process.env.GUIDEZ_ENV_ID, }; const res = await fetch(`${BASE}/users`, { headers }); const data = await res.json();
import os, requests headers = { "Authorization": f"Bearer {os.environ['GUIDEZ_API_KEY']}", "x-environment-id": os.environ["GUIDEZ_ENV_ID"], } resp = requests.get( "https://api.guidez.io/v1/users", headers=headers )
{
"statusCode": 401,
"message": "Unauthorized",
"error": "Invalid or missing API key"
}Environments are isolated namespaces within a project. Most teams have at least Production and Development environments. Users, companies, content, and sessions are completely separate between environments.
Your environment ID is visible in the Dashboard under Settings → Environments. It's a unique string like cm9cs634h00001mp50l45n7kz.
You can have up to 3 environments on the Growth plan, and unlimited on Business. Use separate environments for dev, staging, and production to avoid polluting real user data with test sessions.
API keys are scoped to a single environment. A production API key will only return production data, even if you pass a staging environment ID in the header.
GUIDEZ_API_KEY and GUIDEZ_ENV_ID in your environment variables and never hardcode them. The CLI and MCP server both read these automatically.# Production curl https://api.guidez.io/v1/content \ -H "Authorization: Bearer env_live_sk_prod_xxx" \ -H "x-environment-id: prod_env_id_here" # Development (separate data) curl https://api.guidez.io/v1/content \ -H "Authorization: Bearer env_test_sk_dev_xxx" \ -H "x-environment-id: dev_env_id_here"
# .env (never commit this)
GUIDEZ_API_KEY=env_live_sk_xxxxxxxxxxxxxxxx
GUIDEZ_ENV_ID=cm9cs634h00001mp50l45n7kz
GUIDEZ_BASE_URL=https://api.guidez.ioUnderstanding the Guidez data model makes working with the API intuitive.
A person using your product, identified by their external ID from your database. Users have attributes (name, plan, etc.) used for targeting.
A group or account that users belong to (B2B use case). Companies have their own attributes and memberships linking users.
A tour, checklist, banner, or NPS survey. Content has versions — a published version served to users and an edited draft. Filtered by type.
One user's interaction with one piece of content. Created automatically when a user starts a tour. Records step completions, answers, and timestamps.
The schema for a custom attribute on users or companies. Defines the name, type (string/number/boolean/date), and which object it belongs to.
A named event that can be tracked on users (e.g., file_uploaded, invite_sent). Used for targeting rules in tours.
Users and companies are created or updated in a single POST call using their external id. If the record doesn't exist it's created; if it does, the provided attributes are merged (not replaced). This makes it safe to call on every sign-in.
// User with company membership { "id": "user_123", "externalId": "user_123", "attributes": { "name": "Jane Smith", "email": "jane@acme.com", "plan": "pro" }, "memberships": [{ "company": { "id": "acme", "attributes": { "name": "Acme Inc." } } }], "createdAt": "2026-01-15T09:30:00Z" } // Content session { "id": "cs_abc123", "contentId": "cnt_xyz789", "userId": "user_123", "state": "completed", "completedAt": "2026-01-15T09:35:00Z" }
Guidez uses conventional HTTP response codes. Codes in the 2xx range indicate success. 4xx codes indicate a client error. 5xx codes indicate a server error (rare).
| Code | Meaning |
|---|---|
| 200 OK | Request succeeded. Response body contains the resource. |
| 201 Created | Resource was created successfully. |
| 204 No Content | Request succeeded with no response body (DELETE). |
| 400 Bad Request | Missing or invalid parameters. Check the message field for details. |
| 401 Unauthorized | Missing or invalid API key. Check your Authorization header. |
| 403 Forbidden | Valid key but insufficient permissions for this operation. |
| 404 Not Found | The requested resource does not exist in this environment. |
| 409 Conflict | The request conflicts with an existing resource. |
| 422 Unprocessable | Validation failed. The errors array lists field-level issues. |
| 429 Too Many Requests | Rate limit exceeded. See the Retry-After header. |
| 500 Server Error | Something went wrong on our end. Retry with exponential backoff. |
All errors return a JSON body with at least statusCode and message. Validation errors include an errors array.
// 400 Bad Request { "statusCode": 400, "message": "Validation failed", "errors": [ { "field": "id", "message": "id must be a string" } ] } // 404 Not Found { "statusCode": 404, "message": "User not found", "error": "Not Found" } // 429 Rate Limited { "statusCode": 429, "message": "Too Many Requests", "retryAfter": 60 }
async function withRetry(fn, retries = 3) { for (let i = 0; i < retries; i++) { try { return await fn(); } catch (err) { if (err.status === 429 || err.status >= 500) { await sleep(2 ** i * 1000); continue; } throw err; } } }
List endpoints use cursor-based pagination. This is more efficient than offset pagination and handles concurrent inserts correctly.
| Parameter | Type | Default | Description |
|---|---|---|---|
| limitopt | integer | 20 | Number of items per page. Max: 100. |
| cursoropt | string | — | Opaque cursor from the previous response's next field. |
| orderByopt | string | createdAt | Sort field. Prefix with - for descending (e.g., -createdAt). |
All list responses include results, next, and previous. Pass the next cursor to get the next page. A null value means you're on the last page.
{
"results": [ ... ],
"next": "cm9cs634h00001mp50l45n7kz",
"previous": null
}async function* paginate(url, headers) { let cursor = null; do { const params = cursor ? `?cursor=${cursor}&limit=100` : '?limit=100'; const { results, next } = await fetch(url + params, { headers }) .then(r => r.json()); yield* results; cursor = next; } while (cursor); } for await (const user of paginate('/v1/users', headers)) { console.log(user.id); }
The API enforces rate limits per API key. Exceeding the limit returns a 429 Too Many Requests response with a Retry-After header indicating when you can retry.
| Plan | Requests / minute | Burst |
|---|---|---|
| Hobby | 60 | 100 |
| Starter | 300 | 500 |
| Growth | 1,000 | 2,000 |
| Business | 5,000 | 10,000 |
Every response includes rate limit information in the headers.
| Header | Description |
|---|---|
| X-RateLimit-Limit | Max requests allowed per minute |
| X-RateLimit-Remaining | Requests remaining in current window |
| X-RateLimit-Reset | Unix timestamp when the window resets |
| Retry-After | Seconds to wait before retrying (429 only) |
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 842
X-RateLimit-Reset: 1747500060
# When exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 37
X-RateLimit-Reset: 1747500060/v1/users
Returns a paginated list of users in the environment. Supports cursor-based pagination and sorting.
| Parameter | Type | Description |
|---|---|---|
| limitopt | integer | Items per page. Default: 20. Max: 100. |
| cursoropt | string | Cursor from previous response for pagination. |
| orderByopt | string | createdAt or -createdAt (desc). Default: createdAt. |
| expandopt | string[] | Relations to expand: companies, memberships, memberships.company. |
curl "https://api.guidez.io/v1/users?limit=20&expand=memberships.company" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const res = await fetch( 'https://api.guidez.io/v1/users?limit=20&expand=memberships.company', { headers } ); const { results, next } = await res.json();
resp = requests.get(
"https://api.guidez.io/v1/users",
params={"limit": 20, "expand": "memberships.company"},
headers=headers
){
"results": [
{
"id": "usr_abc123",
"externalId": "user_123",
"attributes": {
"name": "Jane Smith",
"email": "jane@acme.com",
"plan": "pro"
},
"createdAt": "2026-01-15T09:30:00Z"
}
],
"next": "cm9cs634h00001mp50l45n7kz",
"previous": null
}/v1/users/:id
Retrieve a single user by their external ID (the id you passed when identifying them).
| Parameter | Type | Description |
|---|---|---|
| idreq | string | The user's external ID. |
| Parameter | Type | Description |
|---|---|---|
| expandopt | string[] | Relations to expand: companies, memberships, memberships.company. |
curl "https://api.guidez.io/v1/users/user_123?expand=memberships.company" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const user = await fetch( 'https://api.guidez.io/v1/users/user_123?expand=memberships.company', { headers } ).then(r => r.json());
user = requests.get(
"https://api.guidez.io/v1/users/user_123",
params={"expand": "memberships.company"},
headers=headers
).json(){
"id": "usr_abc123",
"externalId": "user_123",
"attributes": {
"name": "Jane Smith",
"email": "jane@acme.com",
"plan": "pro",
"signedUpAt": "2026-01-10"
},
"memberships": [{
"company": {
"id": "acme",
"attributes": { "name": "Acme Inc." }
}
}],
"createdAt": "2026-01-15T09:30:00Z"
}/v1/users
Create or update a user. If the user doesn't exist it's created. If it exists, provided attributes are merged — existing attributes not in the payload are preserved. Safe to call on every sign-in.
| Field | Type | Description |
|---|---|---|
| idreq | string | Your external user ID. This is the stable identifier from your database. |
| attributesopt | object | Key-value map of custom attributes. Values can be strings, numbers, booleans, or ISO 8601 dates. |
| companiesopt | array | Array of { id, attributes } objects. Adds the user to these companies (upserts them too). |
| membershipsopt | array | Array of { company: { id, attributes }, attributes } with membership-level attributes. |
curl -X POST https://api.guidez.io/v1/users \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..." \ -H "Content-Type: application/json" \ -d '{ "id": "user_123", "attributes": { "name": "Jane Smith", "email": "jane@acme.com", "plan": "pro", "signedUpAt": "2026-01-10" }, "companies": [ { "id": "acme", "attributes": { "name": "Acme Inc." } } ] }'
await fetch('https://api.guidez.io/v1/users', { method: 'POST', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'user_123', attributes: { name: 'Jane Smith', email: 'jane@acme.com', plan: 'pro' }, companies: [ { id: 'acme', attributes: { name: 'Acme Inc.' } } ] }) });
requests.post(
"https://api.guidez.io/v1/users",
headers={**headers, "Content-Type": "application/json"},
json={
"id": "user_123",
"attributes": {
"name": "Jane Smith",
"email": "jane@acme.com",
"plan": "pro"
},
"companies": [
{"id": "acme", "attributes": {"name": "Acme Inc."}}
]
}
){
"id": "usr_abc123",
"externalId": "user_123",
"attributes": {
"name": "Jane Smith",
"email": "jane@acme.com",
"plan": "pro"
},
"createdAt": "2026-05-08T12:00:00Z"
}/v1/users/:id
Permanently deletes a user and all associated session data. This action cannot be undone. Use this for GDPR right-to-erasure compliance.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | The user's external ID. |
curl -X DELETE https://api.guidez.io/v1/users/user_123 \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
await fetch('https://api.guidez.io/v1/users/user_123', { method: 'DELETE', headers });
requests.delete(
"https://api.guidez.io/v1/users/user_123",
headers=headers
){ "deleted": true, "id": "user_123" }/v1/companies
Returns a paginated list of companies (accounts/organizations). Use expand to include their member users.
| Parameter | Type | Description |
|---|---|---|
| limitopt | integer | Items per page. Default: 20. Max: 100. |
| cursoropt | string | Pagination cursor from previous response. |
| orderByopt | string | createdAt or -createdAt. |
| expandopt | string[] | users, memberships, memberships.user. |
curl "https://api.guidez.io/v1/companies?limit=20" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const { results } = await fetch( 'https://api.guidez.io/v1/companies?limit=20', { headers } ).then(r => r.json());
resp = requests.get(
"https://api.guidez.io/v1/companies",
params={"limit": 20},
headers=headers
).json(){
"results": [
{
"id": "cmp_xyz789",
"externalId": "acme",
"attributes": {
"name": "Acme Inc.",
"plan": "enterprise",
"employees": 250
},
"createdAt": "2026-01-01T00:00:00Z"
}
],
"next": null,
"previous": null
}/v1/companies/:id
Retrieve a single company by its external ID.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | The company's external ID. |
| Parameter | Type | Description |
|---|---|---|
| expandopt | string[] | users, memberships, memberships.user. |
curl "https://api.guidez.io/v1/companies/acme?expand=memberships.user" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const company = await fetch( 'https://api.guidez.io/v1/companies/acme?expand=memberships.user', { headers } ).then(r => r.json());
company = requests.get(
"https://api.guidez.io/v1/companies/acme",
params={"expand": "memberships.user"},
headers=headers
).json()/v1/companies
Create or update a company. Attributes are merged on update. Use this to sync account data from your CRM or database.
| Field | Type | Description |
|---|---|---|
| idreq | string | Your external company/account ID. |
| attributesopt | object | Key-value attributes. Common: name, plan, employees, industry. |
curl -X POST https://api.guidez.io/v1/companies \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..." \ -H "Content-Type: application/json" \ -d '{ "id": "acme", "attributes": { "name": "Acme Inc.", "plan": "enterprise", "employees": 250, "industry": "Software" } }'
await fetch('https://api.guidez.io/v1/companies', { method: 'POST', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'acme', attributes: { name: 'Acme Inc.', plan: 'enterprise', employees: 250 } }) });
requests.post(
"https://api.guidez.io/v1/companies",
headers={**headers, "Content-Type": "application/json"},
json={
"id": "acme",
"attributes": {
"name": "Acme Inc.",
"plan": "enterprise"
}
}
)/v1/companies/:id
Permanently deletes a company and all its membership records. User accounts linked to this company are not deleted.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | The company's external ID. |
curl -X DELETE https://api.guidez.io/v1/companies/acme \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
await fetch('https://api.guidez.io/v1/companies/acme', { method: 'DELETE', headers });
requests.delete(
"https://api.guidez.io/v1/companies/acme",
headers=headers
){ "deleted": true, "id": "acme" }/v1/company-memberships
Removes a user from a company. The user account and company are not deleted — only the membership link between them is removed.
| Parameter | Type | Description |
|---|---|---|
| userIdreq | string | The user's external ID. |
| companyIdreq | string | The company's external ID. |
curl -X DELETE \ "https://api.guidez.io/v1/company-memberships?userId=user_123&companyId=acme" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
await fetch( 'https://api.guidez.io/v1/company-memberships?userId=user_123&companyId=acme', { method: 'DELETE', headers } );
requests.delete(
"https://api.guidez.io/v1/company-memberships",
params={"userId": "user_123", "companyId": "acme"},
headers=headers
){ "deleted": true }/v1/content
Returns all content in the environment. Content includes product tours, checklists, banners, and NPS surveys. Filter by type to narrow results.
| Parameter | Type | Description |
|---|---|---|
| limitopt | integer | Items per page. Default: 20. Max: 100. |
| cursoropt | string | Pagination cursor. |
| typeopt | string | Filter by content type: tour, checklist, banner, survey. |
| orderByopt | string | createdAt or -createdAt. |
| expandopt | string[] | editedVersion, publishedVersion. |
curl "https://api.guidez.io/v1/content?type=tour&expand=publishedVersion" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const { results } = await fetch( 'https://api.guidez.io/v1/content?type=tour&expand=publishedVersion', { headers } ).then(r => r.json());
resp = requests.get(
"https://api.guidez.io/v1/content",
params={"type": "tour", "expand": "publishedVersion"},
headers=headers
).json(){
"results": [
{
"id": "cnt_abc123",
"name": "Onboarding Tour",
"type": "tour",
"publishedVersionId": "ver_xyz789",
"createdAt": "2026-01-15T09:00:00Z"
}
],
"next": null,
"previous": null
}/v1/content/:id
Retrieve a single piece of content by its ID. Use expand to include the published or edited version with step data.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | Content ID (e.g., cnt_abc123). |
| Parameter | Type | Description |
|---|---|---|
| expandopt | string[] | editedVersion, publishedVersion. |
curl "https://api.guidez.io/v1/content/cnt_abc123?expand=publishedVersion" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const content = await fetch( 'https://api.guidez.io/v1/content/cnt_abc123?expand=publishedVersion', { headers } ).then(r => r.json());
content = requests.get(
"https://api.guidez.io/v1/content/cnt_abc123",
params={"expand": "publishedVersion"},
headers=headers
).json()/v1/content-versions
Returns all versions across all content in the environment. A version is a snapshot of a piece of content — including its steps, targeting rules, and theme. Content can have a published version (live) and an edited draft.
| Parameter | Type | Description |
|---|---|---|
| contentIdopt | string | Filter versions by content ID. |
| limitopt | integer | Items per page. Default: 20. |
| cursoropt | string | Pagination cursor. |
| expandopt | string[] | questions — include survey question definitions. |
curl "https://api.guidez.io/v1/content-versions?contentId=cnt_abc123" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const { results } = await fetch( 'https://api.guidez.io/v1/content-versions?contentId=cnt_abc123', { headers } ).then(r => r.json());
resp = requests.get(
"https://api.guidez.io/v1/content-versions",
params={"contentId": "cnt_abc123"},
headers=headers
).json(){
"id": "ver_xyz789",
"contentId": "cnt_abc123",
"status": "published",
"stepCount": 4,
"publishedAt": "2026-01-20T10:00:00Z",
"createdAt": "2026-01-18T08:30:00Z"
}/v1/content-versions/:id
Retrieve a specific version by its ID. Versions contain the full step list, targeting rules, and theme configuration.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | Version ID (e.g., ver_xyz789). |
| Parameter | Type | Description |
|---|---|---|
| expandopt | string[] | questions — include survey/NPS question definitions with their options. |
curl "https://api.guidez.io/v1/content-versions/ver_xyz789" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const version = await fetch( 'https://api.guidez.io/v1/content-versions/ver_xyz789', { headers } ).then(r => r.json());
version = requests.get(
"https://api.guidez.io/v1/content-versions/ver_xyz789",
headers=headers
).json()/v1/content-sessions
Returns a list of sessions. A session is created each time a user starts interacting with content. Use this to build activation dashboards, churn alerts, or sync completion data to your data warehouse.
| Parameter | Type | Description |
|---|---|---|
| contentIdreq | string | Filter sessions by content ID. Required. |
| userIdopt | string | Filter to sessions for a specific user. |
| limitopt | integer | Items per page. Default: 20. Max: 100. |
| cursoropt | string | Pagination cursor. |
| orderByopt | string | createdAt or -createdAt. |
| expandopt | string[] | user, company, content, version, answers. |
curl "https://api.guidez.io/v1/content-sessions?contentId=cnt_abc123&expand=user" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const { results } = await fetch( 'https://api.guidez.io/v1/content-sessions?contentId=cnt_abc123&expand=user', { headers } ).then(r => r.json());
resp = requests.get(
"https://api.guidez.io/v1/content-sessions",
params={
"contentId": "cnt_abc123",
"expand": "user"
},
headers=headers
).json(){
"id": "cs_abc123",
"contentId": "cnt_abc123",
"userId": "user_123",
"state": "completed",
"currentStep": 4,
"totalSteps": 4,
"startedAt": "2026-05-01T10:00:00Z",
"completedAt": "2026-05-01T10:04:22Z",
"user": { "externalId": "user_123", ... }
}/v1/content-sessions/:id
Retrieve a single session by ID. Use expand=answers to include the user's survey responses.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | Session ID. |
| State | Meaning |
|---|---|
started | User has seen the first step but not yet completed |
completed | User completed all steps / submitted survey |
dismissed | User dismissed / closed the tour early |
expired | Session timed out before completion |
curl "https://api.guidez.io/v1/content-sessions/cs_abc123?expand=answers" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const session = await fetch( 'https://api.guidez.io/v1/content-sessions/cs_abc123?expand=answers', { headers } ).then(r => r.json());
session = requests.get(
"https://api.guidez.io/v1/content-sessions/cs_abc123",
params={"expand": "answers"},
headers=headers
).json()/v1/content-sessions/:id/end
Programmatically end an active session, marking it as completed. Useful when your application knows the user has completed the onboarding objective through another path.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | Session ID to end. |
curl -X POST https://api.guidez.io/v1/content-sessions/cs_abc123/end \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const updated = await fetch( 'https://api.guidez.io/v1/content-sessions/cs_abc123/end', { method: 'POST', headers } ).then(r => r.json());
resp = requests.post(
"https://api.guidez.io/v1/content-sessions/cs_abc123/end",
headers=headers
).json()/v1/content-sessions/:id
Permanently delete a session record. Use for GDPR erasure or cleaning test data. The user and content are not affected.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | Session ID to delete. |
curl -X DELETE https://api.guidez.io/v1/content-sessions/cs_abc123 \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
await fetch( 'https://api.guidez.io/v1/content-sessions/cs_abc123', { method: 'DELETE', headers } );
requests.delete(
"https://api.guidez.io/v1/content-sessions/cs_abc123",
headers=headers
)/v1/attribute-definitions
Returns the schema of custom attributes defined for users and companies. Use this to understand what attributes are available for targeting rules and to validate data before sending.
| Parameter | Type | Description |
|---|---|---|
| limitopt | integer | Items per page. Default: 20. Max: 100. |
| cursoropt | string | Pagination cursor. |
| objectTypeopt | string | Filter by object type: user or company. |
curl "https://api.guidez.io/v1/attribute-definitions?objectType=user" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const { results } = await fetch( 'https://api.guidez.io/v1/attribute-definitions?objectType=user', { headers } ).then(r => r.json());
resp = requests.get(
"https://api.guidez.io/v1/attribute-definitions",
params={"objectType": "user"},
headers=headers
).json(){
"id": "attr_plan",
"name": "plan",
"displayName": "Subscription Plan",
"dataType": "string",
"objectType": "user",
"isRequired": false
}/v1/event-definitions
Returns the schema of custom events that can be tracked on users. Events are used in targeting rules (e.g., "show tour only to users who have NOT completed file_uploaded in the last 7 days").
| Parameter | Type | Description |
|---|---|---|
| limitopt | integer | Items per page. Default: 20. |
| cursoropt | string | Pagination cursor. |
curl "https://api.guidez.io/v1/event-definitions" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const { results } = await fetch( 'https://api.guidez.io/v1/event-definitions', { headers } ).then(r => r.json());
resp = requests.get(
"https://api.guidez.io/v1/event-definitions",
headers=headers
).json(){
"id": "evt_file_uploaded",
"name": "file_uploaded",
"displayName": "File Uploaded",
"description": "User uploaded a file to workspace",
"properties": [
{ "name": "fileType", "dataType": "string" }
]
}Webhooks let Guidez push real-time event notifications to your server when key onboarding events happen — a tour completed, survey submitted, or checklist milestone reached.
POST /v1/webhooksPOST request to your endpoint when events occur200 OKEvery webhook request includes a x-guidez-signature header. Verify it to ensure the request came from Guidez and wasn't tampered with.
The signature is HMAC-SHA256(rawBody, signingSecret) encoded as hex.
const crypto = require('node:crypto'); function verifySignature(rawBody, sig, secret) { const expected = crypto .createHmac('sha256', secret) .update(rawBody) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(sig) ); } // Express example app.post('/webhook', express.raw({type: '*/*'}), (req, res) => { const sig = req.headers['x-guidez-signature']; if (!verifySignature(req.body, sig, process.env.WEBHOOK_SECRET)) { return res.status(401).send('Invalid signature'); } const event = JSON.parse(req.body); // handle event... res.sendStatus(200); });
import hmac, hashlib, os def verify_signature(raw_body: bytes, sig: str) -> bool: secret = os.environ["WEBHOOK_SECRET"].encode() expected = hmac.new(secret, raw_body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, sig) # Flask example @app.route("/webhook", methods=["POST"]) def webhook(): sig = request.headers.get("x-guidez-signature") if not verify_signature(request.data, sig): return "Invalid", 401 event = request.json # handle event... return "", 200
/v1/webhooks
Returns all webhooks registered for the environment. Signing secrets are not included in list responses.
curl "https://api.guidez.io/v1/webhooks" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const { results } = await fetch( 'https://api.guidez.io/v1/webhooks', { headers } ).then(r => r.json());
resp = requests.get(
"https://api.guidez.io/v1/webhooks",
headers=headers
).json(){
"id": "wh_abc123",
"url": "https://your-app.com/webhooks/guidez",
"events": [
"content.completed",
"content.dismissed"
],
"enabled": true,
"createdAt": "2026-01-15T09:00:00Z"
}/v1/webhooks
Register a new webhook endpoint. The response includes the signing secret — store it securely. It will not be shown again.
| Field | Type | Description |
|---|---|---|
| urlreq | string | Your HTTPS endpoint URL. Must be publicly reachable. |
| eventsreq | string[] | Event types to subscribe to. See Event Reference below. |
| enabledopt | boolean | Whether the webhook is active. Default: true. |
curl -X POST https://api.guidez.io/v1/webhooks \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.com/webhooks/guidez", "events": ["content.completed", "content.dismissed", "survey.answered"] }'
const webhook = await fetch( 'https://api.guidez.io/v1/webhooks', { method: 'POST', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify({ url: 'https://your-app.com/webhooks/guidez', events: ['content.completed', 'survey.answered'] }) }).then(r => r.json());
resp = requests.post(
"https://api.guidez.io/v1/webhooks",
headers={**headers, "Content-Type": "application/json"},
json={
"url": "https://your-app.com/webhooks/guidez",
"events": ["content.completed", "survey.answered"]
}
).json(){
"id": "wh_abc123",
"url": "https://your-app.com/webhooks/guidez",
"events": ["content.completed", "survey.answered"],
"secret": "whsec_xxxxxxxxxxxxxxxxxxxx",
"enabled": true,
"createdAt": "2026-05-08T12:00:00Z"
}/v1/webhooks/:id
Update the URL, event subscriptions, or enabled state of an existing webhook.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | Webhook ID. |
| Field | Type | Description |
|---|---|---|
| urlopt | string | New HTTPS endpoint URL. |
| eventsopt | string[] | Replaces the current event list. |
| enabledopt | boolean | Enable or disable the webhook. |
curl -X PATCH https://api.guidez.io/v1/webhooks/wh_abc123 \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..." \ -H "Content-Type: application/json" \ -d '{ "enabled": false }'
await fetch('https://api.guidez.io/v1/webhooks/wh_abc123', { method: 'PATCH', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled: false }) });
requests.patch(
"https://api.guidez.io/v1/webhooks/wh_abc123",
headers={**headers, "Content-Type": "application/json"},
json={"enabled": False}
)/v1/webhooks/:id
Permanently delete a webhook. No further events will be delivered to this endpoint.
curl -X DELETE https://api.guidez.io/v1/webhooks/wh_abc123 \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
await fetch('https://api.guidez.io/v1/webhooks/wh_abc123', { method: 'DELETE', headers });
requests.delete(
"https://api.guidez.io/v1/webhooks/wh_abc123",
headers=headers
)/v1/webhooks/:id/regenerate-secret
Generates a new signing secret for the webhook. The old secret is immediately invalidated. Update your environment variable before calling this to avoid a gap in verification.
curl -X POST \ https://api.guidez.io/v1/webhooks/wh_abc123/regenerate-secret \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const { secret } = await fetch( 'https://api.guidez.io/v1/webhooks/wh_abc123/regenerate-secret', { method: 'POST', headers } ).then(r => r.json());
resp = requests.post(
"https://api.guidez.io/v1/webhooks/wh_abc123/regenerate-secret",
headers=headers
).json()
new_secret = resp["secret"]/v1/webhooks/:id/deliveries
Returns the delivery attempt history for a webhook. Each delivery record shows the event payload, response status, duration, and any error message on failure.
Failed deliveries are retried up to 5 times with exponential backoff: 30s, 5m, 30m, 2h, 8h. If all retries fail the delivery is marked failed.
curl "https://api.guidez.io/v1/webhooks/wh_abc123/deliveries" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const { results } = await fetch( 'https://api.guidez.io/v1/webhooks/wh_abc123/deliveries', { headers } ).then(r => r.json());
resp = requests.get(
"https://api.guidez.io/v1/webhooks/wh_abc123/deliveries",
headers=headers
).json(){
"id": "del_abc123",
"webhookId": "wh_abc123",
"eventType": "content.completed",
"status": "delivered",
"httpStatus": 200,
"durationMs": 142,
"attempt": 1,
"createdAt": "2026-05-08T12:05:00Z"
}All available webhook event types. Use * as a wildcard to subscribe to all events in a category.
content.started content.completed content.dismissed content.step_completed content.*
survey.answered survey.submitted survey.*
checklist.item_completed checklist.completed checklist.*
user.identified user.deleted user.*
* — Subscribe to all event types
{
"id": "evt_abc123",
"type": "content.completed",
"createdAt": "2026-05-08T12:05:00Z",
"data": {
"sessionId": "cs_abc123",
"contentId": "cnt_abc123",
"contentName": "Onboarding Tour",
"userId": "user_123",
"userAttributes": {
"name": "Jane Smith",
"plan": "pro"
},
"completedAt": "2026-05-08T12:05:00Z",
"durationMs": 262000
},
"environmentId": "cm9cs634h..."
}Guidez tracks detailed analytics for all content. The Analytics API lets you pull completion rates, step-level funnels, time-to-complete, and user-level session data into your own BI tools or dashboards.
/v1/content-sessionsexpand=answers// Pull sessions completed yesterday const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); const sessions = []; for await (const s of paginate( `/v1/content-sessions?contentId=${TOUR_ID}&expand=user`, headers )) { if (s.state === 'completed') sessions.push(s); } // completion rate const rate = sessions.length / total * 100; console.log(`Completion rate: ${rate.toFixed(1)}%`);
Aggregate analytics for a specific piece of content over a date range. Returns views, completions, step-level funnel, completion rate, and average duration.
Use GET /v1/content-sessions with your content ID to pull all sessions, then compute aggregates server-side:
state === 'completed' / total sessionscompletedAt - startedAt in mscurrentStep value in dismissed sessionsexpand=answers — parse the numeric answerconst all = [], completed = []; for await (const s of paginate(`/v1/content-sessions?contentId=${ID}`, headers) ) { all.push(s); if (s.state === 'completed') completed.push(s); } const completionRate = (completed.length / all.length * 100).toFixed(1); const avgMs = completed.reduce((sum, s) => { return sum + (new Date(s.completedAt) - new Date(s.startedAt)); }, 0) / completed.length; console.log({ completionRate, avgMs });
/v1/themes
Returns all themes for the project. Themes control the visual appearance (colors, fonts, border radius, shadows) of tours, checklists, and banners.
| Parameter | Type | Description |
|---|---|---|
| projectIdreq | string | Your project ID. |
curl "https://api.guidez.io/v1/themes?projectId=proj_abc" \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
const themes = await fetch( 'https://api.guidez.io/v1/themes?projectId=proj_abc', { headers } ).then(r => r.json());
themes = requests.get(
"https://api.guidez.io/v1/themes",
params={"projectId": "proj_abc"},
headers=headers
).json(){
"id": "thm_abc123",
"name": "Brand Theme",
"isDefault": true,
"settings": {
"primaryColor": "#7c3aed",
"fontFamily": "Inter",
"borderRadius": 8
}
}/v1/themes
Create a new theme for your project. Themes can be applied to individual content items or set as the project default.
| Field | Type | Description |
|---|---|---|
| namereq | string | Human-readable theme name. |
| projectIdreq | string | Project ID to assign theme to. |
| settingsopt | object | Theme configuration (colors, fonts, spacing). |
curl -X POST https://api.guidez.io/v1/themes \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..." \ -H "Content-Type: application/json" \ -d '{ "name": "Dark Mode Theme", "projectId": "proj_abc", "settings": { "primaryColor": "#a78bfa", "backgroundColor": "#1a1a2e" } }'
const theme = await fetch( 'https://api.guidez.io/v1/themes', { method: 'POST', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'Dark Mode Theme', projectId: 'proj_abc', settings: { primaryColor: '#a78bfa' } }) }).then(r => r.json());
theme = requests.post(
"https://api.guidez.io/v1/themes",
headers={**headers, "Content-Type": "application/json"},
json={
"name": "Dark Mode Theme",
"projectId": "proj_abc",
}
).json()/v1/themes/:id
Update a theme's name or settings. Changes take effect immediately for all content using this theme.
| Parameter | Type | Description |
|---|---|---|
| idreq | string | Theme ID. |
curl -X PATCH https://api.guidez.io/v1/themes/thm_abc123 \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..." \ -H "Content-Type: application/json" \ -d '{ "settings": { "primaryColor": "#6d28d9" } }'
await fetch('https://api.guidez.io/v1/themes/thm_abc123', { method: 'PATCH', headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify({ settings: { primaryColor: '#6d28d9' } }) });
requests.patch(
"https://api.guidez.io/v1/themes/thm_abc123",
headers={**headers, "Content-Type": "application/json"},
json={"settings": {"primaryColor": "#6d28d9"}}
)/v1/themes/:id
Delete a theme. Content using this theme will fall back to the project default theme.
curl -X DELETE https://api.guidez.io/v1/themes/thm_abc123 \ -H "Authorization: Bearer env_live_sk_xxx" \ -H "x-environment-id: cm9cs634h..."
await fetch('https://api.guidez.io/v1/themes/thm_abc123', { method: 'DELETE', headers });
requests.delete(
"https://api.guidez.io/v1/themes/thm_abc123",
headers=headers
)The Guidez JavaScript SDK runs in your users' browsers. It handles user identification, tour rendering, targeting evaluation, and event tracking.
Call Guidez.init() once at app startup with your environment token (publishable key — safe for browsers).
useEffect with empty deps or in your root layout_app.tsx inside a useEffectmounted() or a pluginGuidez.identify() after auth state resolvesimport Guidez from '@guidez/sdk'; Guidez.init({ token: 'YOUR_ENVIRONMENT_TOKEN', });
import { useEffect } from 'react'; import Guidez from '@guidez/sdk'; export function App() { useEffect(() => { Guidez.init({ token: 'YOUR_TOKEN' }); }, []); return <YourApp />; }
// app/layout.tsx 'use client'; import { useEffect } from 'react'; import Guidez from '@guidez/sdk'; export default function RootLayout({ children }) { useEffect(() => { Guidez.init({ token: process.env.NEXT_PUBLIC_GUIDEZ_TOKEN }); }, []); return <html><body>{children}</body></html>; }
Tell Guidez who the current user is. Call this after the user signs in. Triggers targeting evaluation — if any published tours match this user, they'll start showing.
| Parameter | Type | Description |
|---|---|---|
| userIdreq | string | Stable unique ID from your database. Must match the id used in server-side API calls. |
| attributesopt | object | User properties for targeting (name, email, plan, etc.). |
| companyopt | object | { id, attributes } — associates user with a company. |
await Guidez.identify('user_123', { name: 'Jane Smith', email: 'jane@acme.com', plan: 'pro', signedUpAt: '2026-01-10', company: { id: 'acme', attributes: { name: 'Acme Inc.', plan: 'enterprise' } } });
import { useEffect } from 'react'; import Guidez from '@guidez/sdk'; import { useAuth } from './auth'; export function useGuidez() { const { user } = useAuth(); useEffect(() => { if (!user) return; Guidez.identify(user.id, { name: user.name, email: user.email, plan: user.plan, }); }, [user]); }
Programmatically show a specific tour, checklist, or banner by content ID. Bypasses targeting rules — useful for "Show me again" buttons or debug flows.
| Parameter | Type | Description |
|---|---|---|
| contentIdreq | string | The content ID to show (e.g., cnt_abc123). |
| optionsopt | object | { force: boolean } — if true, shows even if already completed. |
// Show a specific tour await Guidez.show('cnt_abc123'); // Force-show even if user already completed it await Guidez.show('cnt_abc123', { force: true }); // "Show me again" button button.addEventListener('click', () => Guidez.show('cnt_abc123', { force: true }) );
Track a custom event for the current user. Events can be used in targeting rules — e.g., only show a tour to users who have NOT fired file_uploaded yet.
| Parameter | Type | Description |
|---|---|---|
| eventNamereq | string | The event name. Use snake_case by convention. |
| propertiesopt | object | Optional key-value properties attached to the event. |
// Simple event Guidez.track('file_uploaded'); // Event with properties Guidez.track('payment_completed', { plan: 'pro', amount: 99, currency: 'usd', }); // Track after user action async function onInviteSent(email) { await sendInvite(email); Guidez.track('invite_sent', { recipientEmail: email }); }
Subscribe to Guidez SDK events. Use this to react to tour lifecycle events in your application — for example, unlock a feature when a tour is completed, or fire an analytics event.
| Event | Fired when |
|---|---|
content.started | User sees the first step of a tour/checklist |
content.completed | User completes all steps |
content.dismissed | User closes/skips the tour |
content.step_completed | User advances past a step |
survey.answered | User submits a survey or NPS response |
// Listen for tour completion Guidez.on('content.completed', (event) => { console.log('Tour completed:', event.contentId); // Unlock a feature enableFeature('advanced-settings'); // Fire your analytics analytics.track('Onboarding Completed', { tourId: event.contentId, userId: event.userId, }); }); // Listen for NPS submission Guidez.on('survey.answered', (event) => { if (event.score < 7) { openChurnSaveModal(); } });
Remove an event listener previously registered with guidez.on(). Call this in cleanup functions to prevent memory leaks.
const handler = (event) => { console.log('completed', event); }; Guidez.on('content.completed', handler); // Later, remove listener Guidez.off('content.completed', handler); // React cleanup pattern useEffect(() => { const h = (e) => analytics.track('Tour Done', e); Guidez.on('content.completed', h); return () => Guidez.off('content.completed', h); }, []);
Clears all identity data and session state from the browser. Always call this on sign-out to prevent the next user on a shared device from seeing tours targeted at the previous user.
async function signOut() { await auth.signOut(); Guidez.reset(); // clear Guidez session router.push('/login'); } // Or with async reset async function signOut() { await Promise.all([ auth.signOut(), Guidez.reset(), ]); router.push('/login'); }
Returns the currently identified user object from the local SDK state. Useful to check if a user is identified before showing UI elements, or to read back attributes you've set.
A User object with id, attributes, and company, or null if no user is identified.
const user = Guidez.getUser(); if (!user) { console.log('No user identified'); } else { console.log('Current user:', user.id); console.log('Plan:', user.attributes.plan); } // Type-safe (TypeScript) type GuidezUser = { id: string; attributes: Record<string, unknown>; company?: { id: string; attributes: Record<string, unknown> }; };
Update attributes of the currently identified user without re-identifying. Use this when user properties change mid-session (e.g., they upgrade their plan). Attributes are merged, not replaced.
| Parameter | Type | Description |
|---|---|---|
| attributesreq | object | Attributes to merge into the current user. |
// User upgrades mid-session async function onUpgrade(newPlan) { await upgradePlan(newPlan); await Guidez.update({ plan: newPlan, upgradedAt: new Date().toISOString(), }); // Guidez re-evaluates targeting with new plan }
The Guidez CLI (@guidez/cli) lets you manage users, companies, content, sessions, and webhooks directly from your terminal. Ideal for scripts, CI/CD pipelines, and quick data lookups.
Or use without installing:
| Command | Description |
|---|---|
guidez login | Authenticate and save API key to ~/.guidez/config.json |
guidez users | List, get, identify, and delete users |
guidez companies | List, get, upsert, and delete companies |
guidez content | List and get content |
guidez sessions | List, get, end, and delete sessions |
guidez webhooks | List, create, and delete webhooks |
guidez export analytics | Export session analytics to JSON or CSV |
| Flag | Description |
|---|---|
--json | Output raw JSON (great for piping to jq) |
--env <id> | Override saved environment ID |
--help | Show help for any command |
Authenticate the CLI by saving your API key and environment ID to ~/.guidez/config.json. Your credentials are stored locally and never sent to Guidez servers directly.
| Flag | Description |
|---|---|
--api-key | Your Guidez API secret key |
--base-url | API base URL (default: https://api.guidez.io) |
--env | Default environment ID |
Manage users from the terminal. Great for customer support lookups, data scripts, and GDPR deletion workflows.
| Subcommand | Description |
|---|---|
users list | List all users with table output |
users get <id> | Get a user by external ID |
users identify | Create or update a user |
users delete <id> | Permanently delete a user |
Manage company accounts from the terminal. Sync CRM data, look up accounts, or clean up test data.
| Subcommand | Description |
|---|---|
companies list | List all companies |
companies get <id> | Get a company by external ID |
companies upsert --id <id> --name <name> | Create or update a company |
companies delete <id> | Delete a company |
Browse and inspect content. Useful for finding content IDs to use in scripts, or auditing what's published.
| Subcommand | Description |
|---|---|
content list [--type <type>] | List all content, optionally filtered by type |
content get <id> | Get a single piece of content by ID |
Inspect and manage content sessions. Look up a specific user's completion status or bulk-clean test sessions.
| Subcommand | Description |
|---|---|
sessions list --content <id> | List sessions for a content item |
sessions get <id> | Get a single session by ID |
sessions end <id> | Mark a session as completed |
sessions delete <id> | Delete a session record |
Manage webhook endpoints. Create, list, or delete webhooks from CI/CD or setup scripts.
| Subcommand | Description |
|---|---|
webhooks list | List all webhooks |
webhooks create --url <url> --events <ev> | Create a new webhook |
webhooks delete <id> | Delete a webhook |
Export session data for a content item to JSON or CSV. Iterates all pages automatically and writes to stdout or a file.
| Flag | Description |
|---|---|
--content <id> | Content ID to export sessions for |
--start <date> | Start date filter (YYYY-MM-DD) |
--end <date> | End date filter (YYYY-MM-DD) |
--format json|csv | Output format. Default: json |
--output <file> | Write to file instead of stdout |
The Model Context Protocol (MCP) server exposes all Guidez API capabilities as tools that AI assistants — Claude, Cursor, Windsurf, and any MCP-compatible client — can call natively.
This means you can ask your AI assistant:
Your AI assistant calls Guidez directly — no copy-pasting IDs, no manual API calls.
List all users in the environment
Create or update a user with attributes
Get a user by external ID
Permanently delete a user
List all companies
Create or update a company
Remove a user from a company
List all tours, checklists, and banners
List content sessions for a content item
Mark an active session as completed
List all registered webhook endpoints
Register a new webhook endpoint
// You ask Claude: "Who are our 5 newest users?" // Claude calls: list_users({ limit: 5 }) // Returns: [ { id: "user_789", name: "Alice Wang", ... }, { id: "user_456", name: "Bob Kim", ... }, ... ] // Claude responds: "Your 5 newest users are: 1. Alice Wang (user_789) — signed up 2 hours ago 2. Bob Kim (user_456) — signed up yesterday ..."
The MCP server communicates over stdio — the standard MCP transport. Configure it in your AI assistant's settings once, and it's available in every conversation.
| Variable | Description |
|---|---|
GUIDEZ_API_KEY | Your API secret key (env_live_sk_xxx) |
GUIDEZ_ENV_ID | Your environment ID |
GUIDEZ_BASE_URL | Optional. Default: https://api.guidez.io |
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows).
{
"mcpServers": {
"guidez": {
"command": "npx",
"args": ["@guidez/mcp"],
"env": {
"GUIDEZ_API_KEY": "env_live_sk_xxx",
"GUIDEZ_ENV_ID": "cm9cs634h00001mp50l45n7kz"
}
}
}
}{
"mcpServers": {
"guidez": {
"command": "node",
"args": ["/path/to/node_modules/@guidez/mcp/index.js"],
"env": {
"GUIDEZ_API_KEY": "env_live_sk_xxx",
"GUIDEZ_ENV_ID": "cm9cs634h..."
}
}
}
}# Start the server manually to test
GUIDEZ_API_KEY=env_live_sk_xxx \
GUIDEZ_ENV_ID=cm9cs634h... \
node $(npm root -g)/@guidez/mcp/index.jsFour tools cover the full user lifecycle — list, get, identify/upsert, and delete.
List users. Optional: limit (int), cursor (string).
Required: id (string). Returns full user object with attributes.
Required: id. Optional: name, email, company_id, attributes (object).
Required: id. Permanently deletes user and all session data.
// MCP tool call (JSON) { "name": "identify_user", "arguments": { "id": "user_123", "name": "Alice Wang", "email": "alice@example.com", "attributes": { "plan": "pro", "signedUpAt": "2026-05-08" } } } // Response { "id": "usr_abc123", "externalId": "user_123", "attributes": { "name": "Alice Wang", ... }, "createdAt": "2026-05-08T12:00:00Z" }
List companies. Optional: limit, cursor.
Required: id. Returns company with attributes.
Required: id, name. Optional: attributes (object).
Required: id. Deletes company and all membership links.
Required: user_id, company_id. Removes user from company.
// You say to Claude: "Add Acme Inc. as a company with 500 employees in the tech industry" // Claude calls: upsert_company({ id: "acme", name: "Acme Inc.", attributes: { employees: 500, industry: "Technology" } })
List all content. Optional: type (tour/checklist/banner), limit.
Required: id. Returns content with metadata.
Optional: content_id. Lists all versions.
Required: id. Returns a version with step data.
// You ask: "How many tours do we have published?" // Claude calls: list_content({ type: "tour", limit: 100 }) // Claude responds: "You have 12 tours in total. 8 are published, 4 are drafts. Your most recent is 'Feature Spotlight' published 2 days ago."
Required: content_id. Optional: user_id, limit.
Required: id. Returns session with state, steps, and timestamps.
Required: id. Marks session as completed.
Required: id. Permanently removes session record.
Ask Claude: "Show me which users started the onboarding tour but didn't complete it in the last 7 days"
Claude will call list_sessions, filter for state === 'started', and return the user IDs — which you can then target with a follow-up email.
// You ask Claude: "Which users started but didn't complete the onboarding tour?" // Claude calls: list_sessions({ content_id: "cnt_onboarding", limit: 100 }) // Claude filters, then calls for each: get_user({ id: session.userId }) // Claude responds: "14 users started but didn't finish: - user_789 (alice@co.com) — started 3 days ago, step 2/5 - user_456 (bob@co.com) — started 5 days ago, step 1/5 ..."
No required args. Returns all custom attribute schemas for users and companies.
No required args. Returns all trackable event types with their property schemas.
No required args. Returns all registered webhooks.
Required: url (string), events (string[]). Creates webhook and returns signing secret.
Required: id. Permanently removes webhook.
// You say: "Create a webhook for tour completions pointing to https://my-crm.com/guidez-hook" // Claude calls: create_webhook({ url: "https://my-crm.com/guidez-hook", events: ["content.completed"] }) // Claude responds: "Done! Webhook wh_abc123 created. Your signing secret is: whsec_xxxx (store this in your environment variables)"
Stay up to date with API changes. We version the API and maintain backwards compatibility. Breaking changes get a new version prefix.
@guidez/cli — full terminal interface for all API operations@guidez/mcp — Model Context Protocol server for Claude, Cursor, Windsurfon(), off(), getUser(), update()track() now supports arbitrary event propertiesexpand=memberships.companyidentify() now accepts company parameter for direct association@guidez/sdk published to npm# Current stable version GET https://api.guidez.io/v1/users # We maintain backwards compatibility # Breaking changes get a new version: # v2 (future) GET https://api.guidez.io/v2/users
# Subscribe to API changelog:
# https://guidez.io/changelog
# Status page:
# https://status.guidez.io
# Developer community:
# https://community.guidez.io