# Delete your account Source: https://docs.trytalkvalue.com/administration/account/delete-account What to do before deleting your TalkValue account, and how to fully remove your identity and workspace data. Account deletion fully removes you from TalkValue. The order of operations matters because a workspace cannot exist without an Admin: leaving an unowned workspace behind blocks billing and member management for everyone else. Work through the steps in order. ## Before you delete If you only want to leave a single workspace and keep your TalkValue account on others, see [Leave a workspace](#leave-a-workspace-instead) instead. To delete the account entirely: Once deleted, you lose access to every workspace that depended on you. See [Export your data](/administration/export-your-data). For every workspace where you are the **only Admin**, promote another member to Admin first; otherwise the workspace is left without billing or member control. See [Roles and permissions](/administration/workspace/roles-and-permissions). If your account is the billing owner for a Pro workspace, cancel or transfer billing to another Admin first. See [Cancel and undo](/administration/billing/cancel-and-undo). Open **Settings → General** in each workspace and use **Leave workspace**. ## What deletion removes When TalkValue deletes your account: * Your **identity record** (name, email, avatar reference) is removed. * Your **memberships** in every remaining workspace are removed. * Sessions across all browsers are invalidated. You're signed out everywhere. ## What deletion does not remove Workspace data is owned by the workspace, not by you, and is retained when you leave: * **Events, people, channels, and tags** in any workspace stay with the workspace. * **Badges, templates, and stations** in any workspace stay with the workspace. * **Spark digests and walls** in any workspace stay with the workspace. * **Activity history** in any workspace stays with the workspace. If you want every trace of your activity removed from a workspace's activity history and not just your account, that's a separate full-wipe request. Note it explicitly when you contact support. ## Request deletion Account deletion runs through support. Send an email from the account you want deleted to [support@trytalkvalue.com](mailto:support@trytalkvalue.com) with the subject line **"Delete my TalkValue account"**. Include: * The email address on the account. * Confirmation that you've transferred any workspace Admin roles you needed to transfer. * Whether you also want a **full data wipe**: activity-history removal in workspaces where you took actions. Support replies within 1 business day to confirm and complete the deletion. Once confirmed, the deletion is **irreversible**; there is no undo window. ## Leave a workspace instead To leave one workspace and keep your TalkValue account on others, switch to that workspace from the chip in the top-left header, open **Settings → General**, scroll to the red **Leave workspace** card, and confirm. You lose access to the workspace's data and are switched to one of your other workspaces. You can leave any workspace where you're not the only Admin; otherwise promote someone first. ## Related * [Export your data](/administration/export-your-data). Pull a copy before any deletion. * [Roles and permissions](/administration/workspace/roles-and-permissions). How to promote another member to Admin. * [Cancel and undo](/administration/billing/cancel-and-undo). Wind down a paid subscription you own. * [Profile](/administration/account/profile). View your current account email before contacting support. # Login methods Source: https://docs.trytalkvalue.com/administration/account/login-methods Sign in to TalkValue with a magic link or Google: how each works, when to use which, and how to switch. TalkValue accepts two ways to sign in: a **magic-link code** sent to your email, and **Continue with Google**. Both land you in the same account. Your identity is your email address, and either method authenticates that email. This page covers how each flow works, what changes when, and how to switch between methods. ## Sign-in screen The screen at [`app.trytalkvalue.com/login`](https://app.trytalkvalue.com/login) shows: * **Continue with Google.** A primary button at the top. * A divider labeled *or continue with email*. * An email field followed by a **Continue with email** button. Both buttons sign in an existing account and create one if no account exists for that email. There's no separate sign-up flow. ## Magic-link code Type your email on `/login` and click **Continue with email**. TalkValue sends a 6-digit code that you enter in the 6-slot input on the verify screen. Verification happens as soon as the sixth digit lands, no submit button. First-time accounts land in onboarding; returning accounts land in their last-used workspace. * **Single use.** Each code becomes invalid the moment you verify. * **Resend.** Click **Resend** on the verify screen if the code didn't arrive. 60-second cooldown between resends. * **Invitations use the same flow.** Opening a workspace invitation link routes through the same verify screen; the title reads "Accept invitation" instead of "Check your email". ## Continue with Google Click **Continue with Google** on `/login`. Google opens its account picker, you pick the right account, and Google redirects you back signed in. The Google email is what TalkValue uses as your account email. The first time, Google asks you to approve TalkValue's access to basic profile info: name, email, profile picture. Once approved, your Google profile picture becomes your TalkValue avatar (see [Profile](/administration/account/profile#avatar)). ## Use the same email on both methods The account is identified by email. If you signed up with `you@northwind.io` via magic link and later click **Continue with Google** with a Google account on the same `you@northwind.io` address, both methods sign you into the same TalkValue account. If you have multiple Google accounts (`you@gmail.com` and `you@northwind.io`), pick the one that matches the email already in your TalkValue workspace. Signing in with a different Google email creates a separate account for that email. This is not a security concern; it is a separate identity. ## Switch methods TalkValue doesn't lock you to one method. To switch, sign out from **Settings → Account**, then sign back in with the other button on `/login` using the same email. Your last-used method is whatever you clicked last; there's no preferred-method setting. ## Accepting workspace invitations Invitation links open TalkValue with the invitation token attached and send a 6-digit code to the invited address. Enter that code on the **Accept invitation** screen to join. If you already have an open session on the invited email, the link adds the workspace right away. ## Related * [Profile](/administration/account/profile). Where your name and avatar live after sign-in. * [Invite teammates](/get-started/workspace/invite-teammates). Admin side of the invitation flow. * [Delete your account](/administration/account/delete-account). When you're done with TalkValue. # Profile Source: https://docs.trytalkvalue.com/administration/account/profile Update your name, see your avatar source, and understand what changes when you edit your account. Your profile is the account-level identity that follows you across every TalkValue workspace you belong to. Workspace data is scoped per workspace, but your name, email, and avatar are shared. ## Where it lives **Settings → Account → Profile** is the landing page when you open Settings. The **Profile details** panel shows your avatar, editable **First name** and **Last name**, and a read-only **Email address**. Signing out lives on the account menu instead — the avatar at the bottom of the left icon rail, which also links back to this page. ## Edit your name Click **Settings** at the bottom of the left icon rail, then **Profile** under **Account**. Edit either or both fields. Leading and trailing whitespace is trimmed when you save. A toast confirms **"Profile updated"** when the save completes. **Cancel** discards edits and restores the saved values. Name changes propagate to: * The avatar fallback initials (when no profile picture is set). * The account menu at the foot of the icon rail, and the workspace member list. * Every workspace you belong to. Your name is shared across all of them. ## Avatar The avatar shown in the header and across TalkValue comes from your identity provider: * **Google sign-in.** TalkValue uses your Google profile picture. * **Magic link sign-in.** TalkValue shows your initials until a profile picture is set on the account. You set your avatar through your identity provider (Google or your account picture), not on the TalkValue Settings page. If your Google profile picture has changed and you don't see the update in TalkValue, sign out and back in to refresh the session. ## Email Your account email is the address you sign in with. It's read-only on the profile panel, with this description beside it: > *To change your account email, an admin must send an invitation to the new email address.* Migration path: an Admin invites your new email from **Settings → Members** ([Invite teammates](/get-started/workspace/invite-teammates)), you accept on the new inbox, then the Admin removes the old account. Workspace data stays; only the membership identity changes. ## Role Your role belongs to a workspace, not to your account, so it can differ between the workspaces you belong to. **Settings → Members** lists every member with their role, including yours. To request a role change, ask any workspace Admin to update it there. See [Roles and permissions](/administration/workspace/roles-and-permissions) for the full capability matrix. ## Related * [Login methods](/administration/account/login-methods). Magic link and Google sign-in details. * [Delete your account](/administration/account/delete-account). How to fully remove your TalkValue account. * [Members reference](/administration/workspace/members). For admins changing other people's roles. * [Sign out and switch workspaces](/get-started/workspace/create-workspace). How the workspace chip behaves. # Cancel and undo Source: https://docs.trytalkvalue.com/administration/billing/cancel-and-undo Cancel your Pro subscription at the end of the current billing period, or undo the cancellation before it takes effect. Canceling a Pro subscription doesn't end access immediately. Your workspace stays on Pro through the end of the current paid period, and TalkValue stops the next charge. If you change your mind before that end date, you can reverse the cancellation in one click. This page covers what cancellation does, what it doesn't do, and how to back out. ## Where to cancel **Settings → Billing → Subscription**. The card shows the plan, the next billing date, and a **Manage subscription** button on the right. Click it to open the Stripe Customer Portal, where the cancel action lives. This card is visible to **Admins only**. If you're a Member who needs the subscription canceled, ask an Admin (see [Roles and permissions](/administration/workspace/roles-and-permissions)). ## Cancel Click **Settings** at the bottom of the left icon rail, then **Billing** under **Organization**. A spinner appears briefly, then the page redirects to the Stripe Customer Portal in the same tab. In the portal, find the subscription row and click **Cancel plan**. Stripe asks you to confirm, sometimes with a brief retention prompt. Click **Return to TalkValue** at the top of the portal. The **Subscription** card now shows a **CANCELING** status badge and a warning that the subscription ends on the period-end date. ## What cancellation does Canceling switches the subscription into **cancel-at-period-end** mode. The plan status badge on the Subscription card changes to **CANCELING**, a warning banner appears with the exact end date (*"Cancellation scheduled. Your subscription ends on ``. You'll keep access until then."*), and the next recurring charge is stopped. The workspace, every member, and all data stay on Pro through the end date. No partial month, no proration, no early shutdown. Cancellation does **not** delete your workspace or data, remove members or invitations, or refund the current period's charge. If you want the workspace removed too, do that separately on [General](/administration/workspace/general#delete-workspace-admin-only) before the period ends. After the period ends, see [Resubscribe](/administration/billing/resubscribe). ## Undo the cancellation While the subscription is in **CANCELING** mode, you can reinstate it any time before the end date. The cancellation banner shows the deadline. The Subscription card still shows the **CANCELING** badge and the warning banner. Open the Stripe Customer Portal in the same tab. On the subscription row, click **Renew plan** (Stripe's wording for reverse-cancel). Confirm. The card flips back to **ACTIVE**. The next charge resumes on the existing anniversary date; you don't get a new cycle start. ## After the end date Once the period-end date passes without an undo, the subscription expires. The workspace moves into an **EXPIRED** state and the next sign-in routes to the resubscribe screen. Workspace data is preserved through the lapse window. See [Resubscribe](/administration/billing/resubscribe) for the reactivation flow and the lapse-window behavior. ## Related * [Plans, trial, and Pro](/administration/billing/plans-trial-pro). What you're stopping, and what the trial covers. * [Update payment method](/administration/billing/update-payment-method). Manage the card outside of the cancellation flow. * [Resubscribe](/administration/billing/resubscribe). After a subscription has expired. * [General](/administration/workspace/general). Delete the workspace entirely if cancellation isn't enough. # Plans, trial, and Pro Source: https://docs.trytalkvalue.com/administration/billing/plans-trial-pro What is included in the 7-day trial and the Pro plan. TalkValue has one paid plan, **Pro at \$299/month**, and a 7-day trial that unlocks everything in Pro. Add a payment method on sign-up to start the trial, and convert automatically on day 8 unless you cancel. ## Trial * **Length:** 7 days from sign-up * **Includes:** everything in Pro (Path, Badge, Spark, CLI) * **Payment:** card required on sign-up; no charge during the trial * **Conversion:** automatic switch to Pro on day 8 unless canceled You can cancel the trial from **Settings → Billing** at any point. Canceling before day 8 means no charge. You keep full access until the trial period ends; after that, the workspace's access pauses and an Admin can reactivate it from the **Reactivate your workspace** screen at any time. Your data is preserved. ## Pro * **Price:** \$299/month per workspace * **Includes:** Path, Badge, Spark, and CLI * **Billing:** monthly, on your subscription anniversary * **Usage:** see [Usage and credits](/administration/billing/usage-and-credits) for included credits and per-unit rates ## Manage your subscription Manage your card through the Stripe Customer Portal. Cancel at period end, or reinstate within the current cycle. What's metered, when it resets, and how included credits work. ## Related * [Usage and credits](/administration/billing/usage-and-credits). What's metered and how included credits work. * [Update payment method](/administration/billing/update-payment-method). Manage the card on file through Stripe. * [Cancel and undo](/administration/billing/cancel-and-undo). Cancel at period end, or reinstate within the cycle. * [Resubscribe](/administration/billing/resubscribe). Reactivate a workspace after the subscription has expired. # Resubscribe Source: https://docs.trytalkvalue.com/administration/billing/resubscribe Reactivate a TalkValue workspace after the subscription has expired. When a Pro subscription expires, the workspace is moved into an **EXPIRED** state. Your data is preserved through the lapse window, but no member can use Path, Badge, Spark, or the CLI until an Admin resubscribes. The resubscribe screen at `/billing/resubscribe` is where that reactivation happens. ## When you land on /billing/resubscribe TalkValue routes you to this screen automatically when: * A Pro subscription is canceled and the period-end date has passed. * A subscription lapses because a payment failure exhausted the retry grace window. The next sign-in attempt after either trigger redirects an Admin to `/billing/resubscribe` instead of the dashboard. Members are redirected to the same screen but see a message asking them to ask their Admin to reactivate; the resubscribe button is Admin-only (see [Roles and permissions](/administration/workspace/roles-and-permissions)). The headline reads **"Reactivate your workspace"** with the subtitle *"Your subscription expired. Resume to restore access — your data is still here."* A summary of what Pro includes appears below. ## Resume Pro (Admin) Sign in as an Admin and confirm you're on `/billing/resubscribe`. If you weren't redirected automatically, navigate to the URL directly. The primary button shows the monthly price, **Resume Pro — \$299**. A spinner appears briefly, then the page redirects to Stripe Checkout in the same tab. Stripe Checkout pre-fills the card on file from your previous subscription. Confirm to use it, or enter a new card if the old one isn't valid (expired, replaced). On a successful charge, Stripe redirects you back to TalkValue. The workspace flips to **ACTIVE**, and you land on the dashboard. If anything fails mid-checkout (cancel button, 3D Secure decline), Stripe routes you back to `/billing/resubscribe`. You can try again with a different card. ## What's preserved during the lapse The lapse window is treated as a soft pause. The workspace, events, people, channels, badges, templates, Spark digests, and tags all remain. Members and pending invitations stay on the workspace; they can't sign in past the resubscribe screen. Integrations (Eventbrite, Luma, Slack) remain connected and pause sync activity. Resubscribing restores access without re-importing or reconnecting anything. After an extended lapse, workspace data may no longer be recoverable. Contact [support@trytalkvalue.com](mailto:support@trytalkvalue.com) if your workspace is empty after reactivating. ## If you're a Member When a Member lands on `/billing/resubscribe`, the screen replaces the **Resume Pro** button with an alert: *"Ask your workspace admin to reactivate. Only workspace admins can resume billing. Your data is preserved — once an admin reactivates, you'll regain access here."* Forward the URL or sign-in invite to an Admin in your workspace, or use the **Members** list ([Members](/administration/workspace/members)) before expiration to confirm who currently holds Admin. ## Questions before resubscribing The resubscribe screen has a **"Questions? Connect with our team"** button that opens an in-page scheduling widget for a short call with the TalkValue team. Use it if you want to talk through pricing, custom needs, or what's changed since you last used TalkValue before reactivating. ## Related * [Cancel and undo](/administration/billing/cancel-and-undo). What sent the workspace into the expired state. * [Plans, trial, and Pro](/administration/billing/plans-trial-pro). What Pro includes. * [Update payment method](/administration/billing/update-payment-method). Replace the card if the old one expired. * [Roles and permissions](/administration/workspace/roles-and-permissions). Why only Admins see the Resume button. # Update payment method Source: https://docs.trytalkvalue.com/administration/billing/update-payment-method Add, replace, or remove the card on file for your TalkValue workspace. The card on file pays for your Pro subscription and any usage past your included credits. You manage it through the **Stripe Customer Portal**, which TalkValue opens in a redirect from the billing page. Stripe handles the card form, fraud checks, and 3D Secure; TalkValue picks the result back up when you return. ## Where it lives **Settings → Billing → Billing details → Payment method**. The row shows your current payment method (brand, last four, expiration) when one is on file, and **No card on file** when none is. The button beside it takes you into Stripe: * **Add card** if no card is on file. * **Update** if a card is already on file. This tab and these buttons are visible to **Admins only**. If you're a Member who needs the card updated, ask an Admin (see [Roles and permissions](/administration/workspace/roles-and-permissions)). ## Add or replace your card Click **Settings** at the bottom of the left icon rail, then **Billing** under **Organization**. A spinner appears briefly, then the page redirects to the Stripe Customer Portal in the same tab. In Stripe's portal, click **Add payment method**, fill in the card details, and confirm any 3D Secure challenge from your bank. On the **Payment methods** list, open the new card's menu and pick **Make default**. Stripe uses the default card on the next invoice. Open the old card's menu and pick **Remove**. Stripe blocks removing the default, so set the new card as default first. Click **Return to TalkValue** at the top of the Stripe portal. TalkValue syncs your billing state on the way back, so the **Payment method** row shows the new card as soon as the page loads. ## What the Stripe Customer Portal can do Beyond payment methods, the Stripe portal lets you: * Download past invoices and receipts as PDFs. * Update the billing address used on invoices (for VAT or sales-tax compliance). * Update the billing email that receives invoice and dunning emails. **Open billing portal** on the **Invoice history** row and **Manage subscription** on the plan card both open the same portal. ## If the card fails A failed charge moves your workspace into a **PAST DUE** state. The subscription stays active for a grace window while Stripe retries. TalkValue surfaces the past-due state as a **PAST DUE** badge on the **Billing** tab and as a **Your last payment failed** banner across the top of the dashboard. Use **Update payment method** on the banner or **Update** on the **Billing** tab, then add a working card. The next retry goes through and the workspace returns to **ACTIVE**. If the grace window expires without a successful charge, the workspace moves to **EXPIRED** and routes to the resubscribe screen on next sign-in. See [Resubscribe](/administration/billing/resubscribe). ## Related * [Plans, trial, and Pro](/administration/billing/plans-trial-pro). What you're paying for. * [Usage and credits](/administration/billing/usage-and-credits). What drives the next invoice amount. * [Cancel and undo](/administration/billing/cancel-and-undo). Stop future charges or reinstate within the cycle. * [Resubscribe](/administration/billing/resubscribe). After a subscription has expired. # Usage and credits Source: https://docs.trytalkvalue.com/administration/billing/usage-and-credits What TalkValue meters, how included credits work, when the counter resets, and where to watch usage. Pro is usage-based. The **\$299/month** base includes a set of credits for each metered feature, and usage beyond those credits is billed per unit on the next invoice. This page covers what's metered, when the counter resets, and how to watch usage day to day. ## Where to watch usage **Settings → Billing → Plan**. Each metered feature gets its own cell showing: * The feature icon and label. * The reset window: **Resets ``** for monthly meters, **Cumulative** for lifetime meters. * The count and the credits it draws from: **`` of `` included**. * A progress bar filling toward the included credits. * The per-unit rate for usage past the included credits (**`$X.XX` per additional**). A **Next invoice** cell sits alongside the meters once the current period has an invoice coming, with the amount and due date, split into **`$X` plan + `$Y` usage** when usage has accrued. The figure updates through the cycle; the final invoice is generated on your subscription anniversary. The **Billing** tab is visible to **Admins**. ## Metered features TalkValue meters the surfaces where cost scales with usage. The current set: | Feature | What counts | Resets | | ---------------------- | ------------------------------------------------------------------ | ----------------------------------------- | | **Attendee check-ins** | Each attendee, the first time staff check them in at a Badge event | Monthly, on your subscription anniversary | | **Contacts** | Distinct people in your Path workspace | Cumulative | The Plan section always shows the live set of metered features for your workspace. ## Reset cycle Monthly meters reset on your subscription anniversary, not on the 1st of the calendar month. If your subscription started on March 18, the counter rolls over on the 18th of every month. The cell shows the exact next reset date so you don't have to track it. Cumulative meters don't reset — the counter tracks your workspace's total over its lifetime rather than a monthly window. TalkValue measures your contact count once a day. Deleting people lowers that number at the next daily measurement, and the lower figure reaches your invoice in the next billing period: the current period bills on the highest count it has already reached. ## Usage past your included credits Once a feature's usage passes the credits included in your plan, the additional usage is billed at the per-unit rate shown under its progress bar (**`$X.XX` per additional**) and rolls into your next invoice alongside the base price. The rate reflects your workspace's current pricing and is shown live, so you can confirm it at any time. During the **trial**, usage isn't billed. You can use the full Pro feature set without accruing usage charges. ## How the counters work * **Attendee check-ins** count when staff actually check people in. Importing a roster doesn't count. Each attendee counts once: re-scanning the same badge, checking someone in again on a later day of a multi-day event, or canceling and redoing a check-in all leave the number where it is. * **Contacts** counts the de-duplicated person record. Re-importing the same person doesn't double-count. To scope usage down, delete people you no longer need. The reduction applies from your next billing period — the period you're in has already been billed on the peak it reached, so deleting mid-cycle won't lower the invoice you're about to receive. The monthly attendee counter resets on your anniversary, no manual reset. ## Related * [Plans, trial, and Pro](/administration/billing/plans-trial-pro). What's included in the base subscription. * [Update payment method](/administration/billing/update-payment-method). The card your invoices go to. * [Cancel and undo](/administration/billing/cancel-and-undo). Stop future charges if usage is no longer needed. * [People](/path/manage/people). Where the contact count comes from. * [Badge](/badge). Where the attendee check-in count comes from. # Export your data Source: https://docs.trytalkvalue.com/administration/export-your-data Pull a copy of your workspace data from TalkValue: people, events, registrants, and account-level portability. You can take your workspace data out of TalkValue at any time. CSV is the default format, and the CLI handles repeatable scripted exports. The dashboard surfaces the same data in tables, and account-level portability requests are handled by support. ## What you can export | Data | Where it lives in TalkValue | How to export | | ----------------------------------------------------- | ------------------------------ | --------------------------------------------------------------------------------------------- | | People (contacts) | Path → People | Dashboard CSV export, or `talkvalue path person export` | | Events | Badge → Events / Path → Events | Dashboard tables, or [`person list --json`](/cli/commands/path/person/list) filtered by event | | Event registrants | Path → Events → event detail | [`talkvalue path event person export`](/cli/commands/path/event/person-export) | | Channels and tags | Path → Channels, Tags | Dashboard tables | | Spark digest history | Spark → Digest | Dashboard tables | | Account identity (your name, email, avatar reference) | Profile and identity provider | Support request | The exports give you the underlying data as you put it in plus what TalkValue derives (de-duplication keys, channel attribution). They don't include behavioral analytics summaries (those are recomputed on import). ## People export Two paths, same data. **From the CLI.** The fastest repeatable export is: ```bash theme={null} talkvalue path person export > people.csv ``` The command streams every person in the active workspace as CSV to stdout. Columns match the dashboard's CSV export. Pipe it into a transformer, save it to a file, or schedule it from a cron job. Full details in [`talkvalue path person export`](/cli/commands/path/person/export). **From the dashboard.** Open **Path → People**. The toolbar above the table has an **Export CSV** button that downloads `people.csv` with every person in the workspace, using the same columns as the CLI export. ## Event registrant export Run [`talkvalue path event person export `](/cli/commands/path/event/person-export) to emit a CSV of every registrant on that event: name, email addresses, company, job title, phone numbers, address, avatar and social URLs, and the date the person joined the event. For an event still taking registrations, export at the end for the final state. ## Round-trip exports (CLI) The CLI gives you both halves of the round-trip when you need to export, transform externally, and re-import. See [Recipe: CSV import](/cli/recipes/csv-import) for the canonical pattern, or use [`talkvalue path person list --json`](/cli/commands/path/person/list) for structured output when CSV columns aren't enough. ## Account-level portability For a full account-level portability package (everything tied to your account across every workspace, in a single bundle), email [support@trytalkvalue.com](mailto:support@trytalkvalue.com) from the account email. Include the account email, your preferred format (JSON, CSV, or both), and the workspaces to include (or "all"). Support replies within 2 business days and delivers a signed download link valid for 7 days. The package is account-scoped: it captures data tied to your account, not the entire workspace. For a full workspace bundle, use the per-resource exports above as the workspace Admin. ## Retention after deletion When you delete a workspace ([General → Delete workspace](/administration/workspace/general#delete-workspace-admin-only)), data is removed from the live application immediately and purged from backups within the standard retention window. After the purge, the data cannot be restored. When you [delete your account](/administration/account/delete-account), your account identity is removed and your memberships are dropped from every workspace. Workspace data you created stays with the workspaces, and each workspace keeps its activity history intact. Request a full data wipe explicitly if you want every trace removed. Export anything you want to keep **before** either deletion. There is no undo window once the deletion completes. ## Related * [`talkvalue path person export`](/cli/commands/path/person/export). CSV export from the CLI. * [Recipe: CSV import](/cli/recipes/csv-import). The matching round-trip pattern. * [People](/path/manage/people). The dashboard surface that the export mirrors. * [Delete your account](/administration/account/delete-account). Pull a copy first. * [General](/administration/workspace/general). Workspace lifecycle, including deletion. # Glossary Source: https://docs.trytalkvalue.com/administration/glossary Definitions for the people, products, and core terms you'll see across TalkValue. This page defines the proper nouns and core entities you'll see across the TalkValue product and docs. Each term links to where the concept is explained in depth. ## Workspace and team **Workspace**: Your team's TalkValue instance. Members share one billing account, one set of integrations, and one library of imported people, events, channels, and tags. Switch between workspaces from the chip in the top-left header. See [Create a workspace](/get-started/workspace/create-workspace). **Member**: Anyone in your workspace who isn't an Admin. Members can use Path, Badge, Spark, and the workspace integrations. Admins additionally manage billing and membership. See [Roles and permissions](/administration/workspace/roles-and-permissions). **Admin**: A workspace member with full access to billing, members, integrations, and workspace settings. Every workspace needs at least one Admin. See [Members](/administration/workspace/members). ## Products **Path**: TalkValue's audience analytics product. Path imports your people, events, and channels and answers questions like "which channels brought in the most new audience this quarter?" See [Path](/path). **Badge**: TalkValue's on-site check-in product. Badge designs and prints event badges and runs the mobile check-in stations your staff use at the door. See [Badge](/badge). **Spark**: TalkValue's community engagement product. Spark sends a daily curated news digest to your Slack channel, tracks your community's social reach, and powers live Slack walls on venue TVs. See [Spark](/spark). **CLI**: `talkvalue`, the command-line interface for scripting Path and exporting data. See [CLI](/cli). ## Path entities **Person**: One individual in your audience, identified by email. Holds name, phone, job title, and other optional fields. See [People, companies, channels, events](/platform/concepts/data-model). **Company**: The organization a person works for, auto-grouped by email domain. Every `@northwind.io` person rolls up under one Northwind record. **Channel**: A reusable registration source like newsletters, partner referrals, LinkedIn campaigns, or SDR outbound. Channels persist across events, which is what lets attribution and overlap analytics work. **Event**: A single gathering at a specific time, like a webinar, meetup, or conference. Has a name, timezone, start time, and optional end time and location. **Tag**: A short label you attach to events and channels (`Customer Day`, `Webinar`, `Q2-campaign`) to group them and scope analytics charts. See [Tags](/path/concepts/tags). ## Badge entities **Attendee**: A person registered for a Badge event. Comes in via integration sync or CSV import and is the unit Badge tracks for check-in. **Template**: The visual design Badge prints for each attendee. Includes name, company, role, photo, QR code, and any custom elements. See [Editor overview](/badge/templates/editor-overview). **Access code**: A 6-character code (letters + digits) unique to one Badge event. Lets your check-in staff open the mobile station at `/badge/staff/` without signing in to TalkValue. See [Access codes](/badge/concepts/access-codes). **Station**: A Badge surface for the venue. **Check-in mode** is the mobile QR scanner staff use at the door; **Station mode** is the desktop print station that auto-prints badges as attendees are checked in. ## Spark entities **Digest**: The daily Slack message Spark posts to your community channel. Curated industry news scoped to 1–3 categories you pick. See [Digest schedule](/spark/digest-schedule). **Wall**: A live Slack channel mirror designed for venue TVs. Each wall renders one Slack channel at a public no-login URL you can open on any screen. See [Walls overview](/spark/walls/overview). **Reach**: Spark's competitive social tracking surface. Compares your community's reach across channels against competitors you pick. See [Reach overview](/spark/reach/overview). ## Billing **Pro plan**: TalkValue's single paid plan, \$299 per month per workspace, billed monthly. Includes Path, Badge, Spark, and the CLI. See [Plans, trial, and Pro](/administration/billing/plans-trial-pro). **Trial**: A 7-day window that unlocks everything in Pro. Starts on sign-up, converts automatically to Pro on day 8 unless canceled. A card is required up front; no charge during the trial. ## Integrations **Integration**: An external account connected to TalkValue through OAuth. **Eventbrite** and **Luma** sync events and attendees into Path and Badge; **HubSpot** and **Slack** import channels into Path. Connect them from Settings → Integrations. See [Eventbrite connect](/platform/integrations/eventbrite), [Luma connect](/platform/integrations/luma), [HubSpot connect](/platform/integrations/hubspot), and [Slack connect](/platform/integrations/slack). ## Related * [Path concepts](/platform/concepts/data-model). The entity model in depth. * [Choose your product](/get-started/choose-your-product). Pick where to start based on your goal. # Security and trust Source: https://docs.trytalkvalue.com/administration/security-and-trust How TalkValue protects your data: certifications, encryption, access controls, subprocessors, and responsible disclosure. TalkValue is built for B2B event teams, which means we hold attendee identity data, contact information, and the analytics derived from it. This page covers the controls and certifications that govern how that data is stored, processed, and accessed. ## Certifications TalkValue holds three independent ISO certifications, all issued on **2023-12-11**: | Standard | Scope | | ------------- | ------------------------------- | | **ISO 9001** | Quality Management Systems | | **ISO 27001** | Information Security Management | | **ISO 37301** | Compliance Management Systems | Each certification covers the design and operation of TalkValue's product, infrastructure, and supporting business processes. For an audit copy or the certificate PDFs, contact [security@trytalkvalue.com](mailto:security@trytalkvalue.com). ## Encryption Data is encrypted everywhere it lives and everywhere it moves: * **In transit.** All traffic to `app.trytalkvalue.com`, the TalkValue API, and the public docs at `docs.trytalkvalue.com` is served over TLS 1.2 or higher. HTTP traffic redirects to HTTPS at the edge. Internal service-to-service traffic in our infrastructure is encrypted as well. * **At rest.** Application databases, file storage, and backups are encrypted at rest using industry-standard AES-256 (or equivalent) symmetric encryption. Encryption keys are managed by the cloud provider's key-management service and rotated on the provider's schedule. Backups are stored encrypted in the same region as the primary data, with retention sufficient to recover from operational incidents without manual intervention. ## Access controls Access to your workspace data is enforced at three layers: * **Workspace isolation.** Every request is scoped to the workspace in the caller's session, so data belonging to another workspace is never reachable. Within a workspace, the **Admin** and **Member** roles determine which surfaces the app exposes — billing and member management are Admin surfaces. See [Roles and permissions](/administration/workspace/roles-and-permissions) for the full capability matrix. * **Authentication.** TalkValue supports magic link email and Google sign-in. Both use industry-standard identity protocols. There is no shared-secret password to leak. See [Login methods](/administration/account/login-methods). * **Internal access.** TalkValue staff access to production systems is restricted to a small on-call team, gated by role-based access in our identity provider, and logged. Access to customer data is granted only on documented support need, with the customer's consent where the request originates from the customer. ## Subprocessors TalkValue uses a small set of subprocessors. Each holds its own certifications appropriate to its function: * **Cloud hosting and database.** Production infrastructure and storage. * **Identity provider.** Sign-in flows and session tokens for magic link and Google. * **Payment processor.** Card data, billing, and invoicing. TalkValue holds only the payment-method reference, never raw card numbers. * **AI provider.** Powers the in-app AI assistant. Workspace data is processed under terms that prohibit training on customer content. * **Email delivery.** Magic-link codes, invitations, billing receipts. * **Customer support tooling.** Routes incoming support conversations. * **Product analytics.** Usage signals used to improve TalkValue, no workspace content. For the current named list and hosting regions, contact [security@trytalkvalue.com](mailto:security@trytalkvalue.com). Subprocessors are reviewed annually; material changes are communicated to workspace Admins. ## Customer data ownership Workspace data (events, people, channels, badges, templates, Spark digests, tags) belongs to your workspace. TalkValue is the data processor, not the data owner. You can export it any time (see [Export your data](/administration/export-your-data)). ## Responsible disclosure Report security issues directly to [security@trytalkvalue.com](mailto:security@trytalkvalue.com). Include a description of the issue and its impact, reproduction steps, and your suggested severity. We acknowledge reports within 2 business days and follow up with remediation timing once reproduced. Researchers are credited by name on request once the issue is resolved. When investigating, don't run automated scanners against `app.trytalkvalue.com` without coordinating first, access customer data beyond the minimum needed to demonstrate the issue, or disclose publicly until we've confirmed a fix. ## Status and incidents For live operational status, see [status.trytalkvalue.com](https://status.trytalkvalue.com). Post-incident summaries are posted there once resolved. ## Related * [Export your data](/administration/export-your-data). Pull a workspace copy any time. * [Roles and permissions](/administration/workspace/roles-and-permissions). In-product access control. * [Login methods](/administration/account/login-methods). How authentication works for end users. * [Delete your account](/administration/account/delete-account). End-of-life for account-level identity data. # General Source: https://docs.trytalkvalue.com/administration/workspace/general Edit your workspace name, leave the workspace, or delete it permanently. The **General** tab under Settings is where you rename the workspace, leave it, or (as an Admin) delete it. Everything here is scoped to the workspace you currently have selected from the chip in the top-left header. ## Where it lives **Settings → General** is the first item under **Organization** in the Settings side panel, below the **Account** group. The page is two panels: * **Workspace details.** The workspace logo, the editable workspace name, and the workspace domain when one is set. * **Danger zone.** **Leave workspace** (any role) and **Delete workspace** (Admin only). A Member sees **Leave workspace** in the danger zone; an Admin sees both rows. The danger zone panel is outlined in red so the destructive actions are unmistakable. ## Workspace name The name shows up in the workspace chip in the top-left header, in the workspace switcher dropdown, on the **Members** page, and in invitation emails. Every member sees the same name; it's per-workspace, not per-user. Click **Settings** at the bottom of the left icon rail, then **General**. Type the new name. Leading and trailing whitespace is trimmed when you save. A toast confirms **"Settings saved"** when it completes. The new name takes effect for every member on their next page load. Only Admins can edit the workspace name. ## Workspace logo and domain The logo is resolved from your workspace domain, so it updates on its own when the domain is set — there's nothing to upload. The domain row shows the domain your workspace is registered under, with a **Verified** badge once it's confirmed. A verified domain is what lets teammates signing in with that email domain be matched to your workspace. The row only appears when a domain is set. ## Leave workspace **Leave workspace** removes you from this workspace alone. Your TalkValue account stays active, and you remain a member of any other workspaces you belong to. Clicking **Leave workspace** opens a confirmation dialog. After you confirm, TalkValue switches you to one of your other workspaces. If you don't have any remaining workspaces, you're routed to the create-workspace screen. If you're the **only Admin** of a workspace, you cannot leave. Promote another member to Admin first on **Settings → Members**, then come back to leave. See [Roles and permissions](/administration/workspace/roles-and-permissions) for how to change a role. ## Delete workspace (Admin only) **Delete workspace** is the irreversible end-of-life action. It removes every event, person, channel, badge, template, and Spark digest in the workspace. Every member loses access immediately. A confirmation dialog opens with the workspace name and a warning banner. Type the exact workspace name in the confirmation field. The red **Delete workspace** button stays disabled until the text matches. The workspace is deleted. You're switched to one of your other workspaces, or routed to the create-workspace screen if none remain. There is no undo window. If you want a copy of your data first, see [Export your data](/administration/export-your-data). ## Related * [Members](/administration/workspace/members). Invite, remove, and change roles. * [Roles and permissions](/administration/workspace/roles-and-permissions). Capability matrix for Admin and Member. * [Export your data](/administration/export-your-data). Pull a copy before deletion. * [Delete your account](/administration/account/delete-account). End-of-life for the account, not just one workspace. # Members Source: https://docs.trytalkvalue.com/administration/workspace/members Invite teammates, change their role, remove them, or revoke a pending invitation. The **Members** tab under Settings is where Admins manage who can sign in to the workspace and what role they hold. Members see the same table read-only. ## Where it lives **Settings → Members** is the third item in the Settings side panel. The page has two sections: * **Members** table at the top: everyone who currently has access. * **Pending Invitations** table below: invitations that have been sent but not yet accepted (Admins only, only when there's at least one pending invitation). Admins also see an **Invite Member** button in the top-right of the page header. Members see the button disabled. ## Members table Each row shows a member of the workspace: | Column | What it shows | | ------- | --------------------------------------------------------- | | Member | Avatar, full name (or email if no name is set), and email | | Role | Badge: **admin** or **member** | | Status | Pill: **active** or **pending** | | Joined | The date the membership was created | | Actions | Admins only: per-row menu with role and removal actions | The list updates the moment an Admin makes a change; no manual refresh. ## Invite teammates Click **Invite Member** in the top-right to open the invitation dialog. Fill in: * **Email address.** Where the magic link invitation is sent. * **Role.** **Member** or **Admin**. Members can be promoted later from the row menu. Click **Send Invitation**. A toast confirms **"Invitation sent"** and the new entry appears in the **Pending Invitations** table. For the full invite walk-through with screenshots, see [Invite teammates](/get-started/workspace/invite-teammates). ## Change a role Open the actions menu on a member's row (Admins only). The menu shows context-appropriate items: * **Make Admin.** Appears for any Member. Promotes them to Admin. * **Make Member.** Appears for any Admin who isn't the last one. Demotes them to Member. * **Remove Member.** Removes them from the workspace. You cannot demote yourself if you're the only Admin in the workspace; the **Make Member** item is hidden in that case. Same for **Remove Member** on your own row. ## Remove a member Open the actions menu on a member's row and click **Remove Member**. A confirmation dialog asks you to confirm. After you confirm, the member loses access immediately and is removed from the table. Workspace data created by the removed member (events, people, channels, badges) stays with the workspace. ## Pending Invitations Each row in the **Pending Invitations** table shows a sent-but-not-accepted invitation: | Column | What it shows | | ------- | ------------------------------------------------------ | | Email | The address the invitation was sent to | | Status | **pending** — the invitation is waiting to be accepted | | Sent | When the invitation was created | | Expires | When the invitation token expires | | Actions | Revoke button (X icon) | ### Revoke an invitation Click the **X** button on a pending row. A confirmation dialog asks you to confirm. After you confirm, the invitation token is revoked and the row leaves the table. The recipient can no longer use the link to join. If you want them in after all, send a fresh invitation from the **Invite Member** button. To re-deliver an invitation, revoke the pending one and send a fresh one from the **Invite Member** dialog. ## Related * [Invite teammates](/get-started/workspace/invite-teammates). Walk-through for sending an invitation. * [Roles and permissions](/administration/workspace/roles-and-permissions). What Admin and Member can each do. * [General](/administration/workspace/general). Workspace lifecycle: name, leave, delete. * [Profile](/administration/account/profile). Your own role and identity across workspaces. # Roles and permissions Source: https://docs.trytalkvalue.com/administration/workspace/roles-and-permissions What Admin and Member roles can do in a TalkValue workspace. A TalkValue workspace has two roles: **Admin** and **Member**. Every member of a workspace is one or the other. Your role is set when you're invited and can be changed any time by an Admin on **Settings → Members**. Your role is **per-workspace**. You can be an Admin in one workspace and a Member in another; switching workspaces switches your effective role. ## Capability matrix | Capability | Admin | Member | | ------------------------------------------------------------------- | :---: | :----: | | Sign in and use Path, Badge, and Spark | Yes | Yes | | Read all workspace data (events, people, channels, badges, digests) | Yes | Yes | | Create and edit events, people, channels, tags | Yes | Yes | | Run badge check-ins | Yes | Yes | | Author Spark digests and walls | Yes | Yes | | Use the in-app AI assistant (Cmd+I) | Yes | Yes | | Invite teammates | Yes | No | | Change member roles | Yes | No | | Remove a member | Yes | No | | Revoke a pending invitation | Yes | No | | Edit the workspace name | Yes | No | | Leave the workspace | Yes | Yes | | Delete the workspace | Yes | No | | Connect or disconnect Eventbrite, Luma, HubSpot, Slack | Yes | Yes | | Open the **Billing** tab | Yes | No | | Update payment method, manage subscription, cancel | Yes | No | | Resubscribe after expiration | Yes | No | | Export workspace data (people CSV, etc.) | Yes | Yes | ## What "Admin" means in practice Admins own the workspace shell: billing, membership, and lifecycle. If everyone wants to be hands-on with data while only a few people hold the workspace itself, leave most people as Member. A workspace must have **at least one Admin** at all times. TalkValue prevents the last Admin from demoting themselves or leaving the workspace. To leave when you're the only Admin, promote another member first. ## What "Member" means in practice Members work with the product itself: events, people, channels, badges, integrations, Spark, and the AI assistant. Admins additionally own membership and billing. Member is the right role for most teammates. ## Change a role Open **Settings → Members** as an Admin. On the row of the person you want to change, open the **Member actions** menu (three dots) and pick: * **Make Admin.** Promotes a Member to Admin. * **Make Member.** Demotes an Admin to Member. Hidden when there's only one Admin in the workspace. The role change takes effect immediately on the next page load for that person. ## Request a role change If you're a Member and need Admin to do something specific (open billing, invite a new teammate), the fastest path is to ask any current Admin to make the change for you directly, or to promote you temporarily. Open **Settings → Members** to see who the current Admins are. ## Related * [Members](/administration/workspace/members). Open the members table and the role action menu. * [Invite teammates](/get-started/workspace/invite-teammates). Send an invitation with a starting role. * [General](/administration/workspace/general). Where the workspace lifecycle actions live. * [Plans, trial, and Pro](/administration/billing/plans-trial-pro). Billing requires the Admin role. # Access codes Source: https://docs.trytalkvalue.com/badge/concepts/access-codes How the 6-character staff access code works and what staff can do with it. Every event has a unique **6-character access code** (letters + digits) that lets your staff open the mobile check-in station without signing in to TalkValue. The code is scoped to one event and never grants dashboard access. TalkValue separates two Badge audiences. **Event managers** use the dashboard at `app.trytalkvalue.com` to import events, design templates, and pair printers. That requires a TalkValue login. **Check-in staff** use the mobile station at `app.trytalkvalue.com/badge/staff/`. That requires only the 6-character access code, on any phone or tablet, with no login. ## What the code unlocks When a staff member enters a valid access code at `/badge/staff`, TalkValue looks up the event the code belongs to and routes them to a mode picker for that single event. From there they can: * Pick **Check-in mode** for mobile-optimized QR scanning and manual search check-in. * Pick **Station mode** for a desktop print station that auto-prints badges as attendees are checked in from paired phones. Staff never see other events, the workspace settings, or any data outside the event the code unlocks. The session is per-tab. Closing the browser ends it without persisting credentials. ## Where to find the code Open the event page in the Badge dashboard. The **Staff Access** card shows: * A QR code that links straight to `/badge/staff/` (scan with any phone camera to skip typing). * The 6-character code in a monospace block, with a **Copy** button next to it. * The full staff URL formed as `app.trytalkvalue.com/badge/staff` (where staff type the code) or as a deep link via the QR. Two action buttons in the page header — **Station mode** and **Check-in mode** — open the same mode directly from the dashboard, so you can preview what staff will see before handing the code over. ## Sharing with staff Codes are short, case-insensitive (the staff input uppercases as you type), and safe to share in writing: Slack, SMS, or printed on the brief. The code stays valid for the life of the event. For a longer share-and-handoff playbook (QR posters, day-of staffing tips), see [Get the access code](/badge/staff-stations/get-access-code). ## Security model * One code unlocks one event. Staff cannot pivot to other events or workspace settings from the staff URL. * Codes are not workspace-wide; every event has its own code. * Codes are tied to the event record and stay valid for the life of the event. * All staff actions (check-ins, prints) are logged against the event for the audit trail. ## Related * [Get the access code](/badge/staff-stations/get-access-code). The day-of share, post, and handoff playbook for check-in staff. * [Open on mobile](/badge/staff-stations/open-on-mobile). What staff see when they type the code on a phone. * [QR scan check-in](/badge/staff-stations/qr-scan-checkin). The camera-based check-in flow. * [Manual search check-in](/badge/staff-stations/manual-search-checkin). The fallback when the QR can't be scanned. # Events, attendees, templates Source: https://docs.trytalkvalue.com/badge/concepts/events-attendees-templates The three core entities in Badge and how they relate. TalkValue organizes Badge check-in around three entities: an **event** holds a list of **attendees** imported from your provider, and a set of **templates** decides what each attendee's printed badge looks like. Badge is built around three entities. Every check-in, every printed badge, and every staff station you set up traces back to one of them. These three entities underlie imports, templates, and staff handoff. ## Events An **event** is a single gathering linked to one external source. Each event has a name, a date range, a timezone, an integration provider (Eventbrite or Luma), a 6-character access code for staff, and a sync status that says whether attendee data is flowing. Events are not created from scratch inside Badge. You bring them in from a connected provider via the **Import Event** dialog. Once imported, the event lives on the Badge dashboard with stats, a staff access card, and a templates section. Example: `Q2 Customer Day` on May 22 in San Francisco, imported from Eventbrite, sync status `ACTIVE`, access code `K9F2QT`. ## Attendees An **attendee** is one registration on one event. Each attendee carries an email, optional name fields, company and job title, a ticket name (the ticket type they bought), a barcode or ticket ID, a VIP flag, and a check-in timestamp once they arrive. Attendees stream in as the import job runs and continue updating while sync is `ACTIVE`. New registrations, cancellations, and field edits made on the provider side flow through automatically. Staff check in attendees from the mobile station; VIPs are flagged so you can spot them on the table and apply a different template if you want. Example: Maya Chen, `maya@northwind.io`, ticket `Founder Pass`, VIP, checked in at 9:14 AM. ## Templates A **template** is the printed badge layout for an event. Each event starts with a **Default badge** that applies to every ticket type, and you can add **variant** templates that apply to specific ticket types. For example, a different layout for `Founder Pass` versus `General Admission`. Each ticket type belongs to one template, so assigning a ticket to a new variant moves it off the old one. Templates are designed in the visual editor: text, image, QR, and rectangle elements positioned on the label. Text elements can be bound to attendee fields (full name, company, job title, ticket name, ticket ID, barcode), so the same template renders correctly for every attendee. Example: a Default badge with a logo, the attendee's full name in 14 mm type, company in 6 mm type, ticket name in a colored bar, and a QR with the attendee's barcode. ## How they relate An event contains attendees, and every event has a Default badge. When a staff station prints, TalkValue matches the attendee's provider ticket ID against each variant's assigned tickets, then falls back to the Default badge. Matching on the ticket ID keeps variants attached after you rename a ticket type on the provider. ``` Event ──► Attendees ──┐ │ ├──► Printed badge └────► Templates ─────┘ │ ├── Default (all tickets) └── Variant (assigned tickets) ``` ## Related * [Access codes](/badge/concepts/access-codes). How staff get into a mobile station without signing in. * [Sync status](/platform/concepts/sync-status). What `PENDING` / `ACTIVE` / `FAILED` / `DISCONNECTED` mean for an event. * [Add an event](/badge/events/create). The Import Event dialog from start to finish. * [Editor overview](/badge/templates/editor-overview). The visual template editor. # Add an event to Badge Source: https://docs.trytalkvalue.com/badge/events/create Import an event from Eventbrite or Luma using the provider picker so Badge can start syncing attendees. Badge events are imported from a connected provider (Eventbrite or Luma) through the **Import Event** dialog. Once an event is in Badge, it carries a date range, a timezone, an integration provider, a 6-character staff access code, and a sync status. There is no separate "create event" form; the event entity is owned by the provider and mirrored into Badge. **Before you start** * A TalkValue workspace account with access to **Settings → Integrations**. See [Members](/administration/workspace/members). * At least one **CONNECTED** integration in **Settings → Integrations**. See [Connect Eventbrite](/platform/integrations/eventbrite) or [Connect Luma](/platform/integrations/luma). * The event must exist in your Eventbrite or Luma account before you can import it. ## Add the event Sign in at [app.trytalkvalue.com](https://app.trytalkvalue.com), open **Badge** in the side panel, and click **Import Event** in the page header. The Import Event dialog opens. The dialog shows a provider picker with one row per supported provider: **Eventbrite** and **Luma**. Each row is one of: * **Connected.** Shows the account email and a **Select** action. Click **Select** to load events from that account. * **Not connected.** Shows a **Connect** action. Click it to authorize the provider inline, then continue. The dialog switches to the events list for the chosen provider. Each row shows the event name and an **Import** button, except events already imported, which show **Imported** instead. Click **Import** on the event you want. Badge confirms with a toast (`"Import started"` and the event name) and the dialog closes. Your dashboard refreshes and the new event appears with sync status `PENDING` while attendees are pulled in the background. Click the new event card. If the import job is still running, the event page shows an **Import in progress** view with live progress. When the import completes, the page swaps to the full event view with stat cards, the staff access code, and a default badge template. ## What you get when an event lands Once the import completes, the event detail page shows: * **Header.** Event name, provider badge, sync status indicator, and date range in the event's timezone. * **Action bar.** **Sync** (manual sync), **Station mode** (open the desktop print station), **Check-in mode** (open the mobile check-in station). Both station and check-in mode links use the event's access code so you can preview what staff will see. * **Stat cards.** Total Attendees, Checked In Today, Total Checked In. * **Staff Access.** The 6-character access code, the staff URL, and a QR. See [Get the access code](/badge/staff-stations/get-access-code). * **Badge Template.** Preview of the default template with a **Manage** button to open the [editor](/badge/templates/editor-overview). * **Attendees.** Paginated table of every attendee with check-in status and VIP flag. ## Re-importing or replacing an event If you imported the wrong event or want to recover one whose sync severed, the recovery dialog is the same UI: * **DISCONNECTED** events show an alert with a **Reconnect** button. See [Recovering from disconnect](/badge/events/recovering-from-disconnect). * **FAILED** events show a **Retry** button with the same dialog. Importing the same event a second time doesn't duplicate it. Once `imported` is true on a candidate, the **Import** button is replaced with **Imported**. ## Related * [Events, attendees, templates](/badge/concepts/events-attendees-templates). The three core entities and how they relate. * [Sync status](/platform/concepts/sync-status). What `PENDING` / `ACTIVE` / `FAILED` / `DISCONNECTED` mean on the event card. * [Import attendees](/badge/events/import-attendees). How attendees flow in after import and how to resync mid-event. * [Recovering from disconnect](/badge/events/recovering-from-disconnect). Reconnect an event when the credential is severed. # Import attendees Source: https://docs.trytalkvalue.com/badge/events/import-attendees How attendees flow into a Badge event from Eventbrite or Luma, and how to resync mid-event. Attendees enter Badge through the same import that brings the event in. Once an event lives in Badge, it stays connected to the provider. New registrations, cancellations, and edits made on Eventbrite or Luma flow through automatically while sync is `ACTIVE`. This page walks the initial import, the live sync that follows, and the manual resync you'll want during the event. **Before you start** * The event must already be added to Badge. See [Add an event](/badge/events/create). * The integration that owns the event must be **CONNECTED** in **Settings → Integrations**. * A TalkValue workspace account. ## Initial import When you click **Import** in the Import Event dialog, Badge starts an import job in the background. The job pulls every existing attendee from the provider in one pass. Open the new event from the Badge dashboard. While the job is running, the event page shows an **Import in progress** view with live counts that update without a refresh. Once the job finishes, the page swaps to the full event view. The **Total Attendees** stat card shows the imported count, and the **Attendees** table at the bottom lists every row. You don't have to wait on the event page — if you're on the Badge dashboard when the job finishes, a toast confirms the import with the event name and the final attendee count. If the import stops mid-flight, the event lands in sync status `PENDING` with no active job and surfaces an **Import failed** alert. Click **Retry** in the alert to restart from scratch. The dialog routes through the same provider-picker UI. ## Live sync after import After the initial import, sync status flips to `ACTIVE`. Badge keeps the attendee table in sync with the provider: * **New registrations** appear in the table automatically as they're created on Eventbrite or Luma. * **Edits** to attendee fields (name, ticket type, etc.) update in place. * **Cancellations** mark the attendee as `NOT_ATTENDING`. * **The Attendees table refreshes itself** every 30 seconds while sync is `ACTIVE`, so the table stays current without a page reload. A green **Synced** indicator in the event header confirms the link is live. If it disappears, check the status alerts described in [Sync status](/platform/concepts/sync-status). ## Manual resync On event day you sometimes want a hard pull instead of waiting for the next live update. For example, a registration was just edited on the provider and you need the row to be current at the check-in desk. Click **Sync** in the event page header. Badge runs a one-shot resync that refreshes the attendee list, the event totals, and the check-in statistics. The button reflects the in-flight state and re-enables when the resync completes. ## Provider-side rules The same uniqueness and import rules that apply when [adding an event](/badge/events/create) apply to attendees: * **Eventbrite.** Attendees come from the event's `Orders` API. Each registration that has a ticket becomes one attendee row. * **Luma.** Attendees come from the event's guest list. Each guest becomes one attendee row. * **Ticket name.** The provider's ticket type carries over as the attendee's `ticketName`, which a template can bind to a text element. See [Events, attendees, templates](/badge/concepts/events-attendees-templates) for how variants attach to ticket types. * **VIP flag.** Toggled from inside Badge per attendee. The flag persists across syncs and is not overridden when the provider updates other fields. ## Troubleshooting ### Sync stays `PENDING` and nothing happens The initial import never completed. Click **Retry** in the **Import failed** alert on the event page, or open the Import Event dialog from the Badge dashboard and re-pick the event. ### Sync flips to `DISCONNECTED` mid-event The integration credential was revoked on the provider side or the OAuth token expired. Follow [Recovering from disconnect](/badge/events/recovering-from-disconnect): reconnect the provider in **Settings → Integrations**, then reconnect the event. ### New registrations don't appear Confirm the event header shows the green **Synced** indicator. If it does, click **Sync** to force a fresh pull. If rows still don't appear, wait for the provider to publish the registration, then click **Sync** again. ## Related * [Add an event](/badge/events/create). The Import Event dialog that started this whole flow. * [Sync status](/platform/concepts/sync-status). `PENDING` / `ACTIVE` / `FAILED` / `DISCONNECTED` reference. * [Recovering from disconnect](/badge/events/recovering-from-disconnect). Reconnect when the integration is severed. * [Connect Eventbrite](/platform/integrations/eventbrite). Re-authorize the Eventbrite integration if needed. * [Connect Luma](/platform/integrations/luma). Re-authorize the Luma integration if needed. # Recovering from disconnect Source: https://docs.trytalkvalue.com/badge/events/recovering-from-disconnect Restore attendee sync for a DISCONNECTED, FAILED, or stuck PENDING event. Events lose their live sync for two main reasons: the integration's OAuth token was revoked on the provider side, or the initial import never finished. Badge surfaces both as a banner alert at the top of the event page with a one-click recovery action. This page walks each path. **Before you start** * A TalkValue workspace account with access to **Settings → Integrations**. * For a `DISCONNECTED` event: a working integration of the same provider in **Settings → Integrations**, in `CONNECTED` state. If the integration is also disconnected, reconnect the provider first via [Connect Eventbrite](/platform/integrations/eventbrite) or [Connect Luma](/platform/integrations/luma). ## Recognize the state Open the event page in the Badge dashboard. The alert banner at the top tells you what happened: | Alert title | Sync status | Trigger | Recovery action | | ---------------------------- | ------------------------- | ------------------------------------------------------- | --------------- | | **Integration disconnected** | `DISCONNECTED` | OAuth credential severed on provider side | **Reconnect** | | **Sync failed** | `FAILED` | Last sync attempt errored (transient or provider issue) | **Retry** | | **Import failed** | `PENDING` (no active job) | Initial import did not complete | **Retry** | The button label changes (`Reconnect` vs `Retry`), but every path opens the same recovery dialog. Background details on each status are in [Sync status](/platform/concepts/sync-status). ## Reconnect a DISCONNECTED event On the event page, click **Reconnect** in the **Integration disconnected** banner. The Reconnect dialog opens. The dialog looks up `CONNECTED` integrations of the same provider as this event: * **One found.** The dialog shows the integration as a card with the account email and a green **Connected** badge. Click **Reconnect with this account** to re-link the event. * **None found.** The dialog shows an empty state with a **Go to integrations** button. Open **Settings → Integrations**, reconnect the provider, return to the event, and click **Reconnect** again. Badge confirms with a toast (`"Reconnecting event"`) and refreshes the page. The event flips to `PENDING` while a fresh re-import runs in the background; when complete, status returns to `ACTIVE`. ## Retry a FAILED sync A `FAILED` event is a temporary problem. The integration is still healthy, but the last sync attempt errored. On the event page, click **Retry** in the **Sync failed** banner. The recovery dialog opens with the same connected-integration card shown for `DISCONNECTED`. Click **Reconnect with this account**. Badge re-runs the sync. The toast confirms `"Reconnecting event"` and the page refreshes with the latest data. If `FAILED` returns immediately after a retry, the underlying issue is likely on the provider's side or with the integration credential. Contact [support](mailto:support@trytalkvalue.com) with the event name and the timestamp of the failure. ## Retry a stuck PENDING import While an import runs, `PENDING` is the expected state and the event page shows live progress. If `PENDING` persists with no active job, the initial import never completed. On the event page, the banner reads **Import failed** with a **Retry** button. Click it. The recovery dialog opens with a slightly different title (**Set Up Sync**) but the same connected-integration card. Click **Reconnect with this account**. Badge starts a fresh import job and the toast confirms `"Retrying import"`. The event page returns to the **Import in progress** view until the new job completes. ## Troubleshooting ### No integration found in the Reconnect dialog The dialog filters to integrations in `CONNECTED` state only. A `DISCONNECTED` integration in **Settings → Integrations** won't appear. Reconnect the provider first, then try again. ### Reconnecting succeeds but sync stays DISCONNECTED The integration credential is healthy on the TalkValue side but the provider rejected it again, usually because permission was revoked on the provider's dashboard or the OAuth scope was reduced. Reconnect the provider from scratch, then run **Reconnect** on the event one more time. ## Related * [Sync status](/platform/concepts/sync-status). The full status reference behind every alert. * [Add an event](/badge/events/create). Start fresh if you'd rather re-add the event than reconnect. * [Connect Eventbrite](/platform/integrations/eventbrite). Fix the upstream Eventbrite integration. * [Connect Luma](/platform/integrations/luma). Fix the upstream Luma integration. * [Import attendees](/badge/events/import-attendees). What the resync actually does once it runs. # Badge Source: https://docs.trytalkvalue.com/badge/index Event check-in with custom badges, a template editor, and a mobile staff station. Badge handles the full event check-in flow: import an event from Eventbrite or Luma, design printable badges in the visual template editor, and hand a 6-character access code to your staff for mobile check-in. Import an event and its attendees. Design printable badges with text, images, QR codes, and lines. Mobile check-in via 6-character access code, QR scan, or manual search. ## Next step Import an event, design a template, and check in your first attendee. # Calibration and troubleshooting Source: https://docs.trytalkvalue.com/badge/printer-setup/calibration-troubleshooting Fix the print problems you'll see on event day — blank prints, misalignment, two-label spillover, and ribbon issues. Print problems on event day are almost always one of four things: the loaded label stock doesn't match the template size, the printer hasn't been calibrated to the label gap, the darkness is set wrong for the media, or the print head is dirty. This page walks each one and the recipe to fix it without re-pairing the printer. **Before you start** * Your printer is paired and the browser permission dialog accepted it. See [Connect a printer](/badge/printer-setup/webusb-connection). * A template is open in the editor. See [Template editor](/badge/templates/editor-overview). * Spare label rolls of the same stock, in case calibration burns through a few labels. ## The label-size mismatch (most common) Symptom: the print is shifted, lands on two labels, or leaves a large blank margin. The template's **Label size** (in millimeters) doesn't match the label loaded in the printer. Fix it in two steps: Take one label off the roll and measure it with a ruler in millimeters. Don't trust the box. Labels sold as "4 × 2 in" can be 101.6 × 50.8 mm, 100 × 50 mm, or rounded variants. In the editor's left sidebar, pick the matching preset from the **Label size** dropdown, or type the measured millimeters into **W (mm)** and **H (mm)**. The canvas resizes instantly. Click **Print test** again. The print should now land on a single label. Full reference: [Printer settings](/badge/templates/printer-settings). ## The auto-calibration recipe (gap sensing) Symptom: the print is positioned correctly on the first label but slowly drifts down (or up) on every subsequent label. The printer can't detect the gap between labels, so it advances by a fixed amount that gradually goes out of sync. Run the printer's auto-calibration once at setup. The Zebra desktop printers on the [supported printers](/badge/printer-setup/supported-zebra-models) list expose this through a button or menu: Switch the printer off at the power button. Press and hold the **FEED** button (the one that advances a label) and turn the printer back on. Keep holding **FEED**. The status light cycles through colors. Release **FEED** after one full red flash (the exact pattern varies by model, so check the printed quick-start card that came with the printer). The printer feeds a few labels, measures the gap, and stops. From the editor, click **Print test**. Prints should now land at the same vertical position on every label. If your printer has a touchscreen (ZD420, ZD620), the same routine lives under **Menu → Tools → Calibrate** or similar. Consult the model's quick-start sheet. ## Blank prints (right size, no ink) Symptom: the label feeds, the printer makes the right sound, but the label comes out blank. Two causes, listed in order of likelihood: * **Direct-thermal label loaded upside-down.** Direct-thermal labels only print on one side — the chemically treated side. Pull a label off, scratch the surface with a fingernail or coin: the side that darkens is the print side. If your loaded roll has the print side facing the wrong way, re-load with the right side facing the print head. * **Wrong label type for the printer.** Direct-thermal printers (Zebra ZD220, ZD230, etc.) cannot print on plain paper labels. If you loaded a non-thermal label roll, swap to direct-thermal stock. ## Faint or smudged prints Symptom: text and QR are readable but light, or QR codes fail to scan. The darkness is set too low for the media, or the print head needs cleaning. * **Increase darkness on the printer.** Use the Zebra Setup Utilities tool on the print-station laptop. Set darkness one or two steps higher, then re-test from the editor. Keep going until QR codes scan cleanly with a phone camera. * **Clean the print head.** Power off, open the printer, and wipe the print head with a 70% isopropyl alcohol pad in one long motion. Let it dry for 30 seconds before closing. ## Labels peel off mid-print Symptom: labels come out of the printer but won't stick to the badge backing. This is a label-stock problem, not a printer or template problem. Cold venues (under 15 °C / 59 °F) reduce adhesive tack. Bring labels to room temperature for 30 minutes before the event starts. If the venue stays cold, switch to a higher-tack label adhesive. Your label supplier can recommend a cold-temperature stock. ## The printer prints garbled characters Symptom: random characters print instead of attendee names. The printer is in the wrong language mode. Zebra desktop printers can run in more than one command-set mode; Badge expects the default Zebra mode. Open Zebra Setup Utilities, connect to the printer, and set **Programming Language** to the Zebra default. Save and re-test from the editor. ## The print station shows as Disconnected while printing Symptom: prints stop mid-event and the station chip in the check-in header flips to **Disconnected**. The browser tab closed, the laptop went to sleep, or the USB cable came loose. Reopen Station mode on the print-station laptop and reconnect the printer from the **Printer** tab of **Settings**. See [Connect a printer](/badge/printer-setup/webusb-connection). The station chip returns to **Connected** once the heartbeat resumes. ## Related * [Connect a printer](/badge/printer-setup/webusb-connection). Pair, re-pair, and the Windows driver fix. * [Supported printers](/badge/printer-setup/supported-zebra-models). Confirm your printer is on the supported list. * [Printer settings](/badge/templates/printer-settings). Set template label dimensions to match loaded stock. * [Sync status](/platform/concepts/sync-status). What `DISCONNECTED` means for an event's attendee sync and how the event recovers. # Supported printers Source: https://docs.trytalkvalue.com/badge/printer-setup/supported-zebra-models Compatible Zebra and Nemonic label printers, recommended models, and what to check before you buy. TalkValue Badge prints directly from your browser to a Zebra or Nemonic label printer. This page covers the models that are the safest pick for event badges and what specs to check before you buy. ## The short answer Any Zebra **direct thermal** or **thermal transfer** label printer in the desktop lineup works with TalkValue Badge. We recommend the **ZD220** or **ZD230** for new buyers. They're affordable, 203 dpi, USB-equipped, and built for label widths up to 4 inches (101.6 mm), which covers every preset in the template editor. If you already own a different Zebra desktop model from the table below, it works. ## Recommended models | Model | Resolution | Max label width | Where it fits | | -------------------- | -------------- | --------------- | ------------------------------------------------------------------- | | Zebra ZD220 / ZD230 | 203 dpi | 4 in (108 mm) | First-time buyers; small-to-mid events; entry-level desktop printer | | Zebra ZD420 / ZD421 | 203 or 300 dpi | 4 in (108 mm) | Daily-use desktop printer for events run year-round | | Zebra ZD620 / ZD621 | 203 or 300 dpi | 4 in (108 mm) | Faster print speed; larger event check-in rushes | | Zebra GK420d / GX420 | 203 dpi | 4 in (108 mm) | Older but widely available second-hand; still works | All of the above are **direct thermal** desktop printers. No ink, no ribbon, no toner. Direct thermal label rolls run out faster than thermal transfer, but for one-day events that's the right tradeoff: setup is plug-in-and-print, supplies are cheaper, and labels keep their print quality for the duration of the event. ## Specs to check before you buy If you're picking up a Zebra model not in the table above, confirm three things from the spec sheet: * **Zebra desktop label printer.** Industrial-class models with proprietary or alternate command-set defaults may not work out of the box. Stick to the ZD- or G-series desktop lineup. * **Connectivity: USB.** Pairing from your browser requires a USB cable to the print-station laptop. Wi-Fi-only or serial-only printers won't pair. * **Resolution: 203 dpi or higher.** 203 dpi is the default the template editor targets. 300 dpi works fine and renders slightly sharper text on dense layouts. ## Nemonic MIP printers The staff print station also pairs Nemonic MIP-series printers (MIP-001, MIP-201) over USB. Pick the printer in the browser dialog from the **Station Setup** screen, and the station renders each badge to fit the 80 mm sticky-note stock those models load. ## Where to buy Major resellers carry Zebra desktop models in every region. Search for the model name plus your country. For the US and EU, Barcodes Inc, BarcodesNW, Logiscenter, and Zebra's official store are reliable channels. For event-rental rates, reach out to local AV-rental companies that stock event-registration hardware. ## Related * [Connect a printer](/badge/printer-setup/webusb-connection). Pair your Zebra printer from the template editor. * [Calibration and troubleshooting](/badge/printer-setup/calibration-troubleshooting). Fix label-size mismatches, blank prints, and alignment issues. * [Printer settings](/badge/templates/printer-settings). Set label dimensions in the template that match your loaded label stock. # Connect a printer Source: https://docs.trytalkvalue.com/badge/printer-setup/webusb-connection Pair a Zebra label printer to TalkValue Badge directly from the template editor. Badge prints from your browser to a Zebra label printer. There is no print queue and no driver install on macOS. Plug in a supported printer, pair it from the template editor, and you can print test badges within a minute. Windows machines may need a one-time driver replacement (see Troubleshooting below). **Prerequisites** * A [supported label printer](/badge/printer-setup/supported-zebra-models) * Google Chrome browser on the print-station laptop * The print-station laptop physically next to the printer * A Badge template open in the editor for the event you're printing ## Pair the printer Plug the printer's power cable in and switch it on. Connect the printer to the laptop with a USB cable. Wait for the status light to turn solid (typically green). In TalkValue Badge, open the event, go to **Templates**, and open the template you want to print. In the editor toolbar, click **Connect printer** in the left sidebar. Chrome opens a permission dialog listing connected USB devices. Pick your printer from the dialog (it shows as the Zebra model name, for example `ZD420`) and click **Connect**. Click **Print test**. A single test badge prints within 1 – 2 seconds. When it does, the printer is paired for this session. Printer pairings are per browser profile. If you close the browser or switch profiles, you'll need to pair again. Keep the print-station laptop awake during the event. The station sends a heartbeat while it's open, and the staff check-in header shows it as **Connected** while that heartbeat is current. ## Name the print station When you have multiple printers at a venue, give each station a name that matches its physical location. For example, `Main entrance`, `VIP lounge`, or `Hall B`. The station name appears on the staff handoff card and helps your event staff route attendees to the right pick-up point. Set the name from the print station's **Setup** screen inside Station mode, before doors open. ## Troubleshooting ### The printer doesn't appear in the Chrome dialog **On macOS:** the USB cable is usually loose or the printer is still booting. Unplug, wait 5 seconds, plug back in, and click **Connect printer** again. **On Windows:** the printer is usually claimed by the default Windows print driver, which prevents Chrome from accessing it directly. Replace the driver with **WinUSB** using [Zadig](https://zadig.akeo.ie/): Download Zadig from the official site. It runs as a portable executable, no install needed. Open the **Options** menu in Zadig and check **List All Devices**. Pick your printer from the dropdown. Choose **WinUSB** as the target driver and click **Replace Driver**. Wait for the operation to finish. Restart the laptop, then run the pairing steps above again. ### Pairing succeeds but the test print is blank or misaligned The label media loaded in the printer doesn't match the template's printer settings. Open [Calibration and troubleshooting](/badge/printer-setup/calibration-troubleshooting) for the calibration recipe and label-size reference. ### The print station shows as Disconnected in the check-in header The browser tab closed, the laptop slept, or the USB cable came loose. Reopen Station mode on the print-station laptop and reconnect the printer from the **Printer** tab of **Settings**. The station chip returns to **Connected** once the heartbeat resumes. ## Related * [Supported printers](/badge/printer-setup/supported-zebra-models). Confirm your printer is on the list before pairing. * [Calibration and troubleshooting](/badge/printer-setup/calibration-troubleshooting). Fix print quality, alignment, and label-size issues. * [Sync status](/platform/concepts/sync-status). What `PENDING` / `ACTIVE` / `FAILED` / `DISCONNECTED` mean for an event's attendee sync. * [Get the access code](/badge/staff-stations/get-access-code). Share staff access for mobile check-in once printing is set up. # Badge quickstart Source: https://docs.trytalkvalue.com/badge/quickstart Add an event, design a template, pair a printer, and check in your first attendee, end to end. This walkthrough takes you from an empty Badge dashboard to a working check-in station. You add an event from Eventbrite or Luma, design a badge template, pair a Zebra label printer, and hand your staff a 6-character code for mobile check-in. **Before you start** * A TalkValue workspace account. See [Members](/administration/workspace/members). * An [Eventbrite](/platform/integrations/eventbrite) or [Luma](/platform/integrations/luma) account connected to TalkValue. * For printing: a [supported label printer](/badge/printer-setup/supported-zebra-models) and Google Chrome on the print-station laptop. ## Run the full flow Sign in at [app.trytalkvalue.com](https://app.trytalkvalue.com), open **Badge** in the side panel, and click **Import Event**. Pick **Eventbrite** or **Luma** in the provider picker, then click **Import** next to the event you want. TalkValue starts importing attendees in the background. See [Add an event](/badge/events/create) for the dialog reference. The event opens in import-progress view while attendees are pulled from the provider. When the import finishes, the event detail page appears with stat cards, the staff access code, and a default badge template. See [Sync status](/platform/concepts/sync-status) for what the status badges mean. On the event page, find the **Badge Template** card and click **Manage**, then open the default template. The visual editor opens with text, image, QR, and rectangle tools. Drop the elements you need and bind text fields to attendee data like full name, company, and ticket name. See [Editor overview](/badge/templates/editor-overview) and [Add elements](/badge/templates/add-elements). From the template editor toolbar, click **Connect printer**. Chrome opens a permission dialog. Pick your Zebra model and click **Connect**, then click **Print test** to confirm the layout. Full setup, including Windows driver tips, is in [Connect a printer](/badge/printer-setup/webusb-connection). Back on the event page, the **Staff Access** card shows a 6-character code and a QR. Share the code with your check-in staff. They enter it at `/badge/staff` on any phone or tablet. See [Get the access code](/badge/staff-stations/get-access-code) for the share-and-handoff details. Have a staff member open the staff URL, enter the access code, and pick **Check-in mode**. Scan a ticket QR with the camera. The attendee is marked checked in, and if a print station is connected, the badge prints automatically. See [QR scan check-in](/badge/staff-stations/qr-scan-checkin). ## What's next The three core entities in Badge and how they relate. What to do when an event's `DISCONNECTED` badge appears. Find attendees by name when QR scanning isn't an option. Label size presets and calibration from inside the editor. # Get the access code Source: https://docs.trytalkvalue.com/badge/staff-stations/get-access-code Find your event's 6-character staff access code in the Badge dashboard, then share the code or the QR with your check-in staff. Every Badge event has a unique 6-character access code that lets your check-in staff open the mobile station without signing in to TalkValue. This page shows where the code lives in the dashboard, what's safe to share, and how to hand it off on event day. **Before you start** * The event is created in Badge. See [Add an event](/badge/events/create). * You have a workspace role with access to the event page (any role with read access shows the **Staff Access** card). * Your staff have a phone or tablet with a modern browser (Safari on iOS, Chrome on Android). ## Open the event page Open TalkValue Badge from the dashboard, then click the event you're staffing. The event page has a **Staff Access** card in the middle of the layout, alongside the **Badge Template** card. The **Staff Access** card shows: * A QR code that links straight to the staff station for this event. * The 6-character access code in a monospace block, with a **Copy** button next to it. * A short hint: "Enter at `/badge/staff` or scan QR". ## Copy the code Click the copy-icon button next to the code. The code lands on your clipboard and a confirmation appears. The code is six characters of letters and digits (for example, `R4K8ZP`), short enough to read out over a radio if your staff already has the URL open. ## What to share with your staff You have three ways to hand off access, in order of speed: * **QR code only.** Print the **Staff Access** card or screenshot it onto a flyer. Staff scan the QR with their phone camera and land on the mode picker directly. No typing. * **Code only.** Send the 6 characters in Slack, SMS, or print them on the staff brief. Staff open `app.trytalkvalue.com/badge/staff`, type the code (the input uppercases as they type), and land on the mode picker. * **Full URL.** Send the deep link `app.trytalkvalue.com/badge/staff/` directly. Useful when staff are already on a chat app and tapping a link is faster than scanning a QR. All three end up at the same place: the event's mode picker, where staff pick **Check-in mode** or **Station mode**. See [Open on mobile](/badge/staff-stations/open-on-mobile) for what that looks like. ## Preview before handoff Two action buttons in the event page header, **Station mode** and **Check-in mode**, open the staff UI directly from the dashboard. Click either to see exactly what your staff will see after they enter the code. Use the preview to confirm the print station is connected, attendees imported correctly, and the QR scanner opens with camera permission, before doors open. ## What the code does and doesn't unlock The access code is scoped to **one event**. It does not grant any of: * Dashboard access to other events in the workspace. * Workspace settings, integrations, or billing. * The ability to delete or edit the event. * Access to attendees outside this event. What the code does grant, for any staff member who has it, is the ability to check attendees in to this event, print badges to paired print stations, and view the event's attendee list. Treat the code like an event-day password: short-lived, scoped, and fine to share with the staff team but not in a public Slack channel. ## Sharing tips for event day * **Print posters with the QR for staff-only areas.** A QR poster at the staff briefing table cuts onboarding to seconds. * **Pin the URL in your event Slack channel** so staff coming on for a later shift can find it without re-asking. * **Have a backup paper copy.** If the staff Wi-Fi network has an issue mid-event, you can still read the code aloud or hand a printed slip to a new staff member. * **The code is case-insensitive.** The staff input uppercases as they type, so `r4k8zp` and `R4K8ZP` are the same code. ## Code lifetime The access code stays valid for as long as the event exists. If you want to rotate the code mid-event for security reasons, contact support. ## Related * [Access codes](/badge/concepts/access-codes). Concept page covering the code's scope and security model. * [Open on mobile](/badge/staff-stations/open-on-mobile). What staff see when they enter the code on a phone. * [QR scan check-in](/badge/staff-stations/qr-scan-checkin). The camera-based check-in flow once staff is in. * [Manual search check-in](/badge/staff-stations/manual-search-checkin). The typed-search fallback. # Manual search check-in Source: https://docs.trytalkvalue.com/badge/staff-stations/manual-search-checkin Find and check in an attendee by typing a partial name, email, company, or ticket type — the fallback path when the QR scanner can't read a ticket. Manual search is the reliable fallback for any time the QR scan doesn't work: lost ticket, screenshot won't display, scanner can't focus, camera permission denied. The staff search bar lives at the top of the check-in screen, accepts a partial name, email, company, or ticket type, and surfaces every matching attendee in a tap-to-confirm card list. **Before you start** * You're in Check-in mode on the staff station. See [Open on mobile](/badge/staff-stations/open-on-mobile). * A print station is selected and **Connected** in the header. Without one, you can find attendees but can't queue a badge print. ## Search and check in The top of the Check-in screen has a **Search attendee…** field with a magnifying-glass icon on the left. Tap it. The on-screen keyboard opens. Start typing. The list updates as you type with a short debounce. Three or four characters usually narrows the list to a handful of matches. Search runs against name, email, company, job title, phone, ticket type, and coupon code; partial matches at the start, middle, or end all match. The **VIP** toggle next to the search field filters the list to attendees flagged as VIP. Useful when you're staffing a VIP check-in lane and only want to see priority guests. Each result is a card showing name, email, ticket type, status (pending or checked in), and VIP flag where applicable. Tap the matching card. The attendee drawer slides up with their full details. The drawer's primary action button is contextual: **Print Badge & Check In** for standard attendees, **Reprint Badge** if already checked in, **Force Check In** if marked not attending, and **Check In** when the selected station's printer is disconnected. Tap the button to confirm. A toast confirms `Checked in & printing badge` and the badge job is queued at the selected print station. The drawer also offers **Edit Badge** for fixing what prints (name, company, or job title) without modifying the attendee record. See [Edit what prints on the badge](/badge/staff-stations/qr-scan-checkin#edit-what-prints-on-the-badge); the flow is identical from search. You can clear the search by tapping the **X** on the right of the field. Clearing it returns the main view to a list of recent check-ins from this device's session. ## What the search matches A few details that come up when searching: * **Wide field coverage.** The search matches name, email, company, job title, phone, ticket type, and coupon code, so a guest who remembers only their company email or their ticket type still surfaces. * **Spaces matter the way you'd expect.** "jane smith" matches `Jane Smith`. "smith jane" doesn't; the search is left-to-right within fields. * **Email matches partial strings.** "@acme.com" surfaces every attendee on the Acme domain. Useful when a guest knows their company email but not how the ticket was registered. * **Limited to 50 results per search.** When a search is too broad to narrow down, the list caps at 50. Add a few more characters to filter further. ## Manual badge print (walk-ins and no-records) For an attendee who isn't in the list at all (a walk-in, a guest registered under a different email, or a record that was deleted), use **Manual** in the check-in header. The top-right of the check-in header has a **+ Manual** button. Tap it. A drawer titled **Print New Badge** slides up. Type the attendee's **First Name** and **Last Name** (required), pick a **Ticket Type** from the list (required), and optionally add **Email**, **Company**, and **Job Title**. The ticket types are the same ones imported into the event. Tap **Print Badge**. A toast confirms `Walk-in recorded for `. The walk-in is logged in the event's print history and stays separate from the imported attendee list. Manual prints are useful for press, vendors, sponsors, and on-site walk-ins who didn't go through Eventbrite or Luma registration. ## Cancelling a check-in via search To cancel a check-in you made earlier (wrong person, accidental tap): Type their name or email in the search field. Tap the card. The drawer shows their current status and last check-in time. Open the drawer's three-dot overflow menu — when the attendee is checked in it includes a **Cancel Check-in** action (not a primary button). Tap it to revert. The attendee's status returns to pending. Cancelling does not retrieve any printed badge. Physically retrieve and discard the badge if the cancel matters. ## Troubleshooting ### Search returns "No results found" for a name you can see in the dashboard Three checks: typo in your search, the dashboard view is filtered while the staff station is not (or vice-versa), or the attendee was added to the dashboard after the staff page loaded. The staff station refetches the attendee list on each search, so a fresh search picks up newly added attendees within seconds. ### Search returns "No VIP attendees match your search" The VIP toggle is on but the attendee isn't flagged VIP. Tap **All** next to the search field to disable the VIP filter and re-search. ### Tapping Check In shows "No barcode available" The attendee record has no barcode, common for manually-added entries or some integration imports. Use the **+ Manual** flow instead; the walk-in is logged against the event's print history. ### Tapping Check In shows "No station selected" You haven't picked a print station in the header. Tap the printer chip at the top-left of the header and pick a station. Until one is selected, check-ins can't proceed because Badge has no print destination. ### Tapping Check In shows "Check-in failed" Server-side error, usually a transient network glitch. Try again. If it persists, hand the attendee off to a teammate on a different device, since the attendee record is shared and the second device's session is independent. ## Related * [QR scan check-in](/badge/staff-stations/qr-scan-checkin). The primary scan path; manual is the fallback. * [Open on mobile](/badge/staff-stations/open-on-mobile). Load the staff URL and pick Check-in mode. * [Get the access code](/badge/staff-stations/get-access-code). Share the code with new staff joining mid-event. * [Import attendees](/badge/events/import-attendees). Confirm the attendee list is current before doors open. # Open on mobile Source: https://docs.trytalkvalue.com/badge/staff-stations/open-on-mobile Load the TalkValue Badge staff station on a phone or tablet using the 6-character access code or the deep-link QR — no login required. The staff station is the mobile-optimized check-in UI your event team uses on phones and tablets. There's no app to install and no TalkValue login. Staff load a URL, enter the 6-character access code for the event, and land on a mode picker that opens **Check-in mode** or **Station mode**. This page walks the staff side of that flow. **Before you start** * The event manager has shared the 6-character access code or the deep-link QR. See [Get the access code](/badge/staff-stations/get-access-code). * You have a phone or tablet with a modern browser. Chrome on Android and Safari on iOS are the tested combinations. * The device is on Wi-Fi or cellular data. The staff station calls TalkValue in real time on every scan and search. ## Open by URL and code This is the path staff use when they have just the code, not a QR. On the phone or tablet browser, go to `app.trytalkvalue.com/badge/staff`. The landing screen is a single card titled **Staff Access** with six empty input boxes underneath. Tap the first input and type the code. The input uppercases each character as you type, so `r4k8zp` and `R4K8ZP` are the same code. The on-screen keyboard shows letters and digits only. The instant you type the sixth character, the page shows a small **Verifying…** spinner under the inputs and checks the code against the event. A valid code routes you to the event's mode picker. An invalid code shows **Invalid access code. Please check and try again.** under the inputs and clears the boxes so you can re-enter. On the mode picker, you see the event name and date at the top, and two buttons: **Check-in mode** (mobile-optimized for scanning QR codes) and **Station mode** (desktop with automatic printing). Tap **Check-in mode** for the mobile staff flow. You'll land in the check-in workspace. See [QR scan check-in](/badge/staff-stations/qr-scan-checkin) for what happens next. ## Open by QR (faster) If the event manager printed the **Staff Access** QR or sent a screenshot: On iOS, point the built-in Camera app at the QR. On Android, point the camera at the QR. Most camera apps detect QR codes automatically. A notification appears at the bottom of the screen with the URL. The phone opens the URL in your default browser and lands directly on the event's mode picker. No code entry needed. Tap **Check-in mode** or **Station mode** as above. ## What to expect A few details that come up often: * **No login screen, ever.** The 6-character code is the only credential. If a TalkValue login screen appears, you opened the wrong URL. Go back to `app.trytalkvalue.com/badge/staff`, not `app.trytalkvalue.com`. * **The session is per-tab.** Closing the browser tab or quitting Safari ends the session. Re-opening the same URL puts you back at the code-entry screen, unless you opened by QR (in which case the deep link sends you straight to the mode picker). * **The code scopes you to one event.** You can't switch to another event from inside the staff UI; only by entering a different code on `/badge/staff`. ## Mobile setup tips A few practical setup notes for an event day: * **Use the device camera, not a separate scanner app.** The QR scanner inside Check-in mode is part of the page. It opens when you tap **Scan Ticket**. It needs camera permission, which the browser asks for the first time. Granting permission once persists for the session. * **Keep the device on Wi-Fi or cellular.** The staff station calls TalkValue on every scan and search. If the network drops mid-event, reconnect to resume. * **Turn off auto-lock for the device.** The browser tab needs to stay open for the scanner to keep working. Disable auto-lock or extend the screen timeout to the maximum. * **Charge fully before doors open.** Running the camera scanner for a few hours drains a phone battery noticeably faster than typical usage. ## Troubleshooting ### "Invalid access code" Double-check the 6 characters: `0` (zero) vs `O` (letter), `1` (one) vs `I` (capital I), `5` vs `S`. The code only accepts letters and digits, and the input pattern enforces this. If the code still rejects after a careful re-type, ask the event manager to confirm. The code may have been read off the wrong event page. ### "Failed to verify access code" The device lost network connectivity between typing the code and the server response. Reconnect to Wi-Fi or switch to cellular, then re-enter the code. ### Mode picker shows the wrong event name The code unlocks exactly one event, so a wrong event name means you typed a different code. Tap the browser back button and re-enter the right code. ### The browser keeps redirecting to a login screen You're on the wrong URL, likely `app.trytalkvalue.com` (the dashboard) instead of `app.trytalkvalue.com/badge/staff` (the staff entry). Open a fresh tab and use the exact URL above, or scan the QR. ## Related * [Get the access code](/badge/staff-stations/get-access-code). Where the event manager finds and shares the code. * [QR scan check-in](/badge/staff-stations/qr-scan-checkin). Scan attendee QR codes with the device camera. * [Manual search check-in](/badge/staff-stations/manual-search-checkin). Search by name or email when scanning fails. * [Access codes](/badge/concepts/access-codes). Concept page covering security model and scope. # QR scan check-in Source: https://docs.trytalkvalue.com/badge/staff-stations/qr-scan-checkin Use the device camera to scan an attendee's QR code, confirm details, and check them in — the fastest path on event day. QR scanning is the primary check-in path in TalkValue Badge. Staff tap **Scan Ticket**, point the camera at the attendee's QR code (printed on a ticket or shown on a phone), and confirm a single drawer to check the attendee in and queue a badge print at the paired station. End-to-end, a clean scan takes a few seconds. **Before you start** * You're in Check-in mode on the staff station. See [Open on mobile](/badge/staff-stations/open-on-mobile). * A print station is selected in the header. The header shows the station name plus a **Connected** status indicator. If it shows **No Station** or **Disconnected**, tap the printer chip and pick a station; scanning is disabled until one is selected. * The device camera is granted browser permission. The first scan attempt prompts for it. ## Scan an attendee The blue **Scan Ticket** bar is pinned to the bottom of the check-in screen. Tap it. A full-screen scanner opens with a viewfinder in the middle. The browser asks for camera access. Tap **Allow**. The viewfinder turns on and starts scanning. iOS Safari and Android Chrome remember the permission for the session. Hold the device 10 – 30 cm from the QR. The scanner reads the code and the screen transitions to the attendee drawer within a second of a clean read. There's no "snap" or shutter button; the scanner reads continuously. The drawer shows the attendee's name, email, ticket type, VIP flag, and any prior check-in time. Verify the details match the person in front of you, then tap the drawer's primary action to confirm. The button is contextual: **Print Badge & Check In** for standard attendees, **Reprint Badge** if already checked in, **Force Check In** if marked not attending, and **Check In** when the selected station's printer is disconnected. A toast confirms `Checked in & printing badge` and the badge job is queued at the selected print station. Spot a typo in the details? Fix what prints before confirming — see [Edit what prints on the badge](#edit-what-prints-on-the-badge). The scanner stays open after confirming a check-in, ready for the next person. Tap **Close Scanner** to return to the check-in screen, or keep pointing at the next QR. The scan delay between consecutive reads is 2 seconds, which keeps the scanner from double-firing on the same QR if it lingers in the viewfinder. ## What the QR encodes The QR on the printed ticket or in the attendee's email encodes the **barcode** that uniquely identifies the attendee inside Badge. Depending on the provider, that value is a plain code or a full check-in URL — Luma tickets, for example, encode a `https://luma.com/check-in/…` link. The scanner sends whichever value it reads to the lookup, so both forms resolve to the attendee and open the drawer. Two practical consequences: * **A wrong QR shows "Attendee not found."** If a guest hands over a ticket for a different event, or an old screenshot from a previous registration, the lookup fails. Fall back to [Manual search check-in](/badge/staff-stations/manual-search-checkin). * **The same QR scans on every staff device.** Multiple staff can scan the same event independently. There's no device pairing, only the access code. ## Re-prints and force check-ins The same scan path covers two edge cases without leaving the scanner: * **Re-print.** If the attendee was already checked in, the drawer shows their prior check-in time and the action button reads **Reprint Badge**. Tapping it queues a new badge to the print station without altering the check-in record. A toast confirms `Reprint requested`. * **Force check-in.** If the ticket is marked as not attending, the drawer shows a **Not attending** warning and the action button reads **Force Check In**. Tapping it asks you to confirm. Use it when you've verified the person in front of you matches the record. The toast confirms `Force checked in & printing badge`. ## Edit what prints on the badge A misspelled name, a missing company, an outdated job title — fix it at the desk without touching the attendee record. The attendee drawer has an **Edit Badge** button above the details: A drawer titled **Edit Badge** opens, pre-filled with the attendee's current first name, last name, company, and job title. **First Name** is required; the rest are optional. Whatever you type here is what prints. Tap **Print Badge & Check In** — or **Reprint Badge** if the attendee is already checked in. The badge prints with your edits. The edits apply to this print only. The attendee record keeps its original values, and later syncs from the provider are unaffected. The print button requires a connected print station, same as any other badge job. ## Cancelling a mistaken check-in The attendee drawer also has a **Cancel Check-In** action when an attendee is checked in. Use it to undo a wrong check-in immediately. The attendee returns to the pending list. Cancelling does not retract any printed badge; physically retrieve and discard the badge. ## Troubleshooting ### "Camera permission denied" Browser blocked camera access. Open the device's site settings for `app.trytalkvalue.com`, set **Camera** to **Allow**, then retry. On iOS Safari, the toggle is in Settings → Safari → Camera → Allow. ### "No camera found" The device doesn't expose a usable camera to the browser, usually because another app holds the camera. Close any other camera-using apps (FaceTime, Zoom, Instagram), then retry. ### "Camera is in use" Another tab or app is using the camera. Close them and tap **Retry** in the scanner. ### "Attendee not found" on a valid-looking QR Three possibilities, in order of likelihood: the ticket is for a different event, the QR is from a cancelled or refunded registration that's no longer in the attendee list, or the QR is unrelated to the ticket entirely (a website link, a Wi-Fi code). Fall back to [Manual search check-in](/badge/staff-stations/manual-search-checkin) and look the attendee up by name or email. ### "No barcode available" when tapping Check In The attendee record exists but doesn't carry a barcode, common for manually-added attendees and some Luma free events. Use the **Manual** entry path from the check-in header instead, which prints a badge based on typed details. ### Scanner opens but won't pick up the QR Three quick fixes: improve lighting (a dim QR doesn't scan), hold the camera further back so the full QR fits in the viewfinder, and clean the camera lens. ### "Check-in failed" A network or server error during the check-in call. Try again. If it persists, switch to a different device on the same access code, since the attendee record is shared across all staff devices. ## Related * [Open on mobile](/badge/staff-stations/open-on-mobile). Load the staff URL and pick Check-in mode. * [Manual search check-in](/badge/staff-stations/manual-search-checkin). The typed-search fallback when the QR doesn't work. * [Get the access code](/badge/staff-stations/get-access-code). Share the access code with new staff joining mid-event. * [Connect a printer](/badge/printer-setup/webusb-connection). What the **Connected** / **Disconnected** station chip in the header means. # Add elements Source: https://docs.trytalkvalue.com/badge/templates/add-elements Text, image, QR, and rectangle elements with the full property panels for each. The template editor has four element types: **Text**, **Image**, **QR**, and **Rect**. You add them from the **Add element** row in the left sidebar, drag and resize them on the canvas, and configure their properties in the right panel. **Before you start** * A template open in the [editor](/badge/templates/editor-overview). * For text elements bound to attendee fields: an event that has at least one imported attendee, so you can preview the binding with **Preview as**. ## Add an element In the left sidebar, click **T (Text)**, **Image**, **QR**, or **Rect**. The element drops at the canvas center at a default size. Drag it into place and resize from the corner handles. Fine-tune position and content from the right property panel. ## Text Text elements display a string. The string can be **Custom** (literal text), **Attendee** (a bound field that resolves per attendee at print time), or **Question** (the attendee's answer to one of the event's registration questions). **Position.** `X`, `Y`, `W`, `H` in millimeters. Editing `H` divides by `Max lines` to keep the font size legible. **Content.** Pick a **Data type**: * **Custom.** Fixed text you type in the **Text** input. Use for static labels like an event title or sponsor name. * **Question.** Bind to one of the event's registration questions. Pick the question in the panel and the attendee's answer prints in its place. Use for dietary tags, track selection, or T-shirt size. * **Attendee.** Bind to one of these fields, which resolve per attendee at print time: | Field | What it contains | | ----------- | ----------------------------------------------- | | Full name | Attendee's combined first + last name | | First name | Attendee's first name | | Last name | Attendee's last name | | Company | Attendee's company | | Job title | Attendee's job title | | Email | Attendee's email address | | Phone | Attendee's phone number | | Ticket name | The ticket type the attendee bought | | Ticket ID | The provider's external ticket ID | | Barcode | Provider barcode (same value the QR can encode) | **Typography.** **Font size** in mm (1–50) and **Align** (Left / Center / Right). **Layout.** **Max lines** (1 or 2; controls how text wraps inside the box), **Case** transform (None / Upper / Lower / Title), **Autoscale** to shrink long values automatically so they fit. **Style.** **Invert** flips the element to white-on-black for printing on dark backgrounds. ## Image Image elements display a static image, typically a logo or sponsor mark. **Position.** `X`, `Y`, `W`, `H` in millimeters. **Image.** Drop a file in the **Source** dropzone or click **Browse**. PNG and JPEG are supported; max file size is 4.5 MB. The image is embedded directly in the template. **Monochrome threshold.** Zebra label printers are monochrome, so color and grayscale images are converted to black-and-white at print time. The threshold slider (0–255) sets which pixels become black: lower values keep less detail, higher values keep more. Adjust until the preview matches what you want printed. ## QR QR elements render a square barcode that staff or attendees can scan. **Position.** `X`, `Y` in millimeters and a single `Size` (mm) that controls both width and height since the QR is square. **QR content.** Pick a **QR type**: * **Ticket ID** encodes the provider's external ticket identifier per attendee. * **Barcode** encodes the provider's barcode value per attendee (this is what the Badge staff scanner reads to look up an attendee). * **URL** encodes a fixed URL that you enter in the **URL** field below. Use for a sponsor link, a Wi-Fi captive page, or a session schedule. * **Contact (vCard)** encodes the attendee's name, company, job title, email, and phone as a vCard, so anyone who scans the badge saves the contact straight to their phone. The right panel includes a live preview that updates as you change the type and URL. ## Rect Rect elements draw a rectangle, useful for ticket-type color bars, dividers, or framing a section of the badge. **Position.** `X`, `Y`, `W`, `H` in millimeters. **Style**: * **Filled.** Solid fill (toggle on for a color bar; off for an outline). * **Border (mm).** Outline thickness when **Filled** is off, or the inner border when **Filled** is on. Step is 0.1 mm. ## Edit and reorder The **Elements** list in the left sidebar lists every element in stacking order. Drag to reorder, click to select. Selected elements show their properties in the right panel. Delete with Delete or Backspace. Undo and Redo (⌘Z / ⇧⌘Z) cover every drag, resize, and field edit. ## Related * [Editor overview](/badge/templates/editor-overview). Sidebar layout, canvas controls, save and discard. * [Printer settings](/badge/templates/printer-settings). Label size presets and per-printer calibration. * [Connect a printer](/badge/printer-setup/webusb-connection). Pair a Zebra printer to test prints. * [Events, attendees, templates](/badge/concepts/events-attendees-templates). What attendee fields exist for text bindings. # Template editor Source: https://docs.trytalkvalue.com/badge/templates/editor-overview Open the visual badge editor, set the label size, place elements, preview with real attendee data, and save. In TalkValue's template editor you design what each printed badge looks like on a visual canvas. You set a label size, drop text, image, QR, and rectangle elements on the canvas, bind text fields to attendee data, preview the layout with a real attendee, and save. Variants attach to specific ticket types so different attendees can get different badges. **Before you start** * An event in Badge. See [Add an event](/badge/events/create). * A TalkValue workspace account. * Optional: a paired Zebra printer at this laptop if you want to **Print test** from inside the editor. See [Connect a printer](/badge/printer-setup/webusb-connection). ## Open the editor Open the event from the Badge dashboard. On the event page, find the **Badge Template** card and click **Manage**, or use the event header to go to **Templates**. You land on the **Badge templates** page. The first card on the page is the **Default badge** that applies to every ticket type. Click it to customize. Click **New template** in the page header to create a variant that targets specific ticket names instead. The editor opens in full-screen: a sidebar on the left for properties, a canvas in the middle showing the badge at scale, and a property panel on the right that shows when an element is selected. ## Anatomy of the editor The editor has a header strip on top and three regions below: * **Header.** Event name, **Undo** and **Redo** (⌘Z / ⇧⌘Z), **Discard**, and **Save** (or **Create**). * **Left sidebar.** **Name** (template name), Label size preset, ticket type picker for variants, the **Add element** row (Text / Image / QR / Rect), element list, **Preview as** selector, and the **Connect printer** button. * **Center canvas.** A scaled-to-fit preview of the label. Snaps to a 2 mm grid; elements can be dragged and resized. * **Right panel.** Element-specific properties when one is selected. See [Add elements](/badge/templates/add-elements) for the field reference. ## Set the label size Open the **Label size** dropdown in the left sidebar. Pick from common Zebra presets: | Preset | Width | Height | | -------- | -------- | -------- | | 3 × 2 in | 76.2 mm | 50.8 mm | | 4 × 2 in | 101.6 mm | 50.8 mm | | 4 × 3 in | 101.6 mm | 76.2 mm | | 4 × 6 in | 101.6 mm | 152.4 mm | For non-standard media, type the width and height directly into the **Width (mm)** and **Height (mm)** fields below the dropdown. The canvas resizes immediately. Match this to the actual label stock loaded in your printer, or prints misalign. See [Calibration and troubleshooting](/badge/printer-setup/calibration-troubleshooting) if the layout doesn't match. ## Preview with real attendees The **Preview as** combobox in the left sidebar pre-fills the canvas with sample data by default and lets you switch to any real attendee from the event: * **Sample data.** A fake `Jane Doe — Acme Corporation` so you can see the layout before importing real data. * **Attendee search.** Start typing in the combobox to search by name; pick an attendee to render every text element bound to attendee fields (name, company, ticket) with their actual values. Use **Preview as** to spot-check that long company names wrap correctly, ticket bars stay readable, and QR codes scan at this label size. ## Save, discard, and undo * **Save** (or **Create**) writes the template and routes back to the templates page. * **Discard** confirms if you have unsaved edits, then routes back. The browser also prompts on tab close. * **Undo / Redo** is ⌘Z and ⇧⌘Z. ## Print a test badge from the editor Click **Connect printer** in the left sidebar, pick your Zebra model in the browser permission dialog, then click **Print test**. A single badge prints using the current **Preview as** selection. Click the device chip when done to release the printer so the staff station can claim it on event day. Full pairing reference: [Connect a printer](/badge/printer-setup/webusb-connection). ## Related * [Add elements](/badge/templates/add-elements). Text, image, QR, and rectangle elements with their full property panels. * [Printer settings](/badge/templates/printer-settings). Label size presets and per-printer calibration from the editor. * [Connect a printer](/badge/printer-setup/webusb-connection). Pair a Zebra printer from the editor and from the staff station. * [Events, attendees, templates](/badge/concepts/events-attendees-templates). How variants attach to ticket types and which one prints for each attendee. # Printer settings Source: https://docs.trytalkvalue.com/badge/templates/printer-settings Pick a label size preset or set a custom width and height. The canvas, the preview, and every print use the same dimensions. TalkValue bakes everything the layout needs (label size in millimeters, element positions, font sizes) into the template, then renders it for the connected printer at print time. This page covers the **Label size** control in the left sidebar, where you either pick a preset or type in custom dimensions. Printer maintenance lives in the **Printer settings** dialog beside **Print test**. **Before you start** * A Badge template open in the editor. See [Template editor](/badge/templates/editor-overview). * The actual label stock you'll print on, so you can match its dimensions. ## Pick a label preset Open the **Label size** dropdown in the left sidebar. Four common Zebra presets are pre-loaded: | Preset | Width × Height (mm) | | -------- | ------------------- | | 3 × 2 in | 76.2 × 50.8 mm | | 4 × 2 in | 101.6 × 50.8 mm | | 4 × 3 in | 101.6 × 76.2 mm | | 4 × 6 in | 101.6 × 152.4 mm | The canvas resizes immediately when you pick a preset, and every element on the canvas keeps its absolute position in millimeters. A name field anchored 10 mm from the top stays 10 mm from the top on a 4 × 2 label and on a 4 × 3 label. If any elements sit off-canvas after resizing, re-position them. **Recommended default:** 4 × 2 in. It gives you three or four lines of text plus a QR code at a readable size, fits Zebra direct-thermal label rolls that are widely available, and prints fast on a 203-dpi printer. ## Set a custom size For label stock that doesn't match a preset, type the width and height directly into the **Width (mm)** and **Height (mm)** fields under the dropdown. The canvas resizes as you type, and the **Label size** dropdown shows `Custom: × mm` while a custom size is active. The minimum dimension is 2 mm. Use millimeters even if your label stock is sold in inches. The editor stores dimensions in millimeters internally and maps them to the printer's resolution at print time. ## Match the loaded label stock The single most common cause of a misaligned or blank print is a template size that doesn't match the label stock loaded in the printer. Before printing for the first time at an event: Take one label off the roll and measure width and height in millimeters with a ruler. Don't trust the box. Labels are sometimes labeled in nominal inches that round down. Pick the matching preset, or type the measured millimeters into **Width (mm)** and **Height (mm)**. Click **Connect printer**, pick your Zebra in the browser permission dialog, then **Print test**. The badge prints on a single label with no overflow and no blank space. If the test print runs onto a second label, prints blank, or shifts diagonally, open [Calibration and troubleshooting](/badge/printer-setup/calibration-troubleshooting) for the calibration recipe. ## What the template carries to the printer When you save a template, TalkValue renders those exact dimensions into a printer-ready document at print time and sends it to the printer. That means: * **Label dimensions** drive the print width and the layout grid. Every element's `x`, `y`, `width`, and `height` are converted from millimeters to printer dots. * **Element bindings** (name, company, ticket, QR) are filled in per attendee at print time, but their positions and sizes come from the template. * **Per-printer settings stay on the station.** Calibration, reset, and factory defaults run from the **Printer settings** dialog next to **Print test** in the editor, or from the **Printer** tab of the station's **Settings** dialog. Set **Printer DPI** (152, 203, 300, or 600) on each station to match the printer it drives. Every station renders the same template from the same millimeter dimensions, so a badge lands at the same physical size on any paired printer at the event. ## Related * [Template editor](/badge/templates/editor-overview). Open the editor, anatomy, save and undo. * [Add elements](/badge/templates/add-elements). Text, image, QR, and rectangle element properties. * [Connect a printer](/badge/printer-setup/webusb-connection). Pair a Zebra printer from your browser to test print from the editor. * [Calibration and troubleshooting](/badge/printer-setup/calibration-troubleshooting). Fix size mismatches, misalignment, and blank prints. # AI agents Source: https://docs.trytalkvalue.com/cli/agents/index Use the TalkValue CLI from AI coding assistants. Structured JSON output, deterministic exit codes, and 11 bundled skills. The TalkValue CLI gives AI coding agents a structured data layer for your workspace. Every command emits structured JSON, every failure mode maps to a stable exit code, and the read commands are safe to invoke without side effects. Pair the CLI with the bundled skills and any agent can list, get, update, import, and analyze workspace data without custom tooling. ## Why the CLI is agent-friendly * **Structured JSON on every command.** Pipe-detection auto-switches to JSON, or pass `--json` explicitly. Errors return a `{ "error": { "message": "..." } }` envelope on stderr. See [Output format](/cli/output-format). * **Stable exit codes.** `0` success, `2` usage, `3` authentication, `4` not found, `5` forbidden. Branch on the integer, not the prose. See [Exit codes](/cli/exit-codes). * **Idempotent reads.** Every `list`, `get`, `export`, and analysis call is a pure read. Running it twice produces the same result and never mutates state. * **Predictable mutation surface.** `create`, `update`, `delete`, `merge`, `merge-undo`, `attach`, `detach`, and `import create` are the write paths, each documented with required flags and explicit confirmation where destructive (`--confirm`). * **`llms.txt` discovery.** Fetch the [llms.txt index](https://docs.trytalkvalue.com/llms.txt) for a flat list of every docs page, suitable for embedding in an agent's retrieval layer or context window. * **Skills bundled with the binary.** 11 skill files ship inside the [GitHub repo](https://github.com/talkvalue/cli). Install them all with `npx skills add https://github.com/talkvalue/cli` and the agent can navigate the whole CLI surface without reading every doc page first. ## How an agent uses the CLI A typical agent loop looks like: ```bash theme={null} # 1. Discover IDs talkvalue path event list --json # 2. Read state talkvalue path event person list 18 --sort "joinedAt,desc" --page-size 50 --json # 3. Decide # 4. Write (with explicit confirmation on destructive paths) talkvalue path person update 142 --job-title "Director of Marketing" # 5. Verify talkvalue path person get 142 --json ``` Each step is a single CLI invocation that returns parseable JSON and a definitive exit code. The agent never needs to scrape terminal output. The 11 bundled `SKILL.md` files (7 command-group wrappers, 1 shared reference, and 3 workflow recipes) installable via `npx skills add`. Multi-step shell workflows your agent can compose: registrants, CSV import, channel analysis, jq scripting. ## Related * [Authentication](/cli/authentication). How to use `TALKVALUE_TOKEN` for headless agent runs. * [Global flags](/cli/global-flags). `--json`, `--profile`, `--api-url`, and the rest. * [Troubleshooting](/cli/troubleshooting). Common failure modes by exit code. * [llms.txt](https://docs.trytalkvalue.com/llms.txt). Flat index of every docs page. # AI agent skills Source: https://docs.trytalkvalue.com/cli/agents/skills Install the 11 bundled TalkValue CLI skills (7 command-group wrappers, 1 shared reference, and 3 workflow recipes) into any AI coding agent. The TalkValue CLI ships 11 `SKILL.md` files: one per command group, one shared reference, and one per multi-step workflow recipe. Pair them with any AI coding assistant that supports skills and the agent can navigate the entire CLI surface without reading every doc page first. ## Install everything ```bash theme={null} npx skills add https://github.com/talkvalue/cli ``` One command pulls every skill below into your agent's skill directory. Re-run any time to pick up updates. ## Install a single skill ```bash theme={null} npx skills add https://github.com/talkvalue/cli/tree/main/skills/ ``` Replace `` with the directory of the skill you want, for example, `talkvalue-person` or `recipe-csv-import`. ## Namespaced skills One skill per CLI command group, plus a shared reference. Read `talkvalue-shared` first. Every other skill expects it. | Skill | Description | Install | | -------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | | `talkvalue-shared` | Shared reference: authentication, global flags, output formats (json/table/csv), environment variables, and exit codes. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/talkvalue-shared` | | `talkvalue-person` | Manage contacts: list, get, update, delete, merge/unmerge, export, view per-person activity. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/talkvalue-person` | | `talkvalue-event` | Manage events and event participants: list, get, create, update, delete events, plus add/list/export attendees. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/talkvalue-event` | | `talkvalue-channel` | Manage marketing channels and channel members: list, get, create, update, delete, plus add/list/export members. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/talkvalue-channel` | | `talkvalue-company` | Manage companies and their contacts: list/search, get, update display name, list company contacts, export. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/talkvalue-company` | | `talkvalue-analysis` | Read-only analytics: channel-event attribution, channel audience overlap, event insights, registration trends. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/talkvalue-analysis` | | `talkvalue-import` | CSV import workflow: analyze, create jobs (UPDATE/SKIP modes), monitor status, export failed rows. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/talkvalue-import` | | `talkvalue-tag` | Manage tag labels and attach them to channels or events so analyses can be filtered with `--tag-id`. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/talkvalue-tag` | ## Recipes End-to-end workflow skills that compose the namespaced skills above. Each one matches a [Recipes](/cli/recipes/index) page in the docs. | Skill | Description | Install | | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | `recipe-new-registrants` | Pull this month's event registrants and export them for follow-up. Uses `talkvalue-event` + `talkvalue-person`. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/recipe-new-registrants` | | `recipe-csv-import` | Full CSV import workflow: analyze → create → poll status → export failed rows. Uses `talkvalue-import` + `talkvalue-channel`. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/recipe-csv-import` | | `recipe-channel-analysis` | Channel attribution and audience overlap in one report. Uses `talkvalue-analysis` + `talkvalue-channel` + `talkvalue-event`. | `npx skills add https://github.com/talkvalue/cli/tree/main/skills/recipe-channel-analysis` | ## Compose your own The recipes are deliberately small: three to five CLI invocations stitched with `jq`. Build new ones by following the same shape: discover IDs, read state, compose with `jq`, write. See the [recipes index](/cli/recipes/index) for four documented patterns. ## Related * [AI agents overview](/cli/agents/index). Why the CLI is agent-friendly. * [Recipes](/cli/recipes/index). The workflow recipes packaged as both skills and doc pages. * [GitHub: talkvalue/cli](https://github.com/talkvalue/cli). Source for every `SKILL.md` listed above. * [llms.txt](https://docs.trytalkvalue.com/llms.txt). Flat index of every docs page. # Authentication Source: https://docs.trytalkvalue.com/cli/authentication Sign in interactively in the browser or use an API token in CI. Manage multiple organizations with profiles. The TalkValue CLI supports two authentication paths so the same binary works on your laptop and in automation. Profiles let one install hold credentials for multiple workspaces or accounts. ## Interactive: local desktop Sign in through the browser: ```bash theme={null} talkvalue auth login ``` The CLI prints a one-time code, opens your default browser to the verification page, and waits for you to approve the device. Once you do, it polls for the access token, lists your organizations, and asks which one to use. Pick from the menu and the CLI saves a profile. Skip the org picker by passing the name or ID up front: ```bash theme={null} talkvalue auth login --org "Acme Inc." talkvalue auth login --org org_01HXXX... ``` The access token is stored in your system keyring (Keychain on macOS, libsecret on Linux, Credential Manager on Windows). The profile record on disk holds the organization ID, organization name, your email, and the auth method, never the token itself. ## CI and scripting: API token For non-interactive environments, set `TALKVALUE_TOKEN` and skip `auth login` entirely: ```bash theme={null} export TALKVALUE_TOKEN= talkvalue path person list --json ``` An API token in the environment takes precedence over any saved profile, so the same shell can switch between accounts by re-exporting the variable. Generate the token from the dashboard's Settings area before adding it to your CI secret store. ## Multi-profile workflow Profiles let you keep credentials for a staging workspace and a production workspace on the same machine, or work across multiple customer organizations. | Command | Description | | ----------------------------- | ------------------------------------------------------ | | `talkvalue auth login` | Sign in through the browser and select an organization | | `talkvalue auth status` | Show the active profile, email, and organization | | `talkvalue auth switch [org]` | Switch the active organization | | `talkvalue auth list` | List every saved profile | | `talkvalue auth logout` | Remove a profile and its stored credentials | Target a specific profile for a single command: ```bash theme={null} talkvalue path person list --profile staging ``` Make a profile the default for the shell: ```bash theme={null} export TALKVALUE_PROFILE=staging talkvalue path person list ``` ## Credential precedence The CLI resolves credentials in this order: | Priority | Source | Set via | | -------- | ------------- | -------------------------------------- | | 1 | API token | `TALKVALUE_TOKEN` environment variable | | 2 | Saved profile | `talkvalue auth login` | The `--profile ` flag and `TALKVALUE_PROFILE` env var only pick which saved profile is read at priority 2. A `TALKVALUE_TOKEN` in the environment still wins. ## Sign out ```bash theme={null} talkvalue auth logout ``` Removes the active profile and clears its tokens from your system keyring. Pass `--profile ` to remove a specific profile. ## Related * [Quickstart](/cli/quickstart). Install, sign in, run your first command. * [Environment variables](/cli/environment-variables). Full env reference including `TALKVALUE_TOKEN`. * [Global flags](/cli/global-flags). `--profile`, `--api-url`, and the rest. * [Output format](/cli/output-format). Error envelope when auth fails. # talkvalue auth Source: https://docs.trytalkvalue.com/cli/commands/auth/index Authentication commands: sign in, switch organizations, manage profiles, and sign out. `talkvalue auth` groups every command that touches credentials or profile state. Sign in once through the browser, then use the same install across multiple organizations and machines. ## Subcommands | Command | Description | | ------------------------------------------ | --------------------------------------------------------- | | [`auth login`](/cli/commands/auth/login) | Sign in through the browser and select an organization | | [`auth logout`](/cli/commands/auth/logout) | Remove the active profile and clear its stored tokens | | [`auth status`](/cli/commands/auth/status) | Show the active profile, email, and organization | | [`auth switch`](/cli/commands/auth/switch) | Switch the active organization within the current profile | | [`auth list`](/cli/commands/auth/list) | List every saved profile on this machine | ## Typical workflow Sign in on a new machine and confirm the result: ```bash theme={null} talkvalue auth login talkvalue auth status ``` The first command opens a browser to the verification page, prompts for an organization, and saves a profile to your system keyring. The second prints the profile, email, and organization that the next command will run against. Move between organizations without re-authenticating: ```bash theme={null} talkvalue auth switch "Acme Inc." ``` The `auth` subcommands manage the profiles saved on this machine. A `TALKVALUE_TOKEN` in your shell authenticates the API requests every other command makes. See [Authentication](/cli/authentication) for the full credential precedence rules. ## Related * [Authentication](/cli/authentication). Interactive browser sign-in vs CI tokens. * [Environment variables](/cli/environment-variables). `TALKVALUE_TOKEN`, `TALKVALUE_PROFILE`. * [Global flags](/cli/global-flags). `--profile` to target a specific profile per command. # talkvalue auth list Source: https://docs.trytalkvalue.com/cli/commands/auth/list List every saved profile on this machine with its organization, email, and active marker. Show every profile saved on the current machine. Each row prints the profile name, organization, member email, and an `*` next to the active profile. Use it to remember which workspaces this machine has credentials for. ## Synopsis ```bash theme={null} talkvalue auth list ``` ## Options None. Output respects the global `--format` and `--json` flags. ## Examples ### 1. List in a terminal ```bash theme={null} talkvalue auth list ``` Prints a four-column table: Profile, Organization, Email, Active. The active profile has `*` in the Active column. ### 2. List as JSON ```bash theme={null} talkvalue auth list --json | jq '.data' ``` Returns the raw array so you can filter to a specific profile or organization in a script. ### 3. Find the profile bound to a known org ```bash theme={null} talkvalue auth list --json \ | jq -r '.data[] | select(.orgName == "Acme Inc.") | .profile' ``` Useful when you have multiple profiles and need to feed the matching one into `--profile ` for a downstream command. ## Response ```jsonc theme={null} { "data": [ { "profile": "you", "orgName": "Acme Inc.", "memberEmail": "you@example.com", "active": true }, { "profile": "staging", "orgName": "Acme Staging", "memberEmail": "you@example.com", "active": false } ] } ``` `active` is a boolean in JSON. In the table view it renders as `*` for the active profile and an empty cell for the rest. ## See also * [`talkvalue auth login`](/cli/commands/auth/login). Add a new profile. * [`talkvalue auth status`](/cli/commands/auth/status). Full detail on the active profile. * [`talkvalue auth switch`](/cli/commands/auth/switch). Change the active organization. * [Authentication](/cli/authentication). `--profile` and `TALKVALUE_PROFILE` precedence. # talkvalue auth login Source: https://docs.trytalkvalue.com/cli/commands/auth/login Sign in to TalkValue through the browser and select an organization to use. Sign in through the browser, exchange the code for an access token, pick an organization, and save a profile. Run this once per machine before any other command. ## Synopsis ```bash theme={null} talkvalue auth login [--org ] ``` ## Options | Flag | Type | Description | | -------------------- | ------ | ---------------------------------------------------------------------------------------------------- | | `--org ` | string | Organization name or ID. Skip the interactive picker when you already know which workspace you want. | ## Examples ### 1. Interactive sign-in ```bash theme={null} talkvalue auth login ``` The CLI prints a one-time code, opens your default browser to the verification page, and waits for you to approve. After approval it polls for the token, lists your organizations, and prompts you to pick one. Output ends with `✓ Logged in as you@example.com (Acme Inc.)`. ### 2. Pre-select an organization ```bash theme={null} talkvalue auth login --org "Acme Inc." talkvalue auth login --org org_01HXXX... ``` Matches by name (case-insensitive) or by ID. The picker is skipped entirely, which is useful for scripts that need to re-bind a profile to a known organization. ### 3. CI environments For CI you typically skip `auth login` and use an API token instead: ```bash theme={null} export TALKVALUE_TOKEN= talkvalue path person list --json ``` A token in the environment takes precedence over any saved profile. See [Authentication](/cli/authentication) for the precedence table. ## Response ```jsonc theme={null} { "data": { "email": "you@example.com", "loggedIn": true, "orgId": "org_01HXXX...", "orgName": "Acme Inc.", "profile": "you" } } ``` The access token is stored in your system keyring (Keychain on macOS, libsecret on Linux, Credential Manager on Windows). The profile record on disk holds the organization ID, organization name, your email, and the auth method, never the token itself. ## See also * [`talkvalue auth status`](/cli/commands/auth/status). Confirm the active profile after login. * [`talkvalue auth logout`](/cli/commands/auth/logout). Remove the profile and stored tokens. * [`talkvalue auth switch`](/cli/commands/auth/switch). Change organization without re-authenticating. * [Authentication](/cli/authentication). Browser sign-in vs CI tokens and credential precedence. * [Environment variables](/cli/environment-variables). `TALKVALUE_TOKEN` for non-interactive runs. # talkvalue auth logout Source: https://docs.trytalkvalue.com/cli/commands/auth/logout Remove the active profile and clear its tokens from the system keyring. End the current session by deleting the active profile and clearing its tokens from your system keyring. Other saved profiles are untouched, so this is safe to run on a shared machine when you only want to drop one account. ## Synopsis ```bash theme={null} talkvalue auth logout ``` ## Options None. To target a specific profile, use the global `--profile` flag. ## Examples ### 1. Sign out of the active profile ```bash theme={null} talkvalue auth logout ``` Removes the active profile and clears its tokens. The next command that needs auth will prompt you to run `auth login` again. ### 2. Sign out of a specific profile ```bash theme={null} talkvalue auth logout --profile staging ``` The global `--profile` flag selects which saved profile to remove without touching the others. ### 3. Confirm sign-out in a script ```bash theme={null} talkvalue auth logout --json | jq '.data.loggedOut' # true ``` Branch on `data.loggedOut` to decide whether to chain a follow-up `auth login` for a new account. ## Response ```jsonc theme={null} { "data": { "loggedOut": true, "profile": "you" } } ``` If there's no active session to remove, the CLI returns a no-op response instead and exits `0`: ```jsonc theme={null} { "data": { "loggedIn": false, "message": "No active session to log out from" } } ``` ## See also * [`talkvalue auth login`](/cli/commands/auth/login). Sign back in. * [`talkvalue auth list`](/cli/commands/auth/list). See the remaining profiles. * [Authentication](/cli/authentication). Multi-profile workflow. * [Global flags](/cli/global-flags). `--profile ` to target a specific profile. # talkvalue auth status Source: https://docs.trytalkvalue.com/cli/commands/auth/status Show the active profile, email, and organization the next command will run against. Print the auth profile, email, and organization the CLI will use for its next request. Run it whenever you need to confirm which account is active before a destructive command or a script run. ## Synopsis ```bash theme={null} talkvalue auth status ``` ## Options None. To inspect a specific profile, use the global `--profile` flag. ## Examples ### 1. Confirm the active account ```bash theme={null} talkvalue auth status ``` The table view shows the profile, email, organization, and login state. Use this before running anything that mutates data: `person delete`, `import create`, and so on. ### 2. Check status as JSON ```bash theme={null} talkvalue auth status --json ``` The JSON envelope is the right shape for parsing in scripts. The CLI exits `0` even when not logged in, so branch on `data.loggedIn` instead of the exit code. ### 3. Use in a shell guard ```bash theme={null} if [ "$(talkvalue auth status --json | jq -r '.data.loggedIn')" != "true" ]; then echo "Not signed in. Run 'talkvalue auth login' first." >&2 exit 1 fi ``` A common pre-flight check for CI runners and pre-commit scripts that wrap CLI calls. ## Response ```jsonc theme={null} { "data": { "profile": "you", "loggedIn": true, "memberEmail": "you@example.com", "orgId": "org_01HXXX...", "orgName": "Acme Inc.", "memberFirstName": "Ada", "teamMemberCount": 12 } } ``` `memberFirstName` and `teamMemberCount` come from a follow-up API call and only appear when the session is valid. When you're signed out: ```jsonc theme={null} { "data": { "profile": null, "loggedIn": false } } ``` ## See also * [`talkvalue auth login`](/cli/commands/auth/login). Sign in when `loggedIn` is `false`. * [`talkvalue auth switch`](/cli/commands/auth/switch). Change the organization shown in `orgName`. * [`talkvalue auth list`](/cli/commands/auth/list). See every saved profile. * [Exit codes](/cli/exit-codes). Pairing `status` with a script's exit handling. # talkvalue auth switch Source: https://docs.trytalkvalue.com/cli/commands/auth/switch Switch the active organization for the current profile without re-authenticating. Move between organizations on the same profile without signing in again. The CLI uses your stored refresh token to mint a new access token scoped to the selected organization, then updates the profile record. ## Synopsis ```bash theme={null} talkvalue auth switch [org] ``` ## Arguments | Argument | Type | Description | | -------- | ------ | ---------------------------------------------------------------------------------------------- | | `org` | string | Organization name or ID to switch to. When omitted, the CLI prompts you to pick from the list. | ## Examples ### 1. Pick interactively ```bash theme={null} talkvalue auth switch ``` The CLI fetches your organizations and shows an arrow-key picker. After you confirm, output ends with `✓ Switched to Acme Inc.` on stderr and the JSON envelope on stdout. ### 2. Switch by name or ID ```bash theme={null} talkvalue auth switch "Acme Inc." talkvalue auth switch org_01HXXX... ``` Matches by ID first, then by name (case-insensitive). Skips the picker entirely. ### 3. Combine with profile selection ```bash theme={null} talkvalue auth switch "Production" --profile prod ``` Use the global `--profile` flag to switch the organization on a non-active profile without making it active first. ## Response ```jsonc theme={null} { "data": { "orgId": "org_01HXXX...", "orgName": "Acme Inc.", "profile": "you" } } ``` The new access token is stored in your system keyring and the profile record is updated with the selected `orgId` and `orgName`. Subsequent commands run against the new organization until you switch again. If the active profile has no refresh token, the command fails and asks you to run `auth login`. ## See also * [`talkvalue auth login`](/cli/commands/auth/login). Pick an organization during sign-in. * [`talkvalue auth status`](/cli/commands/auth/status). Confirm which organization is active. * [`talkvalue auth list`](/cli/commands/auth/list). See every saved profile and its organization. * [Authentication](/cli/authentication). Multi-profile and multi-org workflow. # talkvalue path analysis channel audience Source: https://docs.trytalkvalue.com/cli/commands/path/analysis/audience-overlap Audience overlap across 2–5 channels: intersection counts plus aggregate multi-channel reach. Compute how much audience overlap exists across a group of channels. The response carries each channel's own size, every n-way intersection (pairs, triples, and so on), and aggregate metrics: total unique reach, the count of people in more than one channel, and the multi-channel rate. The dashboard [Audience overlap](/path/analytics/audience) card uses the same query. ## Synopsis ```bash theme={null} talkvalue path analysis channel audience --channel-id --channel-id [...] ``` ## Options | Flag | Type | Description | | ------------------- | ------------------------------ | ------------------------------------------------------------------------------------ | | `--channel-id ` | integer (required, repeatable) | Channel ID to include in the overlap. Repeat to add more. Between 2 and 5 IDs total. | The command exits with a usage error if fewer than 2 or more than 5 channel IDs are provided. ## Examples ### 1. Two-channel overlap ```bash theme={null} talkvalue path analysis channel audience \ --channel-id 7 --channel-id 12 --json \ | jq '{intersections: .data.intersections, metrics: .data.metrics}' ``` Returns the single 2-way intersection plus the aggregate metrics for channels `7` and `12`. ### 2. Find the largest overlap in a trio ```bash theme={null} talkvalue path analysis channel audience \ --channel-id 7 --channel-id 12 --channel-id 19 --json \ | jq '.data.intersections | sort_by(-.count) | .[0]' ``` Sorts every n-way intersection by member count and returns the largest. The result includes the 3-way intersection plus every 2-way pair, so you can spot redundancy at a glance. ### 3. Capture the multi-channel rate for tracking ```bash theme={null} talkvalue path analysis channel audience \ --channel-id 7 --channel-id 12 --channel-id 19 --channel-id 25 --json \ | jq -r '[.data.metrics.multiChannelRate, (now | strftime("%Y-%m-%d"))] | @csv' \ >> "reports/multi-channel-rate.csv" ``` Appends the day's multi-channel rate to a long-form CSV. Useful for tracking how concentrated your audience is over time. ## Response ```jsonc theme={null} { "data": { "channels": [ { "id": 7, "name": "Newsletter", "icon": "📬", "color": "#5252FF", "personCount": 1843 }, { "id": 12, "name": "Webinars", "icon": "🎥", "color": "#FF6B5C", "personCount": 920 }, { "id": 19, "name": "Beta List", "icon": "🧪", "color": "#34C77B", "personCount": 412 } ], "intersections": [ { "channelIds": [7, 12], "count": 318 }, { "channelIds": [7, 19], "count": 142 }, { "channelIds": [12, 19], "count": 87 }, { "channelIds": [7, 12, 19], "count": 41 } ], "metrics": { "totalUniquePersons": 2589, "personsInMultipleChannels": 506, "multiChannelRate": 0.1954 } } } ``` `channelIds` in each intersection is sorted ascending. `multiChannelRate` is `personsInMultipleChannels / totalUniquePersons`. ## See also * [`analysis channel attribution`](/cli/commands/path/analysis/channel-attribution). Per-event breakdown for a single channel. * [`channel list`](/cli/commands/path/channel/list). Discover channel IDs to feed into the overlap. * [Audience overlap](/path/analytics/audience). The dashboard surface this command mirrors. * [Recipe: Channel analysis](/cli/recipes/channel-analysis). Compose attribution and overlap in one script. # talkvalue path analysis channel attribution Source: https://docs.trytalkvalue.com/cli/commands/path/analysis/channel-attribution Per-event acquisition breakdown for a single channel: net new joiners vs members already on the channel. Compute how a single channel acquired people across each event it appeared on. The response carries the channel's membership context plus a per-event breakdown of who joined the channel because of that event and who was already on it. The dashboard [Channel attribution](/path/analytics/attribution) card uses the same query. ## Synopsis ```bash theme={null} talkvalue path analysis channel attribution [options] ``` ## Arguments | Argument | Type | Description | | ------------- | ------- | ------------------------------------------------------------------------------ | | `` | integer | Channel ID. Use [`channel list`](/cli/commands/path/channel/list) to find one. | ## Options | Flag | Type | Description | | ----------------- | -------------------- | ------------------------------------------------------------------------------------------- | | `--event-id ` | integer (repeatable) | Limit to specific events. Repeat to pass multiple. Defaults to every event for the channel. | | `--tag-id ` | integer | Limit to events that carry the given tag. | ## Examples ### 1. Attribution for a single event ```bash theme={null} talkvalue path analysis channel attribution 7 --event-id 18 --json ``` Returns the channel's headline metrics plus a one-element `events` array containing the breakdown for event `18`. ### 2. Roll up every event on a channel ```bash theme={null} talkvalue path analysis channel attribution 7 --json \ | jq '{ channel: .data.channel.name, eventParticipationRate: .data.metrics.eventParticipationRate, events: (.data.events | map({name, total, joinedSinceLastEvent, acquisitionRate})) }' ``` Projects each event down to the four fields you typically chart, leaving the channel headline metrics on top. ### 3. Tag-scoped attribution report ```bash theme={null} talkvalue path analysis channel attribution 7 --tag-id 4 --json \ > "reports/channel-7-attribution-$(date +%Y-%m-%d).json" ``` Captures the attribution snapshot for tagged events (for example, every webinar). Drop into a cron job to keep a daily archive. ## Response ```jsonc theme={null} { "data": { "channel": { "id": 7, "name": "Newsletter", "icon": "📬", "color": "#5252FF" }, "metrics": { "channelSize": 1843, "membersEverRegistered": 1204, "eventParticipationRate": 0.6535 }, "events": [ { "id": 18, "name": "Spring Summit", "startAt": "2026-03-12T17:00:00Z", "total": 412, "joinedSinceLastEvent": 87, "alreadyInChannel": 325, "acquisitionRate": 0.2112 } ] } } ``` `acquisitionRate` is `joinedSinceLastEvent / total`. `eventParticipationRate` is `membersEverRegistered / channelSize`. ## See also * [`analysis channel audience`](/cli/commands/path/analysis/audience-overlap). Overlap across multiple channels. * [`channel get`](/cli/commands/path/channel/get). Confirm channel metadata before running the report. * [Channel attribution](/path/analytics/attribution). The dashboard surface this command mirrors. * [Recipe: Channel analysis](/cli/recipes/channel-analysis). Pair attribution with overlap in one script. # talkvalue path analysis event trend Source: https://docs.trytalkvalue.com/cli/commands/path/analysis/event-trends Net new vs returning registrants per event, plus latest-event headline metrics and deltas. Compute the registration-trend snapshot the dashboard plots on the [Registration trend](/path/analytics/registration-trend) card. Each event in the result carries its total registrants split into net-new and returning, with the corresponding rates and a summary block that highlights the latest event and how it moved against the prior data point. ## Synopsis ```bash theme={null} talkvalue path analysis event trend [options] ``` ## Options | Flag | Type | Description | | --------------- | ------- | ----------------------------------------------------------------------------------- | | `--tag-id ` | integer | Limit to events that carry the given tag. Defaults to every event in the workspace. | ## Examples ### 1. Trend across every event ```bash theme={null} talkvalue path analysis event trend --json | jq '.data.summary' ``` Returns the summary block: unique audience size, latest event's headline numbers, and the deltas against the prior event. ### 2. Per-event net-new rate report ```bash theme={null} talkvalue path analysis event trend --json \ | jq -r '.data.events[] | [.name, .total, .netNew, .netNewRate] | @csv' \ > reports/event-trend.csv ``` Writes a four-column CSV for every event. Handy to drop into a spreadsheet for a longer-form chart than the dashboard card shows. ### 3. Tag-scoped trend ```bash theme={null} talkvalue path analysis event trend --tag-id 4 --json | jq '.data.events | length' ``` Counts how many tagged events (for example, every webinar) made it into the trend, so you can sanity-check the slice before charting it. ## Response ```jsonc theme={null} { "data": { "events": [ { "id": 18, "name": "Spring Summit", "startAt": "2026-03-12T17:00:00Z", "total": 412, "netNew": 87, "returning": 325, "netNewRate": 0.2112, "returningRate": 0.7888 } ], "summary": { "uniqueAudience": 2589, "latestTotal": 412, "latestNetNewRate": 0.2112, "returnRate": 0.7888, "latestName": "Spring Summit", "totalDelta": { /* delta vs prior event */ }, "netNewRateDelta": { /* delta vs prior event */ }, "returnRateDelta": { /* delta vs prior event */ } } } } ``` `netNewRate + returningRate ≈ 1.0` for each event. The `*Delta` blocks under `summary` are `null` when there is no prior event to compare against. ## See also * [`analysis channel attribution`](/cli/commands/path/analysis/channel-attribution). Drill from a trending event into the channels that drove its acquisition. * [`event list`](/cli/commands/path/event/list). Pair event IDs with trend numbers. * [Registration trend](/path/analytics/registration-trend). The dashboard surface this command mirrors. * [Recipe: New registrants this week](/cli/recipes/new-registrants). Narrower script that feeds off the same event data. # talkvalue path analysis Source: https://docs.trytalkvalue.com/cli/commands/path/analysis/index Analytical reads for channels and events: attribution, audience overlap, and registration trends. `talkvalue path analysis` groups the analytical reads that power the dashboard's Analytics pages: channel attribution, audience overlap across channels, and the event registration trend. Every command in the group emits a JSON document that maps one-to-one to a single dashboard card, so you can reproduce the same numbers in a script, a spreadsheet, or another report tool. ## Subcommands | Command | Description | | --------------------------------------------------------------------------------- | ---------------------------------------------------- | | [`analysis channel attribution`](/cli/commands/path/analysis/channel-attribution) | Per-event acquisition breakdown for a single channel | | [`analysis channel audience`](/cli/commands/path/analysis/audience-overlap) | Overlap matrix across 2–5 channels | | [`analysis event trend`](/cli/commands/path/analysis/event-trends) | Net new vs returning registrants per event | ## Typical workflow Compare two channels' reach, then drill into how much each channel contributed to a recent event: ```bash theme={null} talkvalue path analysis channel audience \ --channel-id 7 --channel-id 12 --json \ | jq '.data.metrics' talkvalue path analysis channel attribution 7 --event-id 18 --json \ | jq '.data.events[0]' ``` The same numbers also appear on the dashboard. Use the CLI to snapshot them, embed them in a recurring report, or feed them into another system without scraping the dashboard. See [Recipe: Channel analysis](/cli/recipes/channel-analysis) for an end-to-end composition. ## See also * [Channel attribution](/path/analytics/attribution). The dashboard surface for `analysis channel attribution`. * [Audience overlap](/path/analytics/audience). The dashboard surface for `analysis channel audience`. * [Registration trend](/path/analytics/registration-trend). The dashboard surface for `analysis event trend`. * [Recipe: Channel analysis](/cli/recipes/channel-analysis). Compose all three commands in one script. # talkvalue path channel get Source: https://docs.trytalkvalue.com/cli/commands/path/channel/get Fetch a single channel by ID: name, icon, color, people count, and tags. Pull the full record for one channel. The response shape matches what [`channel list`](/cli/commands/path/channel/list) returns. Use this when you already have an ID and want a `jq`-friendly read. ## Synopsis ```bash theme={null} talkvalue path channel get ``` ## Arguments | Argument | Type | Description | | -------- | ------- | ------------------------------------------------------------------------------ | | `` | integer | Channel ID. Use [`channel list`](/cli/commands/path/channel/list) to find one. | ## Examples ### 1. Inspect a channel in the terminal ```bash theme={null} talkvalue path channel get 7 ``` Prints a single-row table with the headline fields. Use `--json` if you need the nested `tags` array or the exact ISO `createdAt` timestamp. ### 2. Read one field with jq ```bash theme={null} talkvalue path channel get 7 --json | jq -r '.data.peopleCount' ``` Returns the people count as a raw number. Combine with other commands when you only need an attribution number, for example, computing a channel's share of total reach. ### 3. Use inside a guard ```bash theme={null} if talkvalue path channel get 7 --json >/dev/null 2>&1; then echo "Channel 7 exists" else echo "Channel 7 not found" fi ``` The CLI exits non-zero when the channel ID is missing, so the guard above branches cleanly. See [Exit codes](/cli/exit-codes) for the full mapping. ## Response ```jsonc theme={null} { "data": { "id": 7, "name": "Newsletter", "icon": "📬", "color": "#5252FF", "peopleCount": 1843, "tags": [{ "id": 4, "name": "Owned channel" }], "createdAt": "2026-01-08T00:00:00Z" } } ``` `icon` holds the emoji picked for the channel and `color` its hex swatch; both are null on channels created without them. `tags` is always an array, empty when no tags are attached. ## See also * [`channel list`](/cli/commands/path/channel/list). Find the ID first. * [`channel people`](/cli/commands/path/channel/people). Page through the people on this channel. * [`path analysis channel-attribution`](/cli/commands/path/analysis/channel-attribution). Channel reach and contribution metrics. * [Channels](/path/manage/channels). The dashboard surface this command mirrors. # talkvalue path channel Source: https://docs.trytalkvalue.com/cli/commands/path/channel/index Manage channels in Path: list, get, and page through the people attributed to a channel. `talkvalue path channel` groups the read commands you need to inspect channels and the people attributed to them. The same dataset powers the Channels surface in the dashboard, so every channel you see in the app is reachable from the CLI. ## Subcommands | Command | Description | | ----------------------------------------------------- | ----------------------------------------------- | | [`channel list`](/cli/commands/path/channel/list) | List every channel in the active workspace | | [`channel get`](/cli/commands/path/channel/get) | Fetch a single channel by ID | | [`channel people`](/cli/commands/path/channel/people) | Page through the people attributed to a channel | ## Typical workflow Find a channel, inspect it, then page through the people attributed to it: ```bash theme={null} talkvalue path channel list talkvalue path channel get 7 talkvalue path channel people 7 --sort "joinedAt,desc" --page-size 25 ``` Every read prints a table by default and respects `--json` for piping into `jq`. Channels appear in dashboard analytics. Pair these commands with [`path analysis channel-attribution`](/cli/commands/path/analysis/channel-attribution) when you need reach and overlap numbers. ## See also * [Channels](/path/manage/channels). The dashboard surface this group mirrors. * [`path event`](/cli/commands/path/event/index). The parallel group for events. * [Recipe: Channel analysis](/cli/recipes/channel-analysis). Pairs `channel people` with attribution metrics. * [Attribution](/path/analytics/attribution). Channel-level reach and contribution. # talkvalue path channel list Source: https://docs.trytalkvalue.com/cli/commands/path/channel/list List every channel in the active workspace: name, icon, color, people count, and tags. Print every channel in the active workspace as a table or JSON. Useful as the first call when you want to find a channel ID before drilling into the people behind it, or as the data source for a recurring channel-mix report. ## Synopsis ```bash theme={null} talkvalue path channel list ``` ## Options This command takes no flags beyond the [global flags](/cli/global-flags). Filtering and pagination happen client-side. Pipe through `jq` or `--json` to slice the result. ## Examples ### 1. Browse channels in the terminal ```bash theme={null} talkvalue path channel list ``` Prints every channel as a table: ID, name, icon, color, people count, tags, created-at. Channels appear in the order the server returns them. ### 2. Find a channel ID with jq ```bash theme={null} talkvalue path channel list --json \ | jq '.data[] | select(.name | test("Newsletter"; "i")) | {id, name, peopleCount}' ``` Returns the ID, name, and people count of every channel whose name contains `Newsletter` (case-insensitive). Use the ID with [`channel get`](/cli/commands/path/channel/get) or [`channel people`](/cli/commands/path/channel/people). ### 3. Snapshot a channel-mix report ```bash theme={null} ts=$(date +%Y-%m-%d) talkvalue path channel list --json \ | jq -r '.data[] | [.id, .name, .peopleCount] | @csv' \ > "snapshots/channels-$ts.csv" ``` Loops over every channel and writes a three-column CSV. Drop into a cron job for a periodic mix snapshot outside of TalkValue. ## Response ```jsonc theme={null} { "data": [ { "id": 7, "name": "Newsletter", "icon": "📬", "color": "#5252FF", "peopleCount": 1843, "tags": [{ "id": 4, "name": "Owned channel" }], "createdAt": "2026-01-08T00:00:00Z" } ] } ``` `icon` holds the emoji picked for the channel and `color` its hex swatch; both are null when the channel was created without them. `peopleCount` is the count of distinct people attributed to the channel, the same number the dashboard shows on the Channels list. ## See also * [`channel get`](/cli/commands/path/channel/get). Fetch one channel by ID. * [`channel people`](/cli/commands/path/channel/people). Drill into the people behind `peopleCount`. * [`path analysis channel-attribution`](/cli/commands/path/analysis/channel-attribution). Channel reach and contribution metrics. * [Channels](/path/manage/channels). The dashboard surface this command mirrors. # talkvalue path channel people Source: https://docs.trytalkvalue.com/cli/commands/path/channel/people List people attributed to a channel with event, company, job-title, keyword, and pagination filters. Page through the people attributed to a single channel. Combine filters to slice the roster, then pipe to `jq` or save the result as JSON. The dashboard channel-detail page shows the same people. ## Synopsis ```bash theme={null} talkvalue path channel people [options] ``` ## Arguments | Argument | Type | Description | | ------------- | ------- | ------------------------------------------------------------------------------ | | `` | integer | Channel ID. Use [`channel list`](/cli/commands/path/channel/list) to find one. | ## Options | Flag | Type | Description | | ----------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | `--keyword ` | string | Free-text match against the person's name, every email address, and phone number. Use `--company-name` and `--job-title` to filter on those fields. | | `--event-id ` | integer (repeatable) | Limit to people also registered for the given event. Repeat to OR multiple. | | `--company-id ` | integer | Limit by company ID. | | `--company-name ` | string | Limit by company display name. | | `--job-title ` | string | Limit by job title. | | `--page <n>` | integer | Page number (zero-indexed). Defaults to `0`. | | `--page-size <n>` | integer | Page size. Defaults to the server default. | | `--sort <value>` | string (repeatable) | Sort expression `field,direction` (for example, `joinedAt,desc`). Repeat for secondary sorts. | ## Examples ### 1. Browse the latest people on a channel ```bash theme={null} talkvalue path channel people 7 --sort "joinedAt,desc" --page-size 20 ``` Prints the 20 most recent people on channel `7` as a table: ID, name, email, phone, company, job title, joined-at. ### 2. Filter by event and pipe to jq ```bash theme={null} talkvalue path channel people 7 \ --event-id 18 \ --json \ | jq '.data[] | {name, primaryEmail, jobTitle}' ``` Returns people on channel `7` who also registered for event `18`, projected to three fields. The `--json` envelope also carries `.pagination`. ### 3. Walk every page in a script ```bash theme={null} page=0 while :; do resp=$(talkvalue path channel people 7 --page "$page" --page-size 100 --json) echo "$resp" | jq -e '.data | length > 0' >/dev/null || break echo "$resp" | jq '.data[]' page=$((page + 1)) done ``` Loops until a page returns no rows. See [Scripting with jq](/cli/recipes/scripting-with-jq) for richer pagination patterns. ## Response ```jsonc theme={null} { "data": [ { "id": 142, "name": "Alice Kim", "primaryEmail": "alice@acme.com", "primaryPhone": "+1-415-555-0199", "company": { "id": 88, "displayName": "Acme Inc.", "domain": "acme.com", "nameUpdatable": false }, "jobTitle": "Head of Growth", "channels": [/* … */], "events": [/* … */], "joinedAt": "2026-04-12T00:00:00Z", "createdAt": "2026-04-12T00:00:00Z" } ], "pagination": { "page": 0, "pageSize": 20, "totalElements": 1843, "totalPages": 93 } } ``` `pagination` appears only in `--json`. `joinedAt` for a channel is when the person was first attributed to it, not when they last engaged. ## See also * [`channel get`](/cli/commands/path/channel/get). Confirm channel metadata before paging. * [`path person list`](/cli/commands/path/person/list). The workspace-wide people query with the same filter grammar. * [Recipe: Channel analysis](/cli/recipes/channel-analysis). `--event-id` filtering paired with attribution metrics. * [Channels](/path/manage/channels). The dashboard surface this command mirrors. # talkvalue path company get Source: https://docs.trytalkvalue.com/cli/commands/path/company/get Fetch a single company by ID: domain, display name, and people count. Pull the full record for one company. The response shape matches what [`company list`](/cli/commands/path/company/list) returns, so the command is most useful when you already have an ID and want a `jq`-friendly read. ## Synopsis ```bash theme={null} talkvalue path company get <id> ``` ## Arguments | Argument | Type | Description | | -------- | ------- | ------------------------------------------------------------------------------ | | `<id>` | integer | Company ID. Use [`company list`](/cli/commands/path/company/list) to find one. | ## Examples ### 1. Inspect a company in the terminal ```bash theme={null} talkvalue path company get 88 ``` Prints a single-row table with the headline fields: ID, domain, display name, people count. Use `--json` if you want the exact field names. ### 2. Read one field with jq ```bash theme={null} talkvalue path company get 88 --json | jq -r '.data.peopleCount' ``` Returns the people count as a raw number. Combine with other commands when you only need a headcount, for example, computing the share of a campaign that lands at a single company. ### 3. Use inside a guard ```bash theme={null} if talkvalue path company get 88 --json >/dev/null 2>&1; then echo "Company 88 exists" else echo "Company 88 not found" fi ``` The CLI exits non-zero when the company ID is missing, so the guard above branches cleanly. See [Exit codes](/cli/exit-codes) for the full mapping. ## Response ```jsonc theme={null} { "data": { "id": 88, "domain": "acme.com", "displayName": "Acme Inc.", "peopleCount": 142 } } ``` `peopleCount` is the number of people currently attributed to the company, and `0` when none are. ## See also * [`company list`](/cli/commands/path/company/list). Find the ID first. * [`company update`](/cli/commands/path/company/update). Rename a company. * [`company person list`](/cli/commands/path/company/person-list). Page through the people behind `peopleCount`. * [Companies](/path/manage/companies). The dashboard surface this command mirrors. # talkvalue path company Source: https://docs.trytalkvalue.com/cli/commands/path/company/index Manage companies in Path: list, get, update, and page through people grouped by company. `talkvalue path company` groups the commands you need to inspect and edit companies, plus the read that drills from a company into its people. The Companies dashboard reads the same data, so edits made here appear there too. ## Subcommands | Command | Description | | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | | [`company list`](/cli/commands/path/company/list) | Page through companies with a keyword filter | | [`company get`](/cli/commands/path/company/get) | Fetch a single company by ID | | [`company update`](/cli/commands/path/company/update) | Update a company's display name | | [`company person list`](/cli/commands/path/company/person-list) | Page through the people in a company with keyword, channel, event, and job-title filters | ## Typical workflow Find a company, inspect it, then drill into the people behind the headcount: ```bash theme={null} talkvalue path company list --keyword "acme" talkvalue path company get 88 talkvalue path company person list 88 --sort "createdAt,desc" --page-size 25 ``` Every read prints a table by default and respects `--json` for piping into `jq`. `company update` is the only mutating command in the group. It patches the display name in-place and returns the updated record so you can confirm the write succeeded. ## See also * [Companies](/path/manage/companies). The dashboard surface this group mirrors. * [`path person`](/cli/commands/path/person/index). The workspace-wide people group that `--company-id` filters tie back to. * [Recipe: Scripting with jq](/cli/recipes/scripting-with-jq). Patterns for piping `--json` output. # talkvalue path company list Source: https://docs.trytalkvalue.com/cli/commands/path/company/list List companies in the workspace with a keyword filter and pagination. Page through every company in the active workspace. Filter by keyword to narrow the result, then pipe to `jq` or save as JSON. The dashboard Companies page uses the same backend query. ## Synopsis ```bash theme={null} talkvalue path company list [options] ``` ## Options | Flag | Type | Description | | --------------------- | ------- | -------------------------------------------------------- | | `--keyword <keyword>` | string | Free-text match against company display name and domain. | | `--page <n>` | integer | Page number (zero-indexed). Defaults to `0`. | | `--page-size <n>` | integer | Page size. Defaults to the server default. | ## Examples ### 1. Browse companies in the terminal ```bash theme={null} talkvalue path company list --page-size 20 ``` Prints the first 20 companies as a table: ID, domain, display name, and the people count attributed to the company. ### 2. Filter by keyword and pipe to jq ```bash theme={null} talkvalue path company list --keyword "acme" --json \ | jq '.data[] | {id, displayName, peopleCount}' ``` Returns the matching companies stripped to three fields. The `--json` envelope also carries `.pagination`. ### 3. Walk every page in a script ```bash theme={null} page=0 while :; do resp=$(talkvalue path company list --page "$page" --page-size 100 --json) echo "$resp" | jq -e '.data | length > 0' >/dev/null || break echo "$resp" | jq '.data[]' page=$((page + 1)) done ``` Loops until a page returns no rows. See [Scripting with jq](/cli/recipes/scripting-with-jq) for richer pagination patterns. ## Response ```jsonc theme={null} { "data": [ { "id": 88, "domain": "acme.com", "displayName": "Acme Inc.", "peopleCount": 142 } ], "pagination": { "page": 0, "pageSize": 20, "totalElements": 1320, "totalPages": 66 } } ``` `pagination` appears only in `--json`. `peopleCount` is the number of people currently attributed to the company, and `0` when none are. ## See also * [`company get`](/cli/commands/path/company/get). Fetch a single company in full detail. * [`company person list`](/cli/commands/path/company/person-list). Drill into the people behind `peopleCount`. * [`path person list`](/cli/commands/path/person/list). The workspace-wide people query with `--company-id` filtering. * [Companies](/path/manage/companies). The dashboard surface this command mirrors. # talkvalue path company person list Source: https://docs.trytalkvalue.com/cli/commands/path/company/person-list List people attributed to a company with keyword, channel, event, job-title filters, and pagination. Page through the people attributed to one company. Combine filters to slice the roster, then pipe to `jq` or save as JSON. The dashboard company-detail page uses the same query. ## Synopsis ```bash theme={null} talkvalue path company person list <companyId> [options] ``` ## Arguments | Argument | Type | Description | | ------------- | ------- | ------------------------------------------------------------------------------ | | `<companyId>` | integer | Company ID. Use [`company list`](/cli/commands/path/company/list) to find one. | ## Options | Flag | Type | Description | | ----------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | `--keyword <keyword>` | string | Free-text match against the person's name, every email address, and phone number. Use `--company-name` and `--job-title` to filter on those fields. | | `--channel-id <id>` | integer (repeatable) | Limit to people also attributed to the given channel. | | `--event-id <id>` | integer (repeatable) | Limit to people also registered for the given event. | | `--company-name <name>` | string | Extra company display-name filter when the person's record uses a different label. | | `--job-title <title>` | string | Limit by job title. | | `--page <n>` | integer | Page number (zero-indexed). Defaults to `0`. | | `--page-size <n>` | integer | Page size. Defaults to the server default. | | `--sort <value>` | string (repeatable) | Sort expression `field,direction` (for example, `createdAt,desc`). Sortable fields: `name`, `email`, `phone`, `jobTitle`, `companyName`, `createdAt`. | ## Examples ### 1. Browse the latest people at a company ```bash theme={null} talkvalue path company person list 88 --sort "createdAt,desc" --page-size 20 ``` Prints the 20 newest people at company `88` as a table: ID, name, email, company, job title, created-at. ### 2. Filter by event and pipe to jq ```bash theme={null} talkvalue path company person list 88 \ --event-id 18 \ --json \ | jq '.data[] | {name, primaryEmail, jobTitle}' ``` Returns people at company `88` who also registered for event `18`, projected to three fields. ### 3. Walk every page in a script ```bash theme={null} page=0 while :; do resp=$(talkvalue path company person list 88 --page "$page" --page-size 100 --json) echo "$resp" | jq -e '.data | length > 0' >/dev/null || break echo "$resp" | jq '.data[]' page=$((page + 1)) done ``` Loops until a page returns no rows. See [Scripting with jq](/cli/recipes/scripting-with-jq) for richer patterns. ## Response ```jsonc theme={null} { "data": [ { "id": 142, "name": "Alice Kim", "primaryEmail": "alice@acme.com", "primaryPhone": "+1-415-555-0199", "company": { "id": 88, "displayName": "Acme Corporation", "domain": "acme.com", "nameUpdatable": false }, "companyName": "Acme Corporation", "jobTitle": "Head of Growth", "channels": [/* … */], "events": [/* … */], "joinedAt": null, "createdAt": "2026-04-12T00:00:00Z" } ], "pagination": { "page": 0, "pageSize": 20, "totalElements": 142, "totalPages": 8 } } ``` `pagination` appears only in `--json`. `companyName` is a flattened convenience field, and the full `company` object is also included. `nameUpdatable` is `true` when the person carries a free-text company name with no company record behind it; rename those through [`person update --company-name`](/cli/commands/path/person/update), and rename linked companies through [`company update`](/cli/commands/path/company/update). `joinedAt` carries a value on the source-scoped lists, [`channel people`](/cli/commands/path/channel/people) and [`event person list`](/cli/commands/path/event/person-list). ## See also * [`company get`](/cli/commands/path/company/get). Confirm company metadata first. * [`path person list`](/cli/commands/path/person/list). Workspace-wide people query, same filter grammar. * [Recipe: New registrants this week](/cli/recipes/new-registrants). `--sort createdAt,desc` driven report. * [Companies](/path/manage/companies). The dashboard surface this command mirrors. # talkvalue path company update Source: https://docs.trytalkvalue.com/cli/commands/path/company/update Update a company's display name. Returns the updated record. Patch the display name on a company record. The command takes a single required flag, `--display-name`, and returns the updated record so you can confirm the write succeeded. `displayName` is the only editable field; `domain` and `peopleCount` are read-only, derived from registrations. ## Synopsis ```bash theme={null} talkvalue path company update <id> --display-name <name> ``` ## Arguments | Argument | Type | Description | | -------- | ------- | --------------------- | | `<id>` | integer | Company ID to update. | ## Options | Flag | Type | Description | | ----------------------- | ----------------- | --------------------------------- | | `--display-name <name>` | string (required) | Replace the company display name. | ## Examples ### 1. Rename a company ```bash theme={null} talkvalue path company update 88 --display-name "Acme Corporation" ``` Prints the updated record as a table. Only `displayName` changes server-side, and `domain` stays the same. ### 2. Confirm the rename in a script ```bash theme={null} talkvalue path company update 88 --display-name "Acme Corporation" --json \ | jq -e '.data.displayName == "Acme Corporation"' ``` `jq -e` exits non-zero if the assertion fails, so the script halts when the rename did not take effect. ### 3. Capture the response for an audit log ```bash theme={null} ts=$(date +%Y-%m-%d) talkvalue path company update 88 --display-name "Acme Corporation" --json \ | tee -a "audit-$ts.jsonl" ``` Appends the full response to a daily JSONL log. Pair with [`person activity`](/cli/commands/path/person/activity) to reconstruct who made which company change and when. ## Response ```jsonc theme={null} { "data": { "id": 88, "domain": "acme.com", "displayName": "Acme Corporation", "peopleCount": null } } ``` The shape matches [`company get`](/cli/commands/path/company/get). Run that command to read the current `peopleCount` for the renamed company. ## See also * [`company get`](/cli/commands/path/company/get). Inspect the record before and after. * [`company list`](/cli/commands/path/company/list). Find the ID first. * [Companies](/path/manage/companies). The dashboard surface this command mirrors. # talkvalue path event get Source: https://docs.trytalkvalue.com/cli/commands/path/event/get Fetch a single event by ID: name, time zone, start, location, people count, and tags. Pull the full record for one event. The response shape matches what [`event list`](/cli/commands/path/event/list) returns. Handy when you already have an ID and want a quick `jq`-friendly read. ## Synopsis ```bash theme={null} talkvalue path event get <id> ``` ## Arguments | Argument | Type | Description | | -------- | ------- | ------------------------------------------------------------------------ | | `<id>` | integer | Event ID. Use [`event list`](/cli/commands/path/event/list) to find one. | ## Examples ### 1. Inspect an event in the terminal ```bash theme={null} talkvalue path event get 18 ``` Prints a single-row table with the headline fields. Use `--json` if you need the nested `tags` array or the exact ISO timestamps. ### 2. Read one field with jq ```bash theme={null} talkvalue path event get 18 --json | jq -r '.data.startAt' ``` Returns the start timestamp as a raw string. Pair with `date -d` (GNU) or `gdate -d` (macOS via Homebrew `coreutils`) to format it for a report. ### 3. Use inside a guard ```bash theme={null} if talkvalue path event get 18 --json >/dev/null 2>&1; then echo "Event 18 exists" else echo "Event 18 not found" fi ``` The CLI exits non-zero when the event ID is missing, so the guard above branches cleanly. See [Exit codes](/cli/exit-codes) for the full mapping. ## Response ```jsonc theme={null} { "data": { "id": 18, "name": "Spring Summit", "timeZone": "America/Los_Angeles", "startAt": "2026-05-02T17:00:00Z", "endAt": "2026-05-02T22:00:00Z", "location": "San Francisco, CA", "peopleCount": 247, "tags": [{ "id": 12, "name": "Customer Conference" }], "createdAt": "2026-03-10T00:00:00Z" } } ``` `endAt` and `location` are null when the event was created without them. `tags` is always an array, empty when no tags are attached. ## See also * [`event list`](/cli/commands/path/event/list). Find the ID first. * [`event person list`](/cli/commands/path/event/person-list). Page through the registrants. * [`event person export`](/cli/commands/path/event/person-export). Stream the registrants as CSV. * [Events](/path/manage/events). The dashboard surface this command mirrors. # talkvalue path event Source: https://docs.trytalkvalue.com/cli/commands/path/event/index Manage events in Path: list, get, and pull the people who registered. `talkvalue path event` groups the read commands you need to inspect events and the people who registered for them. The same dataset powers the Events surface in the dashboard, so every event you see in the app is reachable from the CLI. ## Subcommands | Command | Description | | --------------------------------------------------------------- | ----------------------------------------------- | | [`event list`](/cli/commands/path/event/list) | List every event in the active workspace | | [`event get`](/cli/commands/path/event/get) | Fetch a single event by ID | | [`event person list`](/cli/commands/path/event/person-list) | Page through the people registered for an event | | [`event person export`](/cli/commands/path/event/person-export) | Stream the event registrants as CSV to stdout | ## Typical workflow Find an event, inspect it, then walk the people who registered: ```bash theme={null} talkvalue path event list talkvalue path event get 18 talkvalue path event person list 18 --sort "joinedAt,desc" --page-size 25 talkvalue path event person export 18 > spring-summit.csv ``` Every read prints a table by default and respects `--json` for piping into `jq`. The `person export` subcommand is the exception. It always emits CSV regardless of `--json` so you can redirect straight to a file. ## See also * [Events](/path/manage/events). The dashboard surface this group mirrors. * [`path channel`](/cli/commands/path/channel/index). The parallel group for channels. * [Recipe: New registrants this week](/cli/recipes/new-registrants). Pairs `event person list` with `--sort joinedAt,desc`. * [Recipe: CSV import](/cli/recipes/csv-import). `event person export` complements the import flow. # talkvalue path event list Source: https://docs.trytalkvalue.com/cli/commands/path/event/list List every event in the active workspace: name, time zone, start, location, people count, and tags. Print every event in the active workspace as a table or JSON. Useful as the first call when you want to find an event ID before drilling into the registrants, or as the data source for a recurring event-roster report. ## Synopsis ```bash theme={null} talkvalue path event list ``` ## Options This command takes no flags beyond the [global flags](/cli/global-flags). Filtering and pagination happen client-side. Pipe through `jq` or `--json` to slice the result. ## Examples ### 1. Browse events in the terminal ```bash theme={null} talkvalue path event list ``` Prints every event as a table: ID, name, time zone, start time, location, people count, tags, created-at. Newest events appear in the order the server returns them. ### 2. Find an event ID with jq ```bash theme={null} talkvalue path event list --json \ | jq '.data[] | select(.name | test("Summit"; "i")) | {id, name, startAt}' ``` Returns the ID, name, and start time of every event whose name contains `Summit` (case-insensitive). Use the ID with [`event get`](/cli/commands/path/event/get) or [`event person list`](/cli/commands/path/event/person-list). ### 3. Snapshot events into a report ```bash theme={null} ts=$(date +%Y-%m-%d) talkvalue path event list --json \ | jq -r '.data[] | [.id, .name, .startAt, .peopleCount] | @csv' \ > "snapshots/events-$ts.csv" ``` Loops over every event and writes a four-column CSV. Use a cron job for a periodic roster snapshot outside of TalkValue. ## Response ```jsonc theme={null} { "data": [ { "id": 18, "name": "Spring Summit", "timeZone": "America/Los_Angeles", "startAt": "2026-05-02T17:00:00Z", "endAt": "2026-05-02T22:00:00Z", "location": "San Francisco, CA", "peopleCount": 247, "tags": [{ "id": 12, "name": "Customer Conference" }], "createdAt": "2026-03-10T00:00:00Z" } ] } ``` `endAt` and `location` are null when the event was created without them, and `tags` is an empty array until you attach one. `peopleCount` is the count of distinct people who joined the event, the same number the dashboard shows on the Events list. ## See also * [`event get`](/cli/commands/path/event/get). Fetch one event by ID. * [`event person list`](/cli/commands/path/event/person-list). Drill into the people behind `peopleCount`. * [`event person export`](/cli/commands/path/event/person-export). Stream the registrants as CSV. * [Events](/path/manage/events). The dashboard surface this command mirrors. # talkvalue path event person export Source: https://docs.trytalkvalue.com/cli/commands/path/event/person-export Stream every registrant for an event as CSV to stdout. Always CSV regardless of --format. Dump the full registrant list for one event as CSV. The command writes directly to stdout and ignores `--format` / `--json`. Export is always CSV, by design, so it can be redirected straight to a file or piped into another tool. ## Synopsis ```bash theme={null} talkvalue path event person export <eventId> > registrants.csv ``` ## Arguments | Argument | Type | Description | | ----------- | ------- | ------------------------------------------------------------------------ | | `<eventId>` | integer | Event ID. Use [`event list`](/cli/commands/path/event/list) to find one. | ## Options This command takes no flags beyond the [global flags](/cli/global-flags). Passing `--json` or `--format json` prints a warning to stderr and still emits CSV. ## Examples ### 1. Save to a file ```bash theme={null} talkvalue path event person export 18 > spring-summit.csv ``` Writes the CSV to `spring-summit.csv`. The header row is always present. Column order matches the dashboard registrant export. ### 2. Pipe into a transformer ```bash theme={null} talkvalue path event person export 18 \ | csvtk grep -f Email -p "@acme.com$" \ > spring-summit-acme.csv ``` Streams the CSV through `csvtk` (or `mlr`, `xsv`, etc.) without ever touching disk. Useful when the registrant list is large enough that round-tripping JSON would be expensive. ### 3. Snapshot for handoff ```bash theme={null} ts=$(date +%Y-%m-%d) talkvalue path event person export 18 > "snapshots/event-18-$ts.csv" ``` Drop into a cron job or CI workflow for a periodic backup outside of TalkValue. Pair with the matching event ID in your file name so you can correlate snapshots over time. ## Response ```csv theme={null} Name,First Name,Last Name,Email,Emails,Company,Job Title,Phone,Phones,Address,Avatar URL,LinkedIn URL,X URL,Joined At "Alice Kim",Alice,Kim,alice@acme.com,alice@acme.com;alice.kim@personal.com,"Acme Inc.","Head of Growth",+1-415-555-0199,+1-415-555-0199,"San Francisco, CA",,,,2026-05-02T17:00:00Z … ``` `Joined At` is when the person registered for this event. `Emails` and `Phones` hold every address and number on the person, joined with `;`. Treat the first row as the header and parse the rest as data. ## See also * [`event person list`](/cli/commands/path/event/person-list). Filtered queries when you only need a subset. * [`event get`](/cli/commands/path/event/get). Confirm event metadata before exporting. * [Recipe: CSV import](/cli/recipes/csv-import). The matching import flow for round-tripping data. * [Events](/path/manage/events). The dashboard surface this command mirrors. # talkvalue path event person list Source: https://docs.trytalkvalue.com/cli/commands/path/event/person-list List people registered for an event with channel, company, job-title, keyword, and pagination filters. Page through the people registered for a single event. Combine filters to slice the roster, then pipe to `jq` or save as JSON. The dashboard event-detail page uses the same backend query. ## Synopsis ```bash theme={null} talkvalue path event person list <eventId> [options] ``` ## Arguments | Argument | Type | Description | | ----------- | ------- | ------------------------------------------------------------------------ | | `<eventId>` | integer | Event ID. Use [`event list`](/cli/commands/path/event/list) to find one. | ## Options | Flag | Type | Description | | ----------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | `--keyword <keyword>` | string | Free-text match against the person's name, every email address, and phone number. Use `--company-name` and `--job-title` to filter on those fields. | | `--channel-id <id>` | integer (repeatable) | Limit to people also joined to the given channel. Repeat to OR multiple. | | `--company-id <id>` | integer | Limit by company ID. | | `--company-name <name>` | string | Limit by company display name. | | `--job-title <title>` | string | Limit by job title. | | `--page <n>` | integer | Page number (zero-indexed). Defaults to `0`. | | `--page-size <n>` | integer | Page size. Defaults to the server default. | | `--sort <value>` | string (repeatable) | Sort expression `field,direction` (for example, `joinedAt,desc`). Repeat for secondary sorts. | ## Examples ### 1. Browse the latest registrants ```bash theme={null} talkvalue path event person list 18 --sort "joinedAt,desc" --page-size 20 ``` Prints the 20 most recent registrants as a table: ID, name, primary email, company, job title, joined-at, created-at. ### 2. Filter by channel and pipe to jq ```bash theme={null} talkvalue path event person list 18 \ --channel-id 7 \ --json \ | jq '.data[] | {name, primaryEmail, companyName}' ``` Returns people on event `18` who also belong to channel `7`, stripped to three fields. The `--json` envelope carries `.pagination`. ### 3. Walk every page in a script ```bash theme={null} page=0 while :; do resp=$(talkvalue path event person list 18 --page "$page" --page-size 100 --json) echo "$resp" | jq -e '.data | length > 0' >/dev/null || break echo "$resp" | jq '.data[]' page=$((page + 1)) done ``` Loops until a page returns no rows. See [Scripting with jq](/cli/recipes/scripting-with-jq) for richer pagination patterns. ## Response ```jsonc theme={null} { "data": [ { "id": 142, "name": "Alice Kim", "primaryEmail": "alice@acme.com", "primaryPhone": "+1-415-555-0199", "company": { "id": 88, "displayName": "Acme Inc.", "domain": "acme.com", "nameUpdatable": false }, "companyName": "Acme Inc.", "jobTitle": "Head of Growth", "channels": [/* … */], "events": [/* … */], "joinedAt": "2026-05-02T17:00:00Z", "createdAt": "2026-04-12T00:00:00Z" } ], "pagination": { "page": 0, "pageSize": 20, "totalElements": 247, "totalPages": 13 } } ``` `pagination` appears only in `--json`. `companyName` is a flattened convenience field. The full `company` object is also included. `joinedAt` is when the person registered for the event. The `channels` array carries a slim per-person shape — `{ id, name, icon, joinedAt }` — and `events` carries `{ id, name, joinedAt }`. These are narrower than the full records returned by [`path channel`](/cli/commands/path/channel/list) and [`path event`](/cli/commands/path/event/list). ## See also * [`event person export`](/cli/commands/path/event/person-export). Stream every registrant as CSV. * [`path person list`](/cli/commands/path/person/list). Workspace-wide people query with the same filter grammar. * [Recipe: New registrants this week](/cli/recipes/new-registrants). `--sort joinedAt,desc` report. * [Events](/path/manage/events). The dashboard surface this command mirrors. # talkvalue path import analyze Source: https://docs.trytalkvalue.com/cli/commands/path/import/analyze Upload a CSV file, get a fileKey, and preview the server's column mapping before creating an import job. Pre-check a CSV without committing to an import. The command uploads the file to TalkValue's import staging area, returns a `fileKey` you pass to `import create`, and prints the headers, a sample preview, and TalkValue's suggested column mapping. Required target fields the file cannot satisfy come back under `missingRequired` so you can fix the file before running the full import. ## Synopsis ```bash theme={null} talkvalue path import analyze --file <path> ``` ## Options | Flag | Type | Description | | --------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--file <path>` | string (required) | Path to the CSV file on disk. Read locally, uploaded as `multipart/form-data`. Permission and "file not found" errors surface as usage errors with no upload attempt. | ## Examples ### 1. Inspect a file before importing ```bash theme={null} talkvalue path import analyze --file ./registrants.csv ``` Prints a single record with the `fileKey`, the row count, headers, the first few rows as preview, and the suggested column mappings. ### 2. Pipe the mapping into a script ```bash theme={null} talkvalue path import analyze --file ./registrants.csv --json \ | jq -r '.data.columnMappings[] | "\(.csvIndex):\(.suggestedField)"' ``` Prints one `csvIndex:targetField` pair per line, ready to feed into `import create --mapping`. Capture `.data.fileKey` from the same response and you have both pieces the create step needs. ### 3. Halt the pipeline when required fields are missing ```bash theme={null} talkvalue path import analyze --file ./bad.csv --json \ | jq -e '.data.missingRequired | length == 0' \ || { echo "Fix required columns and try again"; exit 1; } ``` `jq -e` exits non-zero if `missingRequired` has entries, so the surrounding shell can fail loudly instead of forwarding a broken file to `import create`. ## Response ```jsonc theme={null} { "data": { "fileKey": "u/2026/05/9f1a-registrants.csv", "totalRows": 1247, "headers": ["email", "first_name", "last_name", "company"], "preview": [ ["alice@acme.com", "Alice", "Kim", "Acme"] ], "columnMappings": [ { "csvIndex": 0, "csvHeader": "email", "suggestedField": "EMAIL", "confidence": 0.98, "suggestions": [] }, { "csvIndex": 1, "csvHeader": "first_name", "suggestedField": "FIRST_NAME", "confidence": 0.92, "suggestions": [] } ], "missingRequired": [] } } ``` `fileKey` is the only field you must keep. It is the handle `import create` requires. Each entry in `columnMappings` carries the CSV column's index and header alongside the server's `suggestedField` guess plus a confidence score. Pass `csvIndex:suggestedField` to `import create --mapping`, overriding any guess you disagree with. ## See also * [`import create`](/cli/commands/path/import/create). The next step that consumes the `fileKey` and mapping. * [Column mapping](/path/import/column-mapping). The full list of valid target fields. * [Recipe: CSV import](/cli/recipes/csv-import). Analyze, create, status in one script. # talkvalue path import create Source: https://docs.trytalkvalue.com/cli/commands/path/import/create Start a bulk CSV import job from a fileKey, a channel as the source, an upsert mode, and a column mapping. Start an import job from an analyzed CSV. The command takes the `fileKey` returned by `import analyze`, the channel ID that owns the new people, an upsert mode that decides what happens on email collisions, and one or more column mappings that pin CSV columns to TalkValue target fields. It returns immediately with the job ID. Use `import get` to poll until completion. ## Synopsis ```bash theme={null} talkvalue path import create \ --file-key <key> \ --source-id <channel-id> \ --mode <UPDATE|SKIP> \ --mapping <csvIndex:targetField> [--mapping ...] ``` ## Options | Flag | Type | Description | | ---------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--file-key <key>` | string (required) | The `fileKey` returned by [`import analyze`](/cli/commands/path/import/analyze). | | `--source-id <id>` | integer (required) | Channel ID that receives the people. Find it with [`path channel list`](/cli/commands/path/channel/list). | | `--mode <mode>` | enum (required) | `UPDATE` overwrites existing fields on email match. `SKIP` leaves the existing record untouched and counts the row under `skipCount`. | | `--mapping <csvIndex:targetField>` | string (repeatable, ≥1) | Map a zero-indexed CSV column to a TalkValue field. Valid targets: `EMAIL`, `FIRST_NAME`, `LAST_NAME`, `NAME`, `PHONE`, `JOB_TITLE`, `COMPANY_NAME`, `ADDRESS`, `LINKEDIN_URL`, `X_URL`, `JOINED_AT`. | ## Examples ### 1. Import three columns into channel 7 in UPDATE mode ```bash theme={null} talkvalue path import create \ --file-key "u/2026/05/9f1a-registrants.csv" \ --source-id 7 \ --mode UPDATE \ --mapping 0:EMAIL \ --mapping 1:FIRST_NAME \ --mapping 2:LAST_NAME ``` Returns the new job ID and an initial status of `PENDING` or `RUNNING`. The job continues in the background. ### 2. Capture the job ID for the rest of the script ```bash theme={null} job_id=$( talkvalue path import create \ --file-key "$FILE_KEY" \ --source-id 7 \ --mode SKIP \ --mapping 0:EMAIL --mapping 1:NAME --mapping 2:COMPANY_NAME \ --json | jq -r '.data.importJobId' ) talkvalue path import get "$job_id" ``` The two-line pattern is the basis for the full [CSV import recipe](/cli/recipes/csv-import). ### 3. Treat duplicates as silent skips ```bash theme={null} talkvalue path import create \ --file-key "$FILE_KEY" \ --source-id 12 \ --mode SKIP \ --mapping 0:EMAIL --mapping 1:FIRST_NAME --mapping 2:COMPANY_NAME ``` `SKIP` is the right mode when you receive a weekly registrant export and you want every new email but you do not want to overwrite manual edits made in the dashboard. ## Response ```jsonc theme={null} { "data": { "importJobId": 4218, "status": "PENDING" } } ``` `status` is the snapshot at submission. Real progress lives on the job record returned by [`import get`](/cli/commands/path/import/status). ## See also * [`import analyze`](/cli/commands/path/import/analyze). The prerequisite step that produces the `fileKey`. * [`import get`](/cli/commands/path/import/status). Poll the job until it reaches a terminal state. * [`import failed-export`](/cli/commands/path/import/export-failures). Pull the rejected rows after a partial success. * [Column mapping](/path/import/column-mapping). The full target-field reference. # talkvalue path import failed-export Source: https://docs.trytalkvalue.com/cli/commands/path/import/export-failures Stream the rejected rows from an import job as CSV so you can fix and re-import them. Stream every rejected row from an import job to stdout as CSV, in the exact shape of the file you uploaded. Redirect it to a file, fix the values, and re-import. The output is always CSV. The global `--format` and `--json` flags emit a stderr warning and are otherwise ignored. ## Synopsis ```bash theme={null} talkvalue path import failed-export <id> > failed.csv ``` ## Arguments | Argument | Type | Description | | -------- | ------- | ---------------------------------------------------------------------------------- | | `<id>` | integer | The `importJobId` returned by [`import create`](/cli/commands/path/import/create). | ## Examples ### 1. Save failures to a file ```bash theme={null} talkvalue path import failed-export 4218 > failed-4218.csv ``` Captures the rejected rows with the uploaded file's own header row, so you can fix the values in place and feed the file straight back to [`import create`](/cli/commands/path/import/create). ### 2. Count failures grouped by error code ```bash theme={null} talkvalue path import get 4218 --json \ | jq -r '.data.failedRows[].errorCode' \ | sort | uniq -c | sort -rn ``` Reads the error codes off the job record and prints the rank-ordered failure types. Useful when triaging which fix recovers the most rows. ### 3. Only run when the job had failures ```bash theme={null} job_id=4218 failed=$(talkvalue path import get "$job_id" --json | jq -r '.data.failedCount') if [ "$failed" -gt 0 ]; then talkvalue path import failed-export "$job_id" > "failed-$job_id.csv" fi ``` Pairs `import get` with `failed-export` so the CSV file only appears when there is something to fix. ## Response The command writes raw CSV to stdout, not the standard JSON envelope. The columns match the file you uploaded. ```csv theme={null} email,first_name,last_name,company alice@@acme.com,Alice,Kim,Acme ,Bob,Lee,Globex ``` If TalkValue returns a non-200 status the command fails with a usage error carrying the HTTP status. No CSV is written. ## See also * [`import get`](/cli/commands/path/import/status). Branch on `failedCount` before exporting. * [`import create`](/cli/commands/path/import/create). Re-import the fixed CSV with the same channel and mode. * [Recipe: CSV import](/cli/recipes/csv-import). Uses this command in the failure-recovery branch. # talkvalue path import Source: https://docs.trytalkvalue.com/cli/commands/path/import/index Run the CSV bulk import workflow from the CLI: analyze a file, create the job, monitor progress, and export failures. `talkvalue path import` is the CLI surface of the bulk CSV import feature. The flow has four scriptable steps: upload and analyze the file, create the job with a column mapping, monitor the job until it reaches a terminal state, and export any rows the server rejected. The same pipeline backs the dashboard import wizard. ## Subcommands | Command | Description | | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | [`import analyze`](/cli/commands/path/import/analyze) | Upload a CSV and pre-check it. Returns a `fileKey`, headers, a preview, and the server's guess at the column mapping. | | [`import create`](/cli/commands/path/import/create) | Start an import job from a `fileKey` plus a mapping. Returns the job ID. | | [`import get`](/cli/commands/path/import/status) | Inspect a job. Use it to poll until `status` is `COMPLETED`, `PARTIAL_SUCCESS`, or `FAILED`. | | [`import failed-export`](/cli/commands/path/import/export-failures) | Stream rejected rows as CSV so you can fix them and re-import. | ## Typical workflow ```bash theme={null} talkvalue path import analyze --file ./registrants.csv --json # pick the fileKey, columnMappings, and a sourceId (channel id) talkvalue path import create \ --file-key "u/2026/05/abc.csv" \ --source-id 7 \ --mode UPDATE \ --mapping 0:EMAIL --mapping 1:FIRST_NAME --mapping 2:LAST_NAME talkvalue path import get 4218 talkvalue path import failed-export 4218 > failed.csv ``` Each step is idempotent on the CLI side. Re-running `analyze` produces a new `fileKey` without touching prior imports, and `get` is a read. Only `create` writes, and the resulting job has its own ID so repeating the command queues a second import rather than overwriting the first. ## See also * [Recipe: CSV import](/cli/recipes/csv-import). The end-to-end script that drives this group. * [CSV import](/path/import/csv-quickstart). The dashboard wizard the CLI mirrors. * [Column mapping](/path/import/column-mapping). The target-field reference shared by both surfaces. * [`path channel list`](/cli/commands/path/channel/list). Find the `sourceId` (channel ID) you import into. # talkvalue path import get Source: https://docs.trytalkvalue.com/cli/commands/path/import/status Inspect a bulk import job by ID: status, row counts, and per-bucket totals like new, updated, duplicated, and failed. Fetch the current state of an import job. The job moves through `PENDING` → `RUNNING` → one of `COMPLETED`, `PARTIAL_SUCCESS`, or `FAILED`. The response carries the running counts you need to decide whether the import succeeded, whether you need to investigate failures, and whether re-importing is worthwhile. ## Synopsis ```bash theme={null} talkvalue path import get <id> ``` ## Arguments | Argument | Type | Description | | -------- | ------- | ---------------------------------------------------------------------------------- | | `<id>` | integer | The `importJobId` returned by [`import create`](/cli/commands/path/import/create). | ## Examples ### 1. One-off status check ```bash theme={null} talkvalue path import get 4218 ``` Prints the job as a single-record table: status, mode, file name, total and processed rows, and the bucket counts. ### 2. Poll until terminal ```bash theme={null} job_id=4218 while :; do status=$(talkvalue path import get "$job_id" --json | jq -r '.data.status') case "$status" in COMPLETED|PARTIAL_SUCCESS|FAILED) echo "Done: $status"; break ;; esac sleep 5 done ``` The three terminal states map to "everything imported", "some rows failed and the rest succeeded", and "the whole job failed before any rows landed". Branch on the status to decide whether to call [`import failed-export`](/cli/commands/path/import/export-failures). ### 3. Print only the failure summary ```bash theme={null} talkvalue path import get 4218 --json \ | jq '.data | {status, failedCount, totalRows, processedRows}' ``` Useful inside a script that should alert when `failedCount > 0` regardless of overall status. ## Response ```jsonc theme={null} { "data": { "id": 4218, "status": "PARTIAL_SUCCESS", "mode": "UPDATE", "fileName": "registrants.csv", "totalRows": 1247, "processedRows": 1247, "newCount": 1100, "updatedCount": 120, "duplicatedCount": 22, "skipCount": 0, "failedCount": 5, "failedRows": [ { "rowNum": 47, "errorCode": "INVALID_EMAIL", "errorMessage": "Email could not be parsed", "rawValue": "alice@@acme.com" } /* … 4 more, one per failed row … */ ], "processStartedAt": "2026-05-15T10:42:01Z", "completedAt": "2026-05-15T10:43:27Z" } } ``` `failedRows` lists every rejected row with its error code and the raw value that tripped it, so `failedRows` and `failedCount` always agree. [`import failed-export`](/cli/commands/path/import/export-failures) returns those same rows in their original CSV form, ready to fix and re-import. ## See also * [`import create`](/cli/commands/path/import/create). The step that returns the `importJobId`. * [`import failed-export`](/cli/commands/path/import/export-failures). Pull the full failed-rows CSV when `failedCount > 0`. * [Recipe: CSV import](/cli/recipes/csv-import). Uses this command as the poll step. # talkvalue path overview Source: https://docs.trytalkvalue.com/cli/commands/path/overview Dashboard summary stats for the active workspace: people, channels, events, and growth signals. Print the dashboard summary numbers you see on the TalkValue home screen (people, channels, events, companies, plus diversification, growth, and retention signals) for the active workspace. Use `--tag-id` to scope the growth and retention signals to one tag. ## Synopsis ```bash theme={null} talkvalue path overview [--tag-id <id>] [--timezone <tz>] ``` ## Options | Flag | Type | Description | | ----------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- | | `--tag-id <id>` | integer | Scope the growth and retention signals to events carrying this tag. Tag IDs come from `talkvalue path tag create` or the dashboard. | | `--timezone <tz>` | string | IANA timezone (for example, `America/Los_Angeles`) used for the month boundaries behind `newPeopleThisMonth`. Defaults to `UTC`. | A `stats` subcommand returns a slightly different shape with top channels and the latest trend. Run `talkvalue path overview stats --help` for its options. ## Examples ### 1. Snapshot in the terminal ```bash theme={null} talkvalue path overview ``` Prints the workspace totals as a table: people, channels, events, companies, new people this month, plus growth and retention deltas. ### 2. Pull totals into a script ```bash theme={null} talkvalue path overview --json | jq '.data | {peopleCount, eventCount, newPeopleThisMonth}' ``` Returns just the headline counts. Drop the `jq` filter for the full envelope. ### 3. Scope growth and retention to a tag ```bash theme={null} talkvalue path overview --tag-id 42 --json ``` Scopes the `growth` and `retention` blocks to events carrying tag `42`. Combine with [`talkvalue path tag attach`](/cli/commands/path/tag/attach) to maintain tag-scoped trend reports. ## Response ```jsonc theme={null} { "data": { "eventCount": 18, "peopleCount": 4321, "channelCount": 12, "newPeopleThisMonth": 187, "totalCompanies": 642, "diversification": { /* … */ }, "growth": { /* … */ }, "retention": { /* … */ } } } ``` `diversification`, `growth`, and `retention` are nested objects that match the dashboard's overview cards: channel mix, registration trend, and return-visit signals. Inspect each subtree to compose richer reports. ## See also * [`talkvalue path person list`](/cli/commands/path/person/list). Drill into the people behind `peopleCount`. * [`talkvalue path event list`](/cli/commands/path/event/list). List the events behind `eventCount`. * [`talkvalue path analysis channel-attribution`](/cli/commands/path/analysis/channel-attribution). Channel-level revenue and reach. * [Registration trend](/path/analytics/registration-trend). The dashboard surface this command mirrors. # talkvalue path person activity Source: https://docs.trytalkvalue.com/cli/commands/path/person/activity Page through the activity log for a single person: creates, updates, merges, source connections, and more. `talkvalue path person activity` lists the change log for one person. Every create, update, delete, merge, restore, and source connect / disconnect shows up here, with the actor who triggered it, the fields that changed, and (for source events) the channel or event the change came from. Pagination is cursor-based. The CLI prints a `Next page: --cursor <id>` hint on stderr whenever more rows exist. ## Synopsis ```bash theme={null} talkvalue path person activity <personId> [--cursor <n>] [--page-size <n>] ``` ## Arguments | Argument | Type | Description | | ------------ | ------- | ---------------------------------- | | `<personId>` | integer | Person ID whose activity you want. | ## Options | Flag | Type | Description | | ----------------- | ------- | --------------------------------------------------------------------------------------------------------------- | | `--cursor <n>` | integer | Cursor returned by the previous page (printed to stderr as `Next page: --cursor <n>`). Omit for the first page. | | `--page-size <n>` | integer | Page size. Defaults to the server default. | ## Examples ### 1. Recent activity in the terminal ```bash theme={null} talkvalue path person activity 142 ``` Prints ID, action, actor, and created-at columns for the most recent page. Read the stderr hint to fetch the next page. ### 2. Walk every page until exhausted ```bash theme={null} cursor="" while :; do flags=("--json") [ -n "$cursor" ] && flags+=("--cursor" "$cursor") out=$(talkvalue path person activity 142 "${flags[@]}" 2>/tmp/last.err) echo "$out" | jq '.data[]' echo "$out" | jq -e '.data | length > 0' >/dev/null || break cursor=$(awk '/Next page:/ {print $NF}' /tmp/last.err) [ -z "$cursor" ] && break done ``` The loop reads JSON pages on stdout and parses the `Next page: --cursor <id>` hint from stderr. See [Scripting with jq](/cli/recipes/scripting-with-jq) for more patterns. ### 3. Audit a merge ```bash theme={null} talkvalue path person activity 142 --json \ | jq '.data[] | select(.action == "MERGED")' ``` Pulls only the `MERGED` entries. Each one carries `mergedFrom.personId` and `mergedFrom.primaryEmail` so you can trace the source that was absorbed. ## Response ```jsonc theme={null} { "data": [ { "id": 9012, "action": "UPDATED", "actor": { "id": 3, "name": "Ted Lee", "email": "ted@acme.com" }, "actorName": "Ted Lee", "changes": [ { "field": "jobTitle", "before": "Growth Lead", "after": "Head of Growth" } ], "source": null, "mergedFrom": null, "createdAt": "2026-05-21T17:42:11Z" } ] } ``` `action` is one of `CREATED`, `UPDATED`, `DELETED`, `RESTORED`, `MERGED`, `UNMERGED`, `SOURCE_CONNECTED`, or `SOURCE_DISCONNECTED`. The presence of `changes`, `source`, and `mergedFrom` depends on the action. Read [`person update`](/cli/commands/path/person/update) and [`person merge`](/cli/commands/path/person/merge) for the shapes they emit. When more pages exist, look for `Next page: --cursor <n>` on stderr and replay with that cursor. ## See also * [`person update`](/cli/commands/path/person/update). Generates `UPDATED` entries. * [`person merge`](/cli/commands/path/person/merge). Generates `MERGED` entries on the target. * [`person get`](/cli/commands/path/person/get). Pair with activity for full context. * [People](/path/manage/people). The dashboard surface with the same timeline. # talkvalue path person delete Source: https://docs.trytalkvalue.com/cli/commands/path/person/delete Delete a person record from the active workspace. Requires --confirm. Remove a person from the active workspace. The CLI refuses to run without `--confirm`. There is no interactive prompt, so scripts have to opt in explicitly. Deletion is immediate. When the same primary email arrives again through [`import create`](/cli/commands/path/import/create), an integration sync, or a person added in the dashboard, TalkValue restores the record with its history intact. ## Synopsis ```bash theme={null} talkvalue path person delete <id> --confirm ``` ## Arguments | Argument | Type | Description | | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | `<id>` | integer | Person ID to delete. Use [`person list`](/cli/commands/path/person/list) or [`person get`](/cli/commands/path/person/get) to verify the target first. | ## Options | Flag | Type | Description | | ----------- | ---- | ----------------------------------------------------------------- | | `--confirm` | flag | Required. The CLI exits with a usage error if you omit this flag. | ## Examples ### 1. Delete a single record ```bash theme={null} talkvalue path person delete 142 --confirm ``` Prints `{ "deleted": true, "id": 142 }` as a table on success. Re-running the command on a missing ID returns a `404` and a non-zero exit code. ### 2. Pipe to jq for a clean assertion ```bash theme={null} talkvalue path person delete 142 --confirm --json \ | jq -e '.data.deleted == true' ``` `jq -e` exits non-zero if `deleted` is anything but `true`, so the surrounding script fails closed. ### 3. Bulk delete from a file of IDs ```bash theme={null} while read -r id; do talkvalue path person delete "$id" --confirm --json \ | jq -c '{id: .data.id, deleted: .data.deleted}' done < ids-to-delete.txt ``` Process one ID per line. Capture stderr to a log file if you need to inspect failures separately. ## Response ```jsonc theme={null} { "data": { "deleted": true, "id": 142 } } ``` The acknowledgement object is the only payload. The deleted person record itself is not returned. Read [`person activity`](/cli/commands/path/person/activity) on the ID before you delete when you want a copy of the timeline outside TalkValue. ## See also * [`person merge`](/cli/commands/path/person/merge). Prefer merge over delete when consolidating duplicates. * [`person activity`](/cli/commands/path/person/activity). Review the full timeline before deleting. * [`person get`](/cli/commands/path/person/get). Confirm you have the right ID. * [People](/path/manage/people). The dashboard surface this command mirrors. # talkvalue path person export Source: https://docs.trytalkvalue.com/cli/commands/path/person/export Stream every person in the active workspace as CSV to stdout. `talkvalue path person export` streams every person in the active workspace as CSV to stdout. The command writes directly to stdout and ignores `--format` / `--json`. Export is always CSV, so it can be redirected straight to a file or piped into another tool. ## Synopsis ```bash theme={null} talkvalue path person export > people.csv ``` ## Options This command takes no flags beyond the [global flags](/cli/global-flags). Passing `--json` or `--format json` prints a warning to stderr and still emits CSV. ## Examples ### 1. Save to a file ```bash theme={null} talkvalue path person export > people.csv ``` Writes the CSV to `people.csv`. The header row is always present. Column order matches the dashboard export. ### 2. Pipe into a transformer ```bash theme={null} talkvalue path person export \ | csvtk grep -f Email -p "@acme.com$" \ > acme-people.csv ``` Streams the CSV through `csvtk` (or `mlr`, `xsv`, etc.) without ever touching disk. Useful when the dataset is large enough that round-tripping JSON would be expensive. ### 3. Snapshot for archival ```bash theme={null} ts=$(date +%Y-%m-%d) talkvalue path person export > "snapshots/people-$ts.csv" ``` Drop into a cron job or CI workflow for a periodic backup outside of TalkValue. See [Recipe: CSV import](/cli/recipes/csv-import) for the round-trip pattern. ## Response ```csv theme={null} Name,First Name,Last Name,Email,Emails,Company,Job Title,Phone,Phones,Address,Avatar URL,LinkedIn URL,X URL "Alice Kim",Alice,Kim,alice@acme.com,alice@acme.com;alice.kim@personal.com,"Acme Inc.","Head of Growth",+1-415-555-0199,+1-415-555-0199,"San Francisco, CA",,https://linkedin.com/in/alicekim, … ``` `Emails` and `Phones` hold every address and number on the person, joined with `;`. The file carries a UTF-8 BOM so it opens directly in Excel. Treat the first row as the header and parse the rest as data. ## See also * [`person list`](/cli/commands/path/person/list). Filtered queries for narrower exports. * [Recipe: CSV import](/cli/recipes/csv-import). The matching import flow for round-tripping data. * [Recipe: New registrants this week](/cli/recipes/new-registrants). A focused export driven by `person list --json`. * [People](/path/manage/people). The dashboard surface this command mirrors. # talkvalue path person get Source: https://docs.trytalkvalue.com/cli/commands/path/person/get Fetch a single person record by ID, including channels and events. Pull the full record for one person. The response is the same shape the dashboard People detail page renders: primary email and phone, company, job title, and the channels and events the person has joined. ## Synopsis ```bash theme={null} talkvalue path person get <id> ``` ## Arguments | Argument | Type | Description | | -------- | ------- | --------------------------------------------------------------------------- | | `<id>` | integer | Person ID. Use [`person list`](/cli/commands/path/person/list) to find one. | ## Examples ### 1. Inspect a person in the terminal ```bash theme={null} talkvalue path person get 142 ``` Prints a single-row table with the headline fields. Use `--json` if you need the nested `company`, `channels`, and `events` arrays. ### 2. Read one field with jq ```bash theme={null} talkvalue path person get 142 --json | jq -r '.data.primaryEmail.email' ``` Returns the primary email address as a raw string. `primaryEmail` is an object with `email`, `type`, and `domain` fields. Use `.email` to pull the address. Combine with other commands when you only need an identifier, for example, looking up an email before calling `update`. ### 3. Use inside a guard ```bash theme={null} if talkvalue path person get 142 --json >/dev/null 2>&1; then echo "Person 142 exists" else echo "Person 142 not found" fi ``` The CLI exits non-zero on `404` so the guard above branches cleanly. See [Exit codes](/cli/exit-codes) for the full mapping. ## Response ```jsonc theme={null} { "data": { "id": 142, "name": "Alice Kim", "primaryEmail": { "email": "alice@acme.com", "type": "WORK", "domain": "acme.com" }, "emails": [ { "email": "alice@acme.com", "type": "WORK", "domain": "acme.com" } ], "primaryPhone": "+1-415-555-0199", "company": { "id": 88, "displayName": "Acme Inc.", "domain": "acme.com", "nameUpdatable": false }, "jobTitle": "Head of Growth", "channels": [ { "id": 7, "name": "Newsletter", "icon": null, "joinedAt": "2026-04-12T00:00:00Z" } ], "events": [ { "id": 18, "name": "Spring Summit", "startAt": "2026-05-02T17:00:00Z", "joinedAt": "2026-05-02T00:00:00Z" } ], "mergeOperations": [], "createdAt": "2026-04-12T00:00:00Z" } } ``` `primaryEmail` is an object with `email`, `type`, and `domain` fields. The full email list lives on `emails`. `channels` and `events` arrays are limited to the records the person currently belongs to. `mergeOperations` records every merge that produced this person; pass the entry's `id` to [`person merge-undo`](/cli/commands/path/person/merge-undo) to reverse one. ## See also * [`person list`](/cli/commands/path/person/list). Find the ID first. * [`person update`](/cli/commands/path/person/update). Change fields on the returned record. * [`person activity`](/cli/commands/path/person/activity). See how this record has changed over time. * [People](/path/manage/people). The dashboard surface this command mirrors. # talkvalue path person Source: https://docs.trytalkvalue.com/cli/commands/path/person/index Manage people in Path: list, get, update, delete, merge, export, and inspect activity history. `talkvalue path person` groups every command that reads or writes a single person record in Path. The same dataset powers the People surface in the dashboard, so every change you make here is reflected in the dashboard. ## Subcommands | Command | Description | | ----------------------------------------------------------- | ------------------------------------------------------------------------ | | [`person list`](/cli/commands/path/person/list) | List people with keyword, channel, event, company, and job-title filters | | [`person get`](/cli/commands/path/person/get) | Fetch a single person by ID, including channels and events | | [`person update`](/cli/commands/path/person/update) | Update names, emails, phones, job, social URLs, or company assignment | | [`person delete`](/cli/commands/path/person/delete) | Delete a person. Requires `--confirm`. | | [`person merge`](/cli/commands/path/person/merge) | Merge a source person into a target person. Requires `--confirm`. | | [`person merge-undo`](/cli/commands/path/person/merge-undo) | Reverse a merge by `mergeOperationId`. Requires `--confirm`. | | [`person export`](/cli/commands/path/person/export) | Stream the full people list as CSV to stdout | | [`person activity`](/cli/commands/path/person/activity) | Page through the activity log for a single person | ## Typical workflow Find a person, inspect their record, and update a missing field: ```bash theme={null} talkvalue path person list --keyword "alice@" --page-size 5 talkvalue path person get 142 talkvalue path person update 142 --job-title "Head of Growth" ``` Every subcommand respects `--json` for piping into `jq` or another script, and every read prints a table by default. Mutating commands (`update`, `delete`, `merge`) print the resulting record (or a `{ deleted: true }` / `{ undone: true }` acknowledgement) so you can confirm the write succeeded. ## See also * [People](/path/manage/people). The dashboard surface this group mirrors. * [Recipe: New registrants this week](/cli/recipes/new-registrants). End-to-end script that drives `person list`. * [Recipe: CSV import](/cli/recipes/csv-import). `person export` complements the import flow. * [Recipe: Scripting with jq](/cli/recipes/scripting-with-jq). Patterns for piping `--json` output. # talkvalue path person list Source: https://docs.trytalkvalue.com/cli/commands/path/person/list List people in Path with keyword, channel, event, company, and job-title filters, plus pagination. Page through the people in the active workspace. Combine filters to narrow the result, then pipe to `jq` or save as JSON. The dashboard People page uses the same backend query. ## Synopsis ```bash theme={null} talkvalue path person list [options] ``` ## Options | Flag | Type | Description | | ----------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | `--keyword <keyword>` | string | Free-text match against the person's name, every email address, and phone number. Use `--company-name` and `--job-title` to filter on those fields. | | `--channel-id <id>` | integer (repeatable) | Limit to people in the given channel. Repeat to OR multiple. | | `--event-id <id>` | integer (repeatable) | Limit to people registered for the given event. Repeat to OR multiple. | | `--company-id <id>` | integer | Limit by company ID. | | `--company-name <name>` | string | Limit by company display name. | | `--job-title <title>` | string | Limit by job title. | | `--page <n>` | integer | Page number (zero-indexed). Defaults to `0`. | | `--page-size <n>` | integer | Page size. Defaults to the server default. | | `--sort <value>` | string (repeatable) | Sort expression `field,direction` (for example, `createdAt,desc`). Repeat for secondary sorts. | ## Examples ### 1. Browse the latest people ```bash theme={null} talkvalue path person list --sort "createdAt,desc" --page-size 20 ``` Prints the 20 newest people as a table: ID, name, primary email, company, job title, and created-at. ### 2. Filter by channel and pipe to jq ```bash theme={null} talkvalue path person list \ --channel-id 7 --channel-id 12 \ --json \ | jq '.data[] | {id, name, primaryEmail}' ``` Returns people in channel `7` or `12`, stripped to the three fields. The `--json` envelope also carries `.pagination`. ### 3. Walk every page in a script ```bash theme={null} page=0 while :; do resp=$(talkvalue path person list --page "$page" --page-size 100 --json) echo "$resp" | jq -e '.data | length > 0' >/dev/null || break echo "$resp" | jq '.data[]' page=$((page + 1)) done ``` Loops until a page returns no rows. See [Scripting with jq](/cli/recipes/scripting-with-jq) for richer pagination patterns. ## Response ```jsonc theme={null} { "data": [ { "id": 142, "name": "Alice Kim", "primaryEmail": "alice@acme.com", "primaryPhone": "+1-415-555-0199", "company": { "id": 88, "displayName": "Acme Inc.", "domain": "acme.com", "nameUpdatable": false }, "companyName": "Acme Inc.", "jobTitle": "Head of Growth", "channels": [/* … */], "events": [/* … */], "joinedAt": null, "createdAt": "2026-04-12T00:00:00Z" } ], "pagination": { "page": 0, "pageSize": 20, "totalElements": 4321, "totalPages": 217 } } ``` `pagination` appears only in `--json`. `companyName` is a flattened convenience field, and the full `company` object is also included. `joinedAt` carries a value on the source-scoped lists, [`channel people`](/cli/commands/path/channel/people) and [`event person list`](/cli/commands/path/event/person-list), where it records when the person joined that channel or event. ## See also * [`person get`](/cli/commands/path/person/get). Fetch a single record in full detail. * [`person export`](/cli/commands/path/person/export). Stream every person as CSV. * [Recipe: New registrants this week](/cli/recipes/new-registrants). `--sort createdAt,desc` driven report. * [Recipe: Channel analysis](/cli/recipes/channel-analysis). `--channel-id` filtering in scripts. * [People](/path/manage/people). The dashboard surface this command mirrors. # talkvalue path person merge Source: https://docs.trytalkvalue.com/cli/commands/path/person/merge Merge a source person into a target person, consolidating channels, events, and history. Requires --confirm. `talkvalue path person merge` consolidates two duplicate person records into one. The source person's emails, phones, channels, events, and activity history move into the target, and TalkValue retires the source ID. Prefer this over `delete` whenever you spot a duplicate. Attribution and event history from both records remain attached to the target. ## Synopsis ```bash theme={null} talkvalue path person merge <sourceId> <targetId> --confirm ``` ## Arguments | Argument | Type | Description | | ------------ | ------- | ------------------------------------------------------------------------------------- | | `<sourceId>` | integer | Person ID to merge **from**. After the call this ID stops resolving via `person get`. | | `<targetId>` | integer | Person ID to merge **into**. This record survives and absorbs the source. | ## Options | Flag | Type | Description | | ----------- | ---- | ----------------------------------------------------------------- | | `--confirm` | flag | Required. The CLI exits with a usage error if you omit this flag. | ## Examples ### 1. Merge two duplicates ```bash theme={null} talkvalue path person merge 199 142 --confirm ``` Merges person `199` into person `142`. The output is the target's updated record, same shape as [`person get`](/cli/commands/path/person/get), so you can verify the merged email, phone, and channel set. ### 2. Inspect both before merging ```bash theme={null} talkvalue path person get 199 --json > source.json talkvalue path person get 142 --json > target.json diff <(jq '.data.primaryEmail' source.json) <(jq '.data.primaryEmail' target.json) && echo "same person?" ``` This checks the records match before the destructive call, which is useful in CI scripts that auto-merge on an email match. ### 3. Roll back a mistake To reverse a merge, use [`person merge-undo`](/cli/commands/path/person/merge-undo): ```bash theme={null} talkvalue path person merge-undo 503 --confirm ``` Read the merge operation ID from the target's detail record with `talkvalue path person get 142 --json | jq -r '.data.mergeOperations[0].id'`, or from the dashboard's activity log. ## Response ```jsonc theme={null} { "data": { "id": 142, "name": "Alice Kim", "primaryEmail": { "email": "alice@acme.com", "type": "WORK", "domain": "acme.com" }, "emails": [ { "email": "alice@acme.com", "type": "WORK", "domain": "acme.com" }, { "email": "alice.kim@personal.com", "type": "PERSONAL", "domain": "personal.com" } ], "primaryPhone": "+1-415-555-0199", "company": { "id": 88, "displayName": "Acme Inc.", "domain": "acme.com", "nameUpdatable": false }, "jobTitle": "Head of Growth", "channels": [/* combined */], "events": [/* combined */], "mergeOperations": [], "createdAt": "2026-04-12T00:00:00Z" } } ``` The returned record is the target person after the merge, with channels and events from both records combined. Calls to `person get 199` after the merge return `404`. `mergeOperations` is populated by [`person get`](/cli/commands/path/person/get); call it on the target when you need the operation ID. ## See also * [`person get`](/cli/commands/path/person/get). Verify source and target before merging. * [`person merge-undo`](/cli/commands/path/person/merge-undo). Reverse a merge. * [`person activity`](/cli/commands/path/person/activity). `MERGED` entries record the source → target link. * [`person delete`](/cli/commands/path/person/delete). Prefer merge over delete for duplicates. * [People](/path/manage/people). The dashboard surface for the same operation. # talkvalue path person merge-undo Source: https://docs.trytalkvalue.com/cli/commands/path/person/merge-undo Reverse a person merge by mergeOperationId, restoring the source record. Requires --confirm. Reverse a prior [`person merge`](/cli/commands/path/person/merge). `talkvalue path person merge-undo` restores the retired source record, splits the merged emails, phones, channels, events, and activity history back to their original owners, and returns the target to its pre-merge state. Use this when a merge collapsed the wrong pair. ## Synopsis ```bash theme={null} talkvalue path person merge-undo <mergeOperationId> --confirm ``` ## Arguments | Argument | Type | Description | | -------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `<mergeOperationId>` | integer | The merge operation to reverse. Find it in the target's [`person get`](/cli/commands/path/person/get) response under `mergeOperations[].id`, or in the dashboard's activity log. | ## Options | Flag | Type | Description | | ----------- | ---- | ----------------------------------------------------------------- | | `--confirm` | flag | Required. The CLI exits with a usage error if you omit this flag. | ## Examples ### 1. Undo a recent merge ```bash theme={null} talkvalue path person merge-undo 503 --confirm ``` Reverses merge `503`. The output is `{ "undone": true, "mergeOperationId": 503 }`. Re-read the target with `person get` to confirm the source is no longer in `mergeOperations`. ### 2. Find the operation ID from the target ```bash theme={null} talkvalue path person get 142 --json \ | jq -r '.data.mergeOperations[0].id' \ | xargs -I {} talkvalue path person merge-undo {} --confirm ``` Pulls the most recent merge on person `142` and reverses it in one pipeline. Handy when you know which target person was affected but not the specific operation ID. ### 3. Guard against an already-undone operation ```bash theme={null} op_id=503 if talkvalue path person merge-undo "$op_id" --confirm 2>/dev/null; then echo "Reversed merge $op_id" else echo "Cannot undo $op_id (not found or already undone)" >&2 fi ``` The CLI exits non-zero on `404` (operation not found) or `409` (already undone). See [Exit codes](/cli/exit-codes) for the full mapping. ## Response ```jsonc theme={null} { "data": { "undone": true, "mergeOperationId": 503 } } ``` TalkValue replays the prior split. After the call, the source person ID resolves again via `person get`, and the target's `mergeOperations` list no longer contains the reversed entry. ## See also * [`person merge`](/cli/commands/path/person/merge). The forward operation this command reverses. * [`person get`](/cli/commands/path/person/get). Read `mergeOperations[].id` from the target's detail record. * [`person activity`](/cli/commands/path/person/activity). `UNMERGED` entries record the reversal. * [People](/path/manage/people). The dashboard surface for the same operation. # talkvalue path person update Source: https://docs.trytalkvalue.com/cli/commands/path/person/update Update names, emails, phones, job, social URLs, or company assignment for a person. Patch any combination of fields on a person record. Only the flags you pass are written. Omitted fields stay untouched. Pass `--remove-company` to detach the current company. Pass `--company-id` or `--company-name` to reassign. ## Synopsis ```bash theme={null} talkvalue path person update <id> [options] ``` ## Arguments | Argument | Type | Description | | -------- | ------- | -------------------- | | `<id>` | integer | Person ID to update. | ## Options | Flag | Type | Description | | ------------------------- | ------------------- | -------------------------------------------------------------------------------------------- | | `--first-name <name>` | string | Replace the first name. | | `--last-name <name>` | string | Replace the last name. | | `--primary-email <email>` | string | Set the primary email. TalkValue adds the address to the person's email list when it is new. | | `--email <email>` | string (repeatable) | Replace the email list. Repeat for each address. | | `--primary-phone <phone>` | string | Set the primary phone. | | `--phone <phone>` | string (repeatable) | Replace the phone list. Repeat for each number. | | `--job-title <title>` | string | Replace the job title. | | `--address <address>` | string | Replace the address. | | `--avatar-url <url>` | string | Replace the avatar URL. | | `--linkedin-url <url>` | string | Replace the LinkedIn URL. | | `--x-url <url>` | string | Replace the X (formerly Twitter) URL. | | `--company-name <name>` | string | Assign or rename the company by display name. | | `--company-id <id>` | integer | Assign the company by ID. | | `--remove-company` | flag | Detach the current company. Takes precedence over `--company-name` and `--company-id`. | ## Examples ### 1. Update a single field ```bash theme={null} talkvalue path person update 142 --job-title "Head of Growth" ``` Prints the updated record as a table. Only `jobTitle` changes server-side. ### 2. Replace the email list and set the primary ```bash theme={null} talkvalue path person update 142 \ --email "alice@acme.com" \ --email "alice.kim@personal.com" \ --primary-email "alice@acme.com" \ --json ``` Replaces the full email list and sets the primary in one call. ### 3. Detach a company in a script ```bash theme={null} talkvalue path person update 142 --remove-company --json \ | jq -e '.data.company == null' ``` `jq -e` exits non-zero if the assertion fails, so the script halts when the detach did not take effect. ## Response The full updated record comes back, matching the shape of [`person get`](/cli/commands/path/person/get): ```jsonc theme={null} { "data": { "id": 142, "name": "Alice Kim", "primaryEmail": { "email": "alice@acme.com", "type": "WORK", "domain": "acme.com" }, "emails": [ { "email": "alice@acme.com", "type": "WORK", "domain": "acme.com" } ], "primaryPhone": "+1-415-555-0199", "company": { "id": 88, "displayName": "Acme Inc.", "domain": "acme.com", "nameUpdatable": false }, "jobTitle": "Head of Growth", "channels": [/* … */], "events": [/* … */], "mergeOperations": [], "createdAt": "2026-04-12T00:00:00Z" } } ``` ## Troubleshooting * **The email already belongs to another person.** When an address you pass to `--primary-email` or `--email` sits on another record in the workspace, the command exits non-zero and names the conflicting person in the error payload. Consolidate the two records with [`person merge`](/cli/commands/path/person/merge) first. * **`--remove-company` takes precedence.** When you pass `--remove-company` together with `--company-id` or `--company-name`, TalkValue detaches the company and ignores the assignment. Pass one or the other per call. See [Exit codes](/cli/exit-codes) for the full mapping. ## See also * [`person list`](/cli/commands/path/person/list). Find the ID first. * [`person get`](/cli/commands/path/person/get). Inspect the record before and after. * [`person activity`](/cli/commands/path/person/activity). See who changed what and when. * [`person merge`](/cli/commands/path/person/merge). Combine duplicate records. * [People](/path/manage/people). The dashboard surface this command mirrors. # talkvalue path tag attach Source: https://docs.trytalkvalue.com/cli/commands/path/tag/attach Attach a tag to a channel or event by tag ID, or create a tag inline by name and attach it in one call. Attach a tag to a Path source. A source is either a channel ID or an event ID. The same command handles both, because the underlying tag relationship is shared. Pass `--tag-id` to attach an existing tag, or pass `--name` to attach an existing tag by name (and create one with that name if none exists). At least one of the two flags is required. When you pass both, TalkValue uses `--tag-id`. ## Synopsis ```bash theme={null} talkvalue path tag attach <sourceId> --tag-id <id> talkvalue path tag attach <sourceId> --name <name> ``` ## Arguments | Argument | Type | Description | | ------------ | ------- | --------------------------------------------------------------------------------------------------------------------- | | `<sourceId>` | integer | Channel ID or event ID to attach the tag to. TalkValue detects whether the ID is a channel or an event automatically. | ## Options | Flag | Type | Description | | --------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--tag-id <id>` | integer | Attach an existing tag by ID. Find IDs with [`tag list`](/cli/commands/path/tag/index) or capture them when you [`tag create`](/cli/commands/path/tag/create). | | `--name <name>` | string | Attach by name. If no tag with that name exists, TalkValue creates one and attaches it in the same request. | ## Examples ### 1. Attach an existing tag by ID ```bash theme={null} talkvalue path tag attach 7 --tag-id 42 ``` Adds tag `42` to channel (or event) `7`. The response prints the tag as confirmation the write succeeded. ### 2. Create-or-attach by name ```bash theme={null} talkvalue path tag attach 18 --name "Customer Day 2026" ``` Convenient when scripting against a list of source IDs and a small handful of tag names. You do not need to look up or create tags upfront. ### 3. Bulk-attach the same tag to many channels ```bash theme={null} tag_id=42 for channel_id in 7 12 18 21; do talkvalue path tag attach "$channel_id" --tag-id "$tag_id" done ``` Re-uses one ID across the loop. Attaching a tag is idempotent, so re-running the loop after a partial failure is safe. ## Response ```jsonc theme={null} { "data": { "id": 42, "name": "LinkedIn" } } ``` Returns the tag that was attached. The source's tag list (visible in `channel get` or `event get`) updates immediately and includes this tag on subsequent reads. ## See also * [`tag create`](/cli/commands/path/tag/create). Create a tag first when you want a known ID before the attach. * [Tags](/path/concepts/tags). How tags roll up to analytics and dashboard filters. * [`path channel get`](/cli/commands/path/channel/get) and [`path event get`](/cli/commands/path/event/get). Re-read the source to confirm the tag landed. # talkvalue path tag create Source: https://docs.trytalkvalue.com/cli/commands/path/tag/create Create a new Path tag by name and get back the tag ID for attaching to channels or events. Create a single tag. The command takes one required flag, `--name`, and returns the new tag's ID. Use the ID in subsequent [`tag attach`](/cli/commands/path/tag/attach) calls when you want to attach the same tag to many channels or events without rediscovering it by name. Tag names are unique per workspace, matched case-insensitively after trimming. Running `tag create` with a name that already exists returns that existing tag, so the command is safe to re-run in a script. ## Synopsis ```bash theme={null} talkvalue path tag create --name <name> ``` ## Options | Flag | Type | Description | | ------------------- | ----------------- | ----------------------------------------------------------------------- | | `-n, --name <name>` | string (required) | Display name for the tag. Shows up on the dashboard exactly as written. | ## Examples ### 1. Create a single tag ```bash theme={null} talkvalue path tag create --name "LinkedIn" ``` Prints the new tag as a single-record table: ID and name. ### 2. Capture the ID for the rest of the script ```bash theme={null} tag_id=$( talkvalue path tag create --name "Customer Day 2026" --json \ | jq -r '.data.id' ) echo "Created tag $tag_id" talkvalue path tag attach 18 --tag-id "$tag_id" talkvalue path tag attach 19 --tag-id "$tag_id" ``` Use this pattern when you need to attach the same tag to several known sources in one go. ### 3. Bulk-create from a list ```bash theme={null} while read -r name; do talkvalue path tag create --name "$name" --json | jq -r '.data | [.id, .name] | @tsv' done < tags.txt ``` Reads names line by line and prints each `id\tname` pair. Re-running the loop returns the same IDs. Pair it with `tee tag-ids.txt` to keep the mapping for later attach steps. ## Response ```jsonc theme={null} { "data": { "id": 42, "name": "LinkedIn" } } ``` The shape matches every other tag response in the API. Re-use the `id` when scripting many attaches. ## See also * [`tag attach`](/cli/commands/path/tag/attach). Attach the new tag to a channel or event. * [Tags](/path/concepts/tags). When and why to use tags in Path. * [`path channel list`](/cli/commands/path/channel/list). Find channel IDs to attach the tag to. # talkvalue path tag Source: https://docs.trytalkvalue.com/cli/commands/path/tag/index Manage Path tags from the CLI: create tags, attach them to channels and events, and group analytics by tag. `talkvalue path tag` is the CLI surface of Path tags. Tags group channels and events under a shared label so the dashboard can roll up analytics by that label. For example, every LinkedIn-origin channel under a `LinkedIn` tag, or every customer event under a `Customer Day` tag. The CLI exposes the two write operations you script most often, plus list, update, delete, and detach as supporting commands. ## Subcommands | Command | Description | | --------------------------------------------- | ---------------------------------------------------------------------------------------------- | | [`tag create`](/cli/commands/path/tag/create) | Create a new tag by name. | | [`tag attach`](/cli/commands/path/tag/attach) | Attach a tag to a channel or event. Creates the tag inline if you pass `--name` for a new one. | Additional read and cleanup commands are available from the same group: * `talkvalue path tag list [--name <filter>]`. List every tag, optionally filtered by substring. * `talkvalue path tag update <id> --name <new-name>`. Rename a tag. * `talkvalue path tag delete <id> --confirm`. Delete a tag everywhere it is attached. * `talkvalue path tag detach <sourceId> --tag-id <id>`. Remove a tag from a channel or event without deleting the tag itself. ## Typical workflow ```bash theme={null} # Create a tag and attach it to two channels talkvalue path tag create --name "LinkedIn" talkvalue path tag attach 7 --name "LinkedIn" talkvalue path tag attach 12 --name "LinkedIn" # Or attach an existing tag by ID talkvalue path tag list --name "LinkedIn" talkvalue path tag attach 18 --tag-id 42 ``` `attach --name` is the shortcut for "create if missing, attach either way". Once the tag exists you can keep referring to it by ID for the rest of the script. ## See also * [Tags](/path/concepts/tags). What tags do in Path and how they roll up to analytics. * [`path channel list`](/cli/commands/path/channel/list). Find channel IDs to attach tags to. * [`path event list`](/cli/commands/path/event/list). Find event IDs to attach tags to. * [`path analysis channel-attribution`](/cli/commands/path/analysis/channel-attribution). Analytics that respects tag-scoped filters. # talkvalue update Source: https://docs.trytalkvalue.com/cli/commands/update Check whether a newer TalkValue CLI version is available on npm and print the correct install command for your package manager. Look up the latest published `@talkvalue/cli` version on npm and compare it against the version you are running. If a newer version exists, the response carries a ready-to-copy install command tuned to the package manager that put the CLI on disk: npm, pnpm, yarn, or bun. The command performs no install; it prints the command to run. ## Synopsis ```bash theme={null} talkvalue update ``` ## Options This command takes no flags beyond the [global flags](/cli/global-flags). Output respects `--format` / `--json`. ## Examples ### 1. Quick check ```bash theme={null} talkvalue update ``` Prints a single record with the installed version, the latest published version, an `outdated` boolean, and (when out of date) the install command for your package manager. ### 2. Detect outdated in a script ```bash theme={null} out=$(talkvalue update --json | jq -r '.data.outdated') if [ "$out" = "true" ]; then cmd=$(talkvalue update --json | jq -r '.data.installCommand') echo "CLI is out of date. Run: $cmd" fi ``` Use this guard at the top of automation that depends on a recent CLI feature. Combine with `set -e` and an explicit `exit 1` if you want the script to halt instead of warn. ### 3. CI gate that fails when the CLI is stale ```bash theme={null} talkvalue update --json | jq -e '.data.outdated == false' \ || { echo "@talkvalue/cli is out of date in this image"; exit 1; } ``` `jq -e` returns non-zero when the assertion fails, so the CI step fails, signalling the pinned `@talkvalue/cli` version in your image or workflow needs bumping. ## Response ```jsonc theme={null} { "data": { "current": "1.5.0", "latest": "1.6.2", "outdated": true, "installCommand": "pnpm add -g @talkvalue/cli@latest" } } ``` `installCommand` is `null` when `outdated` is `false`. The picked package manager is inferred from `npm_config_user_agent`. When the CLI is run directly from the binary the fallback is `npm`. The remote lookup uses a 10-second timeout. Network failures surface as a hard error rather than a stale "up to date" answer. ## See also * [`talkvalue version`](/cli/commands/version). Print the version that is installed right now. * [Install](/cli/install). Clean install and upgrade instructions per package manager. # talkvalue version Source: https://docs.trytalkvalue.com/cli/commands/version Print the installed CLI version along with the Node runtime version and platform. Print the version of `@talkvalue/cli` that is currently on your `PATH`, plus the Node runtime and platform it is running under. The command is local and offline. It does not contact npm. Use [`talkvalue update`](/cli/commands/update) when you want to compare against the latest published version. ## Synopsis ```bash theme={null} talkvalue version ``` ## Options This command takes no flags beyond the [global flags](/cli/global-flags). Output respects `--format` / `--json`. ## Examples ### 1. Quick version check ```bash theme={null} talkvalue version ``` Prints the installed version, the Node version, and the platform string. ### 2. Capture the version for a bug report ```bash theme={null} talkvalue version --json \ | jq '{cli: .data.version, node: .data.nodeVersion, platform: .data.platform}' ``` Drop this into a support request, or paste it alongside an issue when reporting a CLI bug to [support@trytalkvalue.com](mailto:support@trytalkvalue.com). ### 3. Branch on the CLI version ```bash theme={null} cli_ver=$(talkvalue version --json | jq -r '.data.version') case "$cli_ver" in 1.6.*|1.7.*) echo "CLI supports the analysis subcommands" ;; *) echo "CLI is older. Consider running 'talkvalue update'" ;; esac ``` Useful in shared scripts that have to run on developer laptops with mixed CLI versions. ## Response ```jsonc theme={null} { "data": { "version": "1.6.2", "nodeVersion": "v24.4.0", "platform": "darwin" } } ``` `platform` follows Node's `process.platform`: `darwin`, `linux`, `win32`. `nodeVersion` is the Node runtime that launched the CLI, not the version embedded in the published binary. ## See also * [`talkvalue update`](/cli/commands/update). Compare against the latest version on npm. * [Install](/cli/install). Install or reinstall the CLI per package manager. * [Troubleshooting](/cli/troubleshooting). What to do when the version output looks wrong. # Environment variables Source: https://docs.trytalkvalue.com/cli/environment-variables TALKVALUE_TOKEN, TALKVALUE_PROFILE, TALKVALUE_API_URL, and the rest of the CLI environment surface. The CLI reads its configuration from environment variables at startup. They're the right place to set credentials and overrides in CI, Docker, or shell scripts that drive multiple commands. ## Reference | Variable | Description | | ------------------------ | ----------------------------------------------------------------------------------------------------------------------- | | `TALKVALUE_TOKEN` | API token used for every request. When set, it takes precedence over any saved profile and skips `auth login` entirely. | | `TALKVALUE_PROFILE` | Name of the saved profile to use as the default. Overridden by `--profile`. | | `TALKVALUE_API_URL` | Override the TalkValue data API base URL. Used for staging environments. | | `TALKVALUE_AUTH_API_URL` | Override the auth server base URL used by `auth login` / token refresh. | | `NO_COLOR` | When set to any value, disables ANSI color in table output. Same as `--no-color`. | | `FORCE_COLOR` | When set to any value, forces ANSI color even when stdout is not a TTY (for example, CI logs). | ## Order of precedence For overlapping settings, CLI flags win over environment variables, which win over saved profiles or defaults: | Setting | Flag | Env var | Default | | ------------- | --------------------- | -------------------------- | ----------------------- | | Auth profile | `--profile <name>` | `TALKVALUE_PROFILE` | Active profile | | API base URL | `--api-url <url>` | `TALKVALUE_API_URL` | Built-in production URL | | Color | `--no-color` | `NO_COLOR` / `FORCE_COLOR` | Auto-detect TTY | | Output format | `--format` / `--json` | — | Auto-detect TTY | API tokens are the exception. `TALKVALUE_TOKEN` in the environment always overrides any saved profile and has no flag equivalent. See [Authentication](/cli/authentication). ## Common setups ### CI environment ```bash theme={null} export TALKVALUE_TOKEN=<your-token> talkvalue path person list --json ``` The token replaces interactive login. Store it in your CI provider's secret store. ### Docker ```dockerfile theme={null} ENV TALKVALUE_TOKEN=<your-token> RUN talkvalue path overview --json > /tmp/overview.json ``` Inject the token at build or run time depending on your secrets workflow. ### Multiple profiles in one shell ```bash theme={null} export TALKVALUE_PROFILE=staging talkvalue path person list # staging org talkvalue path person list --profile prod # prod org for this command only ``` ### Staging API ```bash theme={null} export TALKVALUE_API_URL=https://staging.example.trytalkvalue.com export TALKVALUE_AUTH_API_URL=https://staging-auth.example.trytalkvalue.com talkvalue auth login ``` ## Related * [Authentication](/cli/authentication). `TALKVALUE_TOKEN` vs profiles, precedence rules. * [Global flags](/cli/global-flags). Flag equivalents for the env vars above. * [Output format](/cli/output-format). How color and format auto-detection work. # Exit codes Source: https://docs.trytalkvalue.com/cli/exit-codes Stable exit codes for every TalkValue CLI command. Branch on success, auth failure, not found, and more. The TalkValue CLI returns a predictable exit code on every run so shell scripts and CI pipelines can branch on outcome without parsing output. Pair the code with the JSON error envelope on stderr to surface a useful message. ## Reference | Code | Meaning | When you see it | | ---- | -------------------- | -------------------------------------------------------------------------------- | | `0` | Success | The command completed and printed its result. | | `1` | General error | Unexpected failure. Network error or transient API issue. | | `2` | Usage error | Bad arguments, unknown option, missing required value. | | `3` | Authentication error | No credentials, invalid or expired token, organization access revoked. | | `4` | Not found | The targeted resource (person, event, channel, company, tag) doesn't exist. | | `5` | Forbidden | Authenticated, but the active organization isn't allowed to act on the resource. | ## Read the exit code ```bash theme={null} talkvalue path person get 999999 echo $? # 4 = not found ``` ## Branch in a shell script ```bash theme={null} #!/usr/bin/env bash set -e if ! result=$(talkvalue path person get "$1" --json 2>&1); then case $? in 3) echo "Authentication failed. Run 'talkvalue auth login'." >&2 ;; 4) echo "Person $1 not found." >&2 ;; 5) echo "Not allowed to read person $1 in this organization." >&2 ;; *) echo "Lookup failed: $result" >&2 ;; esac exit 1 fi echo "$result" | jq '.data.email' ``` `set -e` halts on the first non-zero exit. The `case` block maps each domain code to a human-readable message and re-exits with `1` so the calling script can detect the failure. ## Combine with the JSON error envelope When `--json` is set (or output is piped), errors land on **stderr** as: ```json theme={null} { "error": { "message": "Person 999999 not found" } } ``` Capture it separately from stdout to get both the message and the code: ```bash theme={null} err=$(talkvalue path person get 999999 --json 2>&1 1>/dev/null) code=$? echo "exit=$code" echo "$err" | jq -r '.error.message' ``` ## CI pipelines Most CI runners (GitHub Actions, GitLab CI, CircleCI) fail a step on any non-zero exit code, so the CLI integrates without extra plumbing: ```yaml theme={null} - name: Export attendees nightly env: TALKVALUE_TOKEN: ${{ secrets.TALKVALUE_TOKEN }} run: | talkvalue path event person export 16 > attendees.csv ``` If `auth login` was skipped because `TALKVALUE_TOKEN` is missing, the command exits `3` and the CI step fails with the auth error printed to stderr. ## Related * [Output format](/cli/output-format). Error envelope shape on stderr. * [Authentication](/cli/authentication). What causes a `3` and how to fix it. * [Troubleshooting](/cli/troubleshooting). Common failure modes by exit code. # Global flags Source: https://docs.trytalkvalue.com/cli/global-flags Flags available on every TalkValue CLI command: format, profile, API URL, color, help, version. These flags work on every command and subcommand. They override defaults set by environment variables and saved profiles. ## Reference | Flag | Description | | ----------------------------- | ------------------------------------------------------------------------------------------- | | `--format <json\|table\|csv>` | Output format. Defaults to `table` for a TTY and `json` when output is piped or redirected. | | `--json` | Shorthand for `--format json`. | | `--profile <name>` | Use a specific saved auth profile instead of the active one. | | `--api-url <url>` | Override the TalkValue API base URL. Useful for staging environments. | | `--no-color` | Disable ANSI color in table output. Equivalent to `NO_COLOR=1`. | | `-h`, `--help` | Show help for the command or subcommand. | | `-V`, `--version` | Show the installed CLI version. | ## Order of precedence For settings that overlap with environment variables or profiles, the CLI resolves them in this order. Flag wins over env wins over profile: | Setting | Flag | Env var | Profile / default | | ------------- | --------------------- | -------------------------- | ----------------------- | | Output format | `--format` / `--json` | — | Auto-detect TTY | | Auth profile | `--profile <name>` | `TALKVALUE_PROFILE` | Active profile | | API base URL | `--api-url <url>` | `TALKVALUE_API_URL` | Built-in production URL | | Color | `--no-color` | `NO_COLOR` / `FORCE_COLOR` | Auto-detect TTY | API tokens are an exception: `TALKVALUE_TOKEN` in the environment always overrides any saved profile, with no flag equivalent. See [Authentication](/cli/authentication). ## Help on any command `--help` is available at every level of the command tree: ```bash theme={null} talkvalue --help talkvalue path --help talkvalue path person list --help ``` Each `--help` page lists the subcommands or options for that scope, plus the global flags above. ## Related * [Output format](/cli/output-format). How `--format` and `--json` behave. * [Environment variables](/cli/environment-variables). The env-var counterparts. * [Authentication](/cli/authentication). `--profile` and credential precedence. * [Exit codes](/cli/exit-codes). Pair with `--json` and stderr for scripting. # TalkValue CLI Source: https://docs.trytalkvalue.com/cli/index Manage contacts, events, channels, and analytics from the command line. Built for humans and AI agents. The TalkValue CLI exposes the same data you see in the dashboard through a scriptable command-line interface. Structured JSON output, multi-profile authentication, and 11 bundled skills make it equally useful for terminal workflows and AI coding agents. ```bash theme={null} npm install -g @talkvalue/cli ``` <Note> **For AI agents:** fetch the docs index at [llms.txt](https://docs.trytalkvalue.com/llms.txt) to discover every command page before exploring further. </Note> <CardGroup> <Card title="Install" icon="download" href="/cli/install"> Install via npm and verify your setup. </Card> <Card title="Quickstart" icon="rocket" href="/cli/quickstart"> Run your first command. </Card> <Card title="Authentication" icon="key" href="/cli/authentication"> Interactive OAuth and CI tokens with multi-profile support. </Card> </CardGroup> ## What you can do * List, get, update, merge, and export people across your workspace * Create and manage events, channels, companies, and tags * Run channel attribution, audience overlap, and event trend analyses * Import CSVs end-to-end: analyze → create → monitor → handle failures * Compose commands with `jq` and shell pipes to build custom reports ## AI agent skills The CLI ships 11 skills (7 namespaced command-group wrappers, 1 shared reference, and 3 workflow recipes) that any AI coding agent can install with one command: ```bash theme={null} npx skills add https://github.com/talkvalue/cli ``` See the full skill index at [AI agent skills](/cli/agents/skills). # Install Source: https://docs.trytalkvalue.com/cli/install Install the TalkValue CLI via npm and verify the global binary on macOS, Linux, or Windows. The TalkValue CLI ships as a single npm package, `@talkvalue/cli`. Install it globally with the package manager of your choice and the `talkvalue` binary becomes available in any terminal. <Note> **Prerequisites** * **Node.js 24 or newer**. Check with `node --version`. * A TalkValue account with at least one organization * npm, pnpm, yarn, or bun on your `$PATH` </Note> ## Install <Steps> <Step title="Install the CLI globally"> Pick the command for your package manager: ```bash theme={null} # npm npm install -g @talkvalue/cli # pnpm pnpm add -g @talkvalue/cli # yarn yarn global add @talkvalue/cli # bun bun add -g @talkvalue/cli ``` </Step> <Step title="Verify the install"> Open a new terminal so your shell picks up the global bin, then run: ```bash theme={null} talkvalue version ``` The installed version prints back. If the command is not found, your package manager's global `bin` directory is not on `$PATH`. Add it and reopen the terminal. </Step> <Step title="Confirm Node.js version"> The CLI requires Node.js 24 or newer. Check yours: ```bash theme={null} node --version ``` If you need to upgrade, use [`nvm`](https://github.com/nvm-sh/nvm), [`fnm`](https://github.com/Schniz/fnm), or your OS package manager. </Step> </Steps> ## Update The CLI checks npm for new releases in the background and prints a banner when one is available. To check on demand: ```bash theme={null} talkvalue update ``` `talkvalue update` reports your current version, the latest published version, and the exact install command for your detected package manager (npm, pnpm, yarn, or bun). Re-run that command to upgrade in place. ## Platform notes * **macOS**: the recommended path is Homebrew-managed Node plus `npm install -g`. The CLI uses your system keychain to store auth tokens. * **Linux**: install Node via your distro or `nvm`, then `npm install -g`. The CLI uses `libsecret` for keyring access on most distros. * **Windows**: use PowerShell or Windows Terminal. The CLI uses the Windows Credential Manager for token storage. * **WSL**: install inside the Linux side. The CLI behaves identically to native Linux. ## CI and Docker Skip `talkvalue auth login` in non-interactive environments and pass an API token instead: ```bash theme={null} export TALKVALUE_TOKEN=<your-token> talkvalue path person list --json ``` See [Authentication](/cli/authentication) for how to generate the token and [Environment variables](/cli/environment-variables) for the full env reference. ## Uninstall ```bash theme={null} # npm npm uninstall -g @talkvalue/cli # pnpm pnpm remove -g @talkvalue/cli ``` Remove your saved profile too: ```bash theme={null} talkvalue auth logout ``` ## Related * [Quickstart](/cli/quickstart). Run your first command in 60 seconds. * [Authentication](/cli/authentication). Sign in interactively or with a token. * [Environment variables](/cli/environment-variables). Full env reference. # Output format Source: https://docs.trytalkvalue.com/cli/output-format JSON for pipes, table for humans, CSV for spreadsheets. Auto-detected based on TTY with explicit overrides. Every TalkValue CLI command emits its result in one of three formats: `json`, `table`, or `csv`. The CLI picks the right one automatically based on where the output is going, and you can override it on any command. ## Auto-detection | Where output goes | Default format | | ------------------ | -------------- | | A terminal (TTY) | `table` | | A pipe or redirect | `json` | The CLI inspects `stdout` at startup. Running interactively gets a human-friendly table. Piping to another tool or redirecting to a file gets parseable JSON. That means `talkvalue path person list | jq` works with no flag required. ## Override the format Pick a format explicitly with `--format`: ```bash theme={null} talkvalue path person list --format json talkvalue path person list --format table talkvalue path person list --format csv ``` Or use the `--json` shorthand: ```bash theme={null} talkvalue path person list --json ``` The `--json` flag is equivalent to `--format json` and exists because it's the most common override. ## JSON envelope Every JSON response wraps the result in a stable envelope so scripts can rely on the shape. Single-resource response: ```jsonc theme={null} { "data": { "id": 42, "name": "Ada Lovelace", "primaryEmail": "ada@analytical-engine.org", "company": { "id": 7, "displayName": "Analytical Engine Co." }, "jobTitle": "Founder" } } ``` List response (paginated): ```json theme={null} { "data": [ { "id": 1, "name": "Ada Lovelace", "primaryEmail": "ada@analytical-engine.org" }, { "id": 2, "name": "Charles Babbage", "primaryEmail": "charles@analytical-engine.org" } ], "pagination": { "page": 1, "pageSize": 20, "totalPages": 5, "totalElements": 100 } } ``` Paginated list commands (`person list`, `event person list`, `channel people`, `company list`, `company person list`, `import list`) return the `pagination` block, so you can compute the next page or the total count without a second request. ## Error envelope Errors go to **stderr**, not stdout, and use a separate envelope: ```json theme={null} { "error": { "message": "Person 999999 not found" } } ``` Because errors go to stderr, this works as expected: ```bash theme={null} talkvalue path person get 999999 2>/dev/null | jq ``` Pair the JSON message with the [exit code](/cli/exit-codes) to branch in a shell script. ## CSV `--format csv` works on any list command and writes RFC-4180 compliant CSV with the first row as headers. Use it for spreadsheets or ad-hoc reports: ```bash theme={null} talkvalue path person list --format csv > people.csv ``` Export-style commands (`person export`, `event person export`, `channel export`, `import failed-export`) always emit CSV regardless of `--format`. They exist specifically for spreadsheet workflows. ## TTY tips * **Color.** Table output uses color when stdout is a TTY. Turn it off with `--no-color` or `NO_COLOR=1`, or force it with `FORCE_COLOR=1` in places like CI logs that strip TTY detection but render ANSI. * **Update banner.** The CLI prints an upgrade banner when a newer version is on npm. It's automatically suppressed when output is JSON or piped, so it never contaminates parsed output. ## Related * [Exit codes](/cli/exit-codes). Branch on success vs auth error vs not-found in scripts. * [Global flags](/cli/global-flags). `--format`, `--json`, `--no-color`, and the rest. * [Scripting with jq](/cli/recipes/scripting-with-jq). Common `jq` patterns for CLI output. * [Environment variables](/cli/environment-variables). `NO_COLOR`, `FORCE_COLOR`. # Quickstart Source: https://docs.trytalkvalue.com/cli/quickstart Install the TalkValue CLI, sign in via OAuth, and run your first command in 60 seconds. This walks through installing the CLI, signing in through the browser, and piping your first command through `jq` to confirm the JSON envelope. <Note> **Prerequisites** * Node.js 24 or newer (`node --version`) * A TalkValue account with at least one organization * `jq` for the JSON example, or skip the pipe to see the table view </Note> ## Run your first command <Steps> <Step title="Install the CLI"> ```bash theme={null} npm install -g @talkvalue/cli ``` Verify with `talkvalue version`. Full options: [Install](/cli/install). </Step> <Step title="Sign in"> ```bash theme={null} talkvalue auth login ``` The CLI prints a one-time code, opens your default browser to the verification page, and waits for you to confirm. After you approve, it polls until it gets a token, then asks which organization to use. Pass `--org <name-or-id>` to skip the picker. On success you'll see `✓ Logged in as you@example.com (Acme Inc.)`. </Step> <Step title="List people in your workspace"> Run a `path person list` to confirm everything is wired up. Pipe through `jq` to inspect the JSON envelope: ```bash theme={null} talkvalue path person list --json | jq '.data[0]' ``` The first person record appears: `id`, `name`, `primaryEmail`, `primaryPhone`, `company`, `jobTitle`, `channels`, `events`, `joinedAt`. The pagination block follows the array. </Step> </Steps> ## What just happened * `auth login` ran the browser sign-in, exchanged the code for an access token, prompted for organization selection, and saved a profile in your system keyring. * `path person list --json` called the dashboard's people endpoint as the organization you selected. * The `--json` flag forced JSON output. Without a pipe, the CLI defaults to a table. With a pipe (or `--json`), it switches to JSON automatically. See [Output format](/cli/output-format). ## A few more commands to try ```bash theme={null} # List the next 50 people, sorted by most recent join date talkvalue path person list --page-size 50 --sort "joinedAt,desc" # Show your dashboard overview talkvalue path overview --json | jq '.data | {peopleCount, eventCount, channelCount, newPeopleThisMonth}' # Export attendees for event 16 to a CSV talkvalue path event person export 16 > attendees.csv # Analyze a CSV before importing talkvalue path import analyze --file contacts.csv --json ``` Run `talkvalue --help` for the full command tree, or `talkvalue path person list --help` for any subcommand. ## For AI agents The CLI is built for both humans and AI coding agents. Every response is structured JSON, and the repo ships ready-to-install skills that wrap each command group. Add them to any agent in one command: ```bash theme={null} npx skills add https://github.com/talkvalue/cli ``` See [AI agents](/cli/agents) for the full list. ## Related * [Install](/cli/install). Per-OS install notes and CI setup. * [Authentication](/cli/authentication). Interactive vs CI tokens and multi-profile. * [Output format](/cli/output-format). JSON envelope, auto-detection, CSV exports. * [Scripting with jq](/cli/recipes/scripting-with-jq). Recipes for piping CLI output into shell pipelines. # Recipe: Channel analysis Source: https://docs.trytalkvalue.com/cli/recipes/channel-analysis Combine channel-event attribution with audience overlap for a full channel ROI report. All from the CLI. Run a complete channel ROI report by composing the two read-only channel analyses: per-event attribution (who joined the channel because of which event) and audience overlap (how much each pair of channels shares). The recipe wires [`analysis channel attribution`](/cli/commands/path/analysis/channel-attribution) and [`analysis channel audience`](/cli/commands/path/analysis/audience-overlap) together with `jq` for downstream charting. <Note> **Prerequisites:** authenticated CLI and at least two channels with event registrations. Audience overlap requires between 2 and 5 channel IDs. </Note> ## Steps <Steps> <Step title="Discover the channels you want to analyze"> ```bash theme={null} talkvalue path channel list --json \ | jq '.data[] | {id, name, peopleCount}' ``` Returns every channel with its current member count. Pick two to five IDs for the rest of the script. </Step> <Step title="Discover the events for attribution scope"> ```bash theme={null} talkvalue path event list --json \ | jq '.data[] | {id, name, startAt}' ``` Use this when you want to pin attribution to a specific event subset rather than every event the channel touched. </Step> <Step title="Per-channel attribution across selected events"> ```bash theme={null} CHANNEL_ID=7 talkvalue path analysis channel attribution "$CHANNEL_ID" \ --event-id 18 --event-id 22 \ --json \ | jq '{ channel: .data.channel.name, channelSize: .data.metrics.channelSize, eventParticipationRate: .data.metrics.eventParticipationRate, events: (.data.events | map({name, total, joinedSinceLastEvent, acquisitionRate})) }' ``` Returns the channel's headline metrics (`channelSize`, `membersEverRegistered`, `eventParticipationRate`) plus a per-event breakdown showing how many new members the channel acquired from each event (`joinedSinceLastEvent`, with `acquisitionRate`) versus people already on the channel (`alreadyInChannel`). Omit `--event-id` entirely to roll up every event the channel ever appeared on. </Step> <Step title="Audience overlap across the channel group"> ```bash theme={null} talkvalue path analysis channel audience \ --channel-id 7 --channel-id 12 --channel-id 19 \ --json \ | jq '{ channels: (.data.channels | map({name, personCount})), intersections: .data.intersections, multiChannelRate: .data.metrics.multiChannelRate }' ``` Returns each channel's size, every n-way intersection (pairs, triples, and so on), and the aggregate `multiChannelRate`: the fraction of unique people who sit in more than one channel. </Step> <Step title="Combine into a single report"> ```bash theme={null} CHANNEL_IDS=(7 12 19) OUT="reports/channel-analysis-$(date +%Y-%m-%d).json" mkdir -p reports OVERLAP=$( talkvalue path analysis channel audience \ $(printf -- '--channel-id %s ' "${CHANNEL_IDS[@]}") \ --json ) ATTRIBUTION="[" for id in "${CHANNEL_IDS[@]}"; do row=$(talkvalue path analysis channel attribution "$id" --json | jq '.data') ATTRIBUTION+="$row," done ATTRIBUTION="${ATTRIBUTION%,}]" jq -n --argjson overlap "$OVERLAP" --argjson attribution "$ATTRIBUTION" \ '{generatedAt: now | todate, overlap: $overlap.data, attribution: $attribution}' \ > "$OUT" echo "Wrote $OUT" ``` Iterates the channel list, captures each channel's full attribution snapshot, runs one overlap call, and writes a single timestamped JSON file. Drop the loop body into a cron job for a daily archive. </Step> </Steps> ## Variants ### Scope every event analysis to a single tag ```bash theme={null} talkvalue path analysis channel attribution 7 --tag-id 4 --json \ | jq '.data.events | map({name, total, joinedSinceLastEvent, acquisitionRate})' ``` `--tag-id` limits the attribution to events that carry the given tag. Useful for "webinars only" or "Q2 campaign only" reports. See [Tags](/path/concepts/tags) and [`tag attach`](/cli/commands/path/tag/attach) for tagging events. ### Spot the largest audience overlap in a trio ```bash theme={null} talkvalue path analysis channel audience \ --channel-id 7 --channel-id 12 --channel-id 19 --json \ | jq '.data.intersections | sort_by(-.count) | .[0]' ``` Returns the single most overlapped n-way slice across the trio. The full intersection list includes every 2-way pair plus the 3-way intersection. ### Track multi-channel rate over time ```bash theme={null} talkvalue path analysis channel audience \ --channel-id 7 --channel-id 12 --channel-id 19 --channel-id 25 --json \ | jq -r '[.data.metrics.multiChannelRate, (now | strftime("%Y-%m-%d"))] | @csv' \ >> reports/multi-channel-rate.csv ``` Appends a daily row to a long-form CSV. Useful for monitoring how concentrated your audience is becoming over time. ## Tips * `acquisitionRate` on an event is `joinedSinceLastEvent / total`: the share of the event's audience that the channel acquired specifically because of that event. * `eventParticipationRate` on a channel is `membersEverRegistered / channelSize`: the share of channel members who registered for at least one event. * Audience overlap requires `2 ≤ channelCount ≤ 5`. Outside that range, the command exits with a usage error (exit `2`). * For the dashboard view of the same data, see [Channel attribution](/path/analytics/attribution) and [Audience overlap](/path/analytics/audience). ## See also * [`analysis channel attribution`](/cli/commands/path/analysis/channel-attribution). Full response schema. * [`analysis channel audience`](/cli/commands/path/analysis/audience-overlap). Intersection and metric shape. * [`channel list`](/cli/commands/path/channel/list). Discover channel IDs. * [`event list`](/cli/commands/path/event/list). Discover event IDs to feed `--event-id`. * [AI agent skill: recipe-channel-analysis](/cli/agents/skills). Install as a skill. # Recipe: CSV import end-to-end Source: https://docs.trytalkvalue.com/cli/recipes/csv-import Analyze a CSV, create the import job, poll until terminal, and export any rejected rows. All from the CLI. Run the full CSV bulk-import workflow from the command line: upload and analyze the file, create the job with a column mapping, poll until the job reaches a terminal state, and pull the rejected rows if any landed. The recipe composes every leaf in [`path import`](/cli/commands/path/import/index). <Note> **Prerequisites:** authenticated CLI, a CSV file with a header row, and a channel ID to import the contacts into. Find a channel ID with [`path channel list`](/cli/commands/path/channel/list). </Note> ## Steps <Steps> <Step title="Analyze the CSV"> ```bash theme={null} talkvalue path import analyze --file ./contacts.csv --json ``` Uploads the file, returns a `fileKey`, the headers, a preview, and the server's suggested column mapping. Note the `fileKey` and the column indices. You need both for the next step. </Step> <Step title="Capture the fileKey"> ```bash theme={null} FILE_KEY=$(talkvalue path import analyze --file ./contacts.csv --json | jq -r '.data.fileKey') echo "$FILE_KEY" ``` Saves the key in a shell variable so the rest of the script can reference it without re-uploading. </Step> <Step title="Create the import job"> ```bash theme={null} SOURCE_CHANNEL_ID=7 JOB_ID=$( talkvalue path import create \ --file-key "$FILE_KEY" \ --source-id "$SOURCE_CHANNEL_ID" \ --mode UPDATE \ --mapping 0:EMAIL \ --mapping 1:FIRST_NAME \ --mapping 2:LAST_NAME \ --json \ | jq -r '.data.importJobId' ) echo "Job: $JOB_ID" ``` Returns immediately with the `importJobId`. The job runs in the background. Your terminal is free for the polling loop below. `--mode UPDATE` overwrites fields on existing contacts matched by email. Switch to `--mode SKIP` if you want to leave existing records untouched and treat collisions as duplicates. </Step> <Step title="Poll until the job reaches a terminal state"> ```bash theme={null} while :; do STATUS=$(talkvalue path import get "$JOB_ID" --json | jq -r '.data.status') echo " status: $STATUS" case "$STATUS" in COMPLETED|PARTIAL_SUCCESS|FAILED) break ;; esac sleep 5 done ``` The job moves through `PENDING` → `RUNNING` → one of `COMPLETED`, `PARTIAL_SUCCESS`, or `FAILED`. The loop exits on any terminal state. Tighten or relax `sleep` based on import size. </Step> <Step title="Export rejected rows when there are failures"> ```bash theme={null} FAILED=$(talkvalue path import get "$JOB_ID" --json | jq -r '.data.failedCount') if [ "$FAILED" -gt 0 ]; then talkvalue path import failed-export "$JOB_ID" > "failed-$JOB_ID.csv" echo "$FAILED rejected row(s) written to failed-$JOB_ID.csv" else echo "No failures." fi ``` Pulls the full rejected-row CSV only when the job had failures. The export carries the header row and the rejected rows from the file you uploaded, so the columns match your original CSV. Fix the rows, re-run the import on the corrected file, and the failure count drops. </Step> </Steps> ## Variants ### Treat duplicates as silent skips ```bash theme={null} talkvalue path import create \ --file-key "$FILE_KEY" \ --source-id "$SOURCE_CHANNEL_ID" \ --mode SKIP \ --mapping 0:EMAIL --mapping 1:NAME --mapping 2:COMPANY_NAME \ --json ``` `SKIP` is the right mode for a weekly registrant export when you want every new email but you don't want to overwrite manual edits made in the dashboard. ### Group failures by error code before fixing ```bash theme={null} talkvalue path import get "$JOB_ID" --json \ | jq -r '.data.failedRows[].errorCode' \ | sort | uniq -c | sort -rn ``` Counts failures by `errorCode` so you can prioritize the fix that unlocks the most rows. ### One-shot script ```bash theme={null} #!/usr/bin/env bash set -euo pipefail FILE="$1" SOURCE_CHANNEL_ID="$2" FILE_KEY=$(talkvalue path import analyze --file "$FILE" --json | jq -r '.data.fileKey') JOB_ID=$( talkvalue path import create \ --file-key "$FILE_KEY" \ --source-id "$SOURCE_CHANNEL_ID" \ --mode UPDATE \ --mapping 0:EMAIL --mapping 1:FIRST_NAME --mapping 2:LAST_NAME \ --json | jq -r '.data.importJobId' ) while :; do STATUS=$(talkvalue path import get "$JOB_ID" --json | jq -r '.data.status') case "$STATUS" in COMPLETED|PARTIAL_SUCCESS|FAILED) break ;; esac sleep 5 done FAILED=$(talkvalue path import get "$JOB_ID" --json | jq -r '.data.failedCount') [ "$FAILED" -gt 0 ] && talkvalue path import failed-export "$JOB_ID" > "failed-$JOB_ID.csv" echo "Final status: $STATUS, $FAILED failure(s)" ``` Drop into `import-csv.sh`, then run `./import-csv.sh ./contacts.csv 7`. ## Tips * Valid mapping target fields: `EMAIL`, `FIRST_NAME`, `LAST_NAME`, `NAME`, `PHONE`, `JOB_TITLE`, `COMPANY_NAME`, `ADDRESS`, `LINKEDIN_URL`, `X_URL`, `JOINED_AT`. The full reference lives at [Column mapping](/path/import/column-mapping). * Re-importing `failed-$JOB_ID.csv` after corrections clears the failure count. It does not double-import the successful rows from the first run. * Each `import create` queues a separate job. If you re-run with the same `fileKey` you get a second job ID, not an overwrite of the first. * Need to inspect a job later? Every import is listed by [`import list`](/cli/commands/path/import/index) and individual jobs by [`import get <id>`](/cli/commands/path/import/status). ## See also * [`import analyze`](/cli/commands/path/import/analyze). File upload, headers, preview. * [`import create`](/cli/commands/path/import/create). Mapping and mode reference. * [`import get`](/cli/commands/path/import/status). Full job-record schema. * [`import failed-export`](/cli/commands/path/import/export-failures). Rejected-row CSV format. * [Troubleshooting](/cli/troubleshooting). Mapping errors, file errors, and rate limits. * [AI agent skill: recipe-csv-import](/cli/agents/skills). Install as a skill. # Recipes Source: https://docs.trytalkvalue.com/cli/recipes/index Multi-step CLI workflows that compose Path leaf commands with jq, shell pipes, and standard Unix tools. Recipes are end-to-end scripts that solve a single, scoped job: pull this month's registrants, run a CSV import from analyze to recovery, compare a set of channels, or shape any list with `jq`. Each one composes the leaf commands already documented under [Commands](/cli/commands/path/overview) with standard shell tools, so nothing is hidden behind a wrapper. ## When to use a recipe * You want a finished workflow, not a per-command reference. * You need to run the same multi-step report on a schedule and want a starting script. * You're an AI agent and you want a documented composition pattern to follow. <CardGroup> <Card title="New registrants this week" icon="user-plus" href="/cli/recipes/new-registrants"> Pull the latest event sign-ups, filter by date, and export them for follow-up. </Card> <Card title="CSV import end-to-end" icon="file-csv" href="/cli/recipes/csv-import"> Analyze, create, poll, and recover failed rows in one script. </Card> <Card title="Channel analysis" icon="chart-mixed" href="/cli/recipes/channel-analysis"> Combine channel-event attribution with audience overlap for a full ROI view. </Card> <Card title="Scripting with jq" icon="terminal" href="/cli/recipes/scripting-with-jq"> Reusable `jq` snippets for filtering, projecting, and aggregating CLI JSON output. </Card> </CardGroup> ## See also * [Commands](/cli/commands/path/overview). Every leaf command the recipes compose. * [Output format](/cli/output-format). The JSON envelope `jq` walks. * [AI agent skills](/cli/agents/skills). The same recipes packaged as installable skills. # Recipe: New registrants this week Source: https://docs.trytalkvalue.com/cli/recipes/new-registrants Pull the latest event sign-ups, filter by date, and export them as CSV for follow-up. Pull the people who registered for a specific event recently, optionally filter to this month or this week, then save them as CSV for outreach. The recipe composes [`event list`](/cli/commands/path/event/list), [`event person list`](/cli/commands/path/event/person-list), and [`event person export`](/cli/commands/path/event/person-export) with `jq`. <Note> **Prerequisites:** authenticated CLI (run [`auth login`](/cli/commands/auth/login) once) and at least one event with attendees in the active workspace. </Note> ## Steps <Steps> <Step title="Find the event ID"> ```bash theme={null} talkvalue path event list --json | jq '.data[] | {id, name, startAt}' ``` Lists every event in the workspace with the three fields you need to pick the one you want. </Step> <Step title="Browse the latest registrants"> ```bash theme={null} EVENT_ID=18 talkvalue path event person list "$EVENT_ID" --sort "joinedAt,desc" --page-size 50 ``` Prints the 50 most recent registrants as a table, newest first. The `--sort` flag is what makes this a "new registrants" report. </Step> <Step title="Filter to this month"> ```bash theme={null} EVENT_ID=18 SINCE=$(date -u +"%Y-%m-01T00:00:00Z") talkvalue path event person list "$EVENT_ID" \ --sort "joinedAt,desc" --page-size 100 --json \ | jq --arg since "$SINCE" \ '[.data[] | select(.joinedAt >= $since)] | {count: length, registrants: .}' ``` Captures the month boundary at midnight UTC, asks for the first 100 registrants newest first, then keeps only the ones who joined on or after the first of the month. The output is a small object with a `count` plus the filtered list. </Step> <Step title="Export to CSV for follow-up"> ```bash theme={null} talkvalue path event person export "$EVENT_ID" > "registrants-event-$EVENT_ID.csv" ``` Streams every registrant (not just this month's) as a CSV file. `export` is always CSV regardless of the global `--format` flag. </Step> </Steps> ## Variants ### Filter to a custom date range ```bash theme={null} SINCE="2026-05-01T00:00:00Z" UNTIL="2026-05-22T00:00:00Z" talkvalue path event person list "$EVENT_ID" \ --sort "joinedAt,desc" --page-size 100 --json \ | jq --arg since "$SINCE" --arg until "$UNTIL" \ '[.data[] | select(.joinedAt >= $since and .joinedAt < $until)]' ``` Two ISO timestamps bracket the window. Use any half-open `[since, until)` range for weekly, daily, or arbitrary slices. ### Filter by channel ```bash theme={null} talkvalue path event person list "$EVENT_ID" \ --channel-id 7 \ --sort "joinedAt,desc" --page-size 50 ``` Use `--channel-id` (repeatable) when you want only registrants who are also on a specific marketing channel, for example, newsletter subscribers who signed up for the event. ### Export only this month's registrants as CSV ```bash theme={null} SINCE=$(date -u +"%Y-%m-01T00:00:00Z") talkvalue path event person list "$EVENT_ID" \ --sort "joinedAt,desc" --page-size 500 --json \ | jq -r --arg since "$SINCE" \ '["id","name","primaryEmail","jobTitle","companyName","joinedAt"], (.data[] | select(.joinedAt >= $since) | [.id, .name, .primaryEmail, .jobTitle, .companyName, .joinedAt]) | @csv' \ > "new-registrants-$(date +%Y-%m).csv" ``` The `event person export` endpoint always returns every registrant, so this variant projects six columns yourself when you specifically need the month-bounded slice as CSV. ## Tips * `--page-size` defaults to the server default. Pass `--page-size 100` to fetch more per call. For larger pulls, see the page-walk loop in [Scripting with jq](/cli/recipes/scripting-with-jq). * `joinedAt` is when the person registered for the event. The CLI returns it as an ISO 8601 UTC timestamp, which sorts lexicographically. `>=` string comparison in `jq` works as expected. * Pair this with [`person activity`](/cli/commands/path/person/activity) to see the full change log for any specific registrant. ## See also * [`event person list`](/cli/commands/path/event/person-list). Full filter and pagination reference. * [`event person export`](/cli/commands/path/event/person-export). CSV stream of every registrant. * [Recipe: Scripting with jq](/cli/recipes/scripting-with-jq). Projection, aggregation, and pagination patterns. * [AI agent skill: recipe-new-registrants](/cli/agents/skills). Install as a skill. # Recipe: Scripting with jq Source: https://docs.trytalkvalue.com/cli/recipes/scripting-with-jq Reusable jq snippets for filtering, projecting, aggregating, and paginating TalkValue CLI JSON output. Every TalkValue CLI command supports `--json` (or auto-emits JSON when piped). [jq](https://jqlang.github.io/jq/) is the standard tool for slicing that JSON into the exact shape you need: a single field, a count, a CSV, a chart-ready projection. The snippets below cover the patterns that keep showing up in real scripts. <Note> **Prerequisites:** authenticated CLI and `jq` installed. On macOS, `brew install jq`. On Debian/Ubuntu, `sudo apt install jq`. On Windows, `winget install jqlang.jq`. </Note> ## The envelope Paginated list commands return this shape: ```jsonc theme={null} { "data": [ /* items */ ], "pagination": { "page": 0, "pageSize": 20, "totalElements": 4321, "totalPages": 217 } } ``` Every single-resource command returns: ```jsonc theme={null} { "data": { /* item */ } } ``` Errors land on stderr as: ```jsonc theme={null} { "error": { "message": "..." } } ``` Almost every snippet below opens with `.data` or `.data[]`. ## Project: pick specific fields ```bash theme={null} talkvalue path person list --json | jq '.data[] | {id, name, primaryEmail}' ``` Returns one object per person with only the three fields. The same pattern works on any list: ```bash theme={null} talkvalue path event list --json | jq '.data[] | {id, name, startAt}' talkvalue path channel list --json | jq '.data[] | {id, name, peopleCount}' talkvalue path company list --json | jq '.data[] | {id, displayName, domain}' ``` ## Extract a single field as a flat list ```bash theme={null} talkvalue path person list --json | jq -r '.data[].primaryEmail' ``` `-r` (raw output) strips JSON quotes so you get one email per line. Ready to pipe into `mail`, `wc -l`, or a follow-up CLI call. ## Filter: keep rows that match ```bash theme={null} # People at Acme Inc. talkvalue path person list --json \ | jq '[.data[] | select(.companyName == "Acme Inc.")]' # People who registered for an event this month SINCE=$(date -u +"%Y-%m-01T00:00:00Z") talkvalue path event person list 18 --json \ | jq --arg since "$SINCE" '[.data[] | select(.joinedAt >= $since)]' # Companies with a domain set talkvalue path company list --json \ | jq '[.data[] | select(.domain != null and .domain != "")]' ``` Wrap the pipeline in `[ ... ]` to collect the matches into an array. Drop the brackets for a stream of unwrapped objects. ## Count ```bash theme={null} # Total people talkvalue path person list --page-size 1 --json | jq '.pagination.totalElements' # Registrants this month talkvalue path event person list 18 --json \ | jq --arg since "$SINCE" '[.data[] | select(.joinedAt >= $since)] | length' # Job titles ranked for one company talkvalue path company person list 88 --json \ | jq '[.data[] | .jobTitle] | group_by(.) | map({title: .[0], count: length}) | sort_by(-.count) | .[0:10]' ``` `length` on an array returns its size. `pagination.totalElements` returns the server-side total without pulling every page. ## Group and count by company ```bash theme={null} talkvalue path event person list 18 --page-size 500 --json \ | jq '[.data[] | .companyName // "Unknown"] | group_by(.) | map({company: .[0], count: length}) | sort_by(-.count)' ``` The `// "Unknown"` fallback keeps people without a company in the group instead of producing a `null` bucket. ## Project to CSV ```bash theme={null} talkvalue path person list --json \ | jq -r '["id","name","primaryEmail","companyName"], (.data[] | [.id, .name, .primaryEmail, .companyName]) | @csv' \ > people.csv ``` `@csv` quotes fields, escapes commas, and produces a valid CSV file. The first line is the header, the rest are rows. ## Walk every page ```bash theme={null} page=0 while :; do resp=$(talkvalue path person list --page "$page" --page-size 100 --json) echo "$resp" | jq -e '.data | length > 0' >/dev/null || break echo "$resp" | jq '.data[]' page=$((page + 1)) done ``` `jq -e` exits non-zero when the test is false, so the loop stops the first time a page returns no rows. Streaming `.data[]` keeps every record on stdout for further piping. ## Combine: count by company across all pages ```bash theme={null} page=0 EVENT_ID=18 all=$( while :; do resp=$(talkvalue path event person list "$EVENT_ID" --page "$page" --page-size 100 --json) echo "$resp" | jq -e '.data | length > 0' >/dev/null || break echo "$resp" | jq '.data[]' page=$((page + 1)) done ) echo "$all" \ | jq -s 'group_by(.companyName // "Unknown") | map({company: .[0].companyName // "Unknown", count: length}) | sort_by(-.count)' ``` The page-walk streams every record. `jq -s` (slurp) collects them back into a single array for the group-and-count step. ## Read the error envelope ```bash theme={null} err=$(talkvalue path person get 999999 --json 2>&1 1>/dev/null) code=$? if [ "$code" -ne 0 ]; then echo "exit=$code message=$(echo "$err" | jq -r '.error.message')" >&2 fi ``` Captures stderr separately from stdout so you get both the exit code (see [Exit codes](/cli/exit-codes)) and the structured error message in one place. ## Tips * Quote your jq filter in single quotes so the shell doesn't expand `$` characters before jq sees them. * Pass dynamic values with `--arg name value` (string) or `--argjson name value` (parsed JSON). Inside the filter, reference them as `$name`. * Pretty-printed JSON is the default. Pass `-c` for one-record-per-line output that streams cleanly into other tools. * jq has a built-in `now` function. `now | strftime("%Y-%m-%d")` makes timestamped filenames trivial. ## See also * [Output format](/cli/output-format). The JSON envelope every command returns. * [Recipe: New registrants this week](/cli/recipes/new-registrants). Uses `select`, `--arg`, and `@csv` end-to-end. * [Recipe: CSV import](/cli/recipes/csv-import). Uses `jq -r` to capture IDs from API responses. * [Recipe: Channel analysis](/cli/recipes/channel-analysis). Uses `--argjson` to combine multiple commands. * [jq manual](https://jqlang.github.io/jq/manual/). The upstream reference. # Troubleshooting Source: https://docs.trytalkvalue.com/cli/troubleshooting Diagnose common TalkValue CLI failures: auth errors, missing IDs, rate limits, network issues, and import mapping problems. Every CLI failure leaves three pieces of evidence: an exit code, an error message on stderr, and the command you ran. The patterns below match the most common failure modes to a symptom, a cause, and a fix. <Note> **Quick reference:** see [Exit codes](/cli/exit-codes) for the full code table. The error message envelope on stderr is documented in [Output format](/cli/output-format). </Note> ## Authentication failures (exit `3`) ### Symptom: "Not logged in. Run 'talkvalue auth login' to authenticate." ```bash theme={null} $ talkvalue path person list Not logged in. Run 'talkvalue auth login' to authenticate. $ echo $? 3 ``` **Cause:** no `TALKVALUE_TOKEN` is set in the environment and no saved profile exists for the current shell. **Fix:** ```bash theme={null} # Interactive (laptop) talkvalue auth login # Non-interactive (CI, scripts, agents) export TALKVALUE_TOKEN=<your-token> ``` See [Authentication](/cli/authentication) for the full credential precedence and multi-profile workflow. ### Symptom: "Session expired. Run 'talkvalue auth login' to re-authenticate." The OAuth profile exists but the refresh token has lapsed. **Fix:** ```bash theme={null} talkvalue auth login ``` Re-runs the device flow and refreshes the credential stored in your system keyring. ### Symptom: "Server did not return a refresh token. Please try logging in again." A login race or revoked session prevented the server from issuing a refresh token. **Fix:** re-run `talkvalue auth login`. If it persists, sign out first to clear local state: ```bash theme={null} talkvalue auth logout talkvalue auth login ``` ### Symptom: "Device code expired before authorization" The sign-in code from `auth login` was not approved in the browser before its TTL elapsed. **Fix:** run `talkvalue auth login` again and approve the code promptly. ### Symptom: "Multiple organizations available. Use --org \<name-or-id> to select one." Your account belongs to more than one organization and the login flow can't pick one. **Fix:** ```bash theme={null} talkvalue auth login --org "Acme Inc." # or talkvalue auth login --org org_01HXXX... ``` ## Not found (exit `4`) ### Symptom: "\<entity> \<id> not found" ```bash theme={null} $ talkvalue path person get 999999 Person 999999 not found. $ echo $? 4 ``` **Cause:** the resource (person, event, channel, company, tag, or import job) doesn't exist in the active organization. Wrong ID, wrong organization, or the record was deleted. **Fix:** 1. Confirm the active organization with `talkvalue auth status`. 2. Switch organizations if needed: `talkvalue auth switch "Other Org"`. 3. List the resource to confirm the ID: ```bash theme={null} talkvalue path person list --keyword "alice@acme.com" --json talkvalue path event list --json talkvalue path channel list --json ``` ## Forbidden (exit `5`) ### Symptom: a `5` exit code with a permission-style message ```bash theme={null} $ talkvalue path person delete 142 --confirm Forbidden. Your role does not allow this action. $ echo $? 5 ``` **Cause:** you're authenticated and the resource exists, but the active organization's role doesn't permit the operation. **Fix:** * Ask an organization admin to grant the necessary role. * Confirm you're authenticated as the correct identity with `talkvalue auth status`. See [Roles and permissions](/administration/workspace/roles-and-permissions) for what each role allows. ## Usage errors (exit `2`) ### Symptom: a required flag is missing ```bash theme={null} $ talkvalue path import create --source-id 7 --mode UPDATE Creating an import requires --file-key $ echo $? 2 ``` **Cause:** a required option was omitted. **Fix:** read the error message. It names the missing flag. The full required-flag list for every command lives on its leaf page. For `import create`, see [`import create`](/cli/commands/path/import/create). ### Symptom: an enum value is invalid ```bash theme={null} $ talkvalue path import create --file-key abc --source-id 7 --mode REPLACE --mapping 0:EMAIL --mode must be one of: UPDATE, SKIP $ echo $? 2 ``` **Cause:** you passed a value that isn't in the allowed set. **Fix:** use one of the values the error names. `import create` accepts `UPDATE` or `SKIP`; other commands list their allowed values in the error and on the leaf page. ### Symptom: out-of-range argument count ```bash theme={null} $ talkvalue path analysis channel audience --channel-id 7 --channel-id requires between 2 and 5 channel IDs $ echo $? 2 ``` **Cause:** an option that takes a bounded number of arguments received too few or too many. **Fix:** match the count to the bound. `audience` accepts 2 to 5 `--channel-id` flags; others bound themselves similarly. ### Symptom: "File not found" or "Permission denied" on `import analyze` ```bash theme={null} $ talkvalue path import analyze --file ./missing.csv File not found: ./missing.csv $ echo $? 2 ``` **Cause:** the CSV path doesn't exist or isn't readable by the current user. **Fix:** confirm the path with `ls`, fix permissions with `chmod`, or pass an absolute path. ### Symptom: "Unsupported output format" ```bash theme={null} $ talkvalue path person list --format xml Unsupported output format: xml $ echo $? 2 ``` **Cause:** `--format` accepts only `json`, `table`, or `csv`. **Fix:** use one of the three. See [Output format](/cli/output-format). ## Network and rate-limit failures (exit `1`) ### Symptom: "Request failed with status 429" You hit the API rate limit. **Fix:** the CLI already retries `429`, `502`, `503`, and `504` automatically with exponential backoff, and honors the server's `Retry-After` header up to 60 seconds. If you still see a `429` after retries, slow your script: ```bash theme={null} # In a loop, sleep between calls for id in 1 2 3 4 5; do talkvalue path person get "$id" sleep 1 done ``` ### Symptom: "Request failed with status 5xx" or timeout ```bash theme={null} $ talkvalue path person list Request failed with status 503 $ echo $? 1 ``` **Cause:** transient server-side failure or network timeout. The CLI retries up to three times before surfacing the error. **Fix:** 1. Wait and retry. `5xx` errors usually self-heal in seconds. 2. Check the API status at [status.trytalkvalue.com](https://status.trytalkvalue.com). 3. If you're overriding the API host, confirm `TALKVALUE_API_URL` and `--api-url` point at the right environment. ### Symptom: a generic network error or `TypeError` A transient connectivity issue between your machine and the API. **Fix:** the CLI auto-retries network failures. If it persists, check your proxy or VPN configuration, then re-run. ## CSV import problems ### Symptom: "Creating an import requires at least one --mapping" You skipped the mapping step. **Fix:** run `import analyze` first to see the suggested mapping, then pass it back to `import create`: ```bash theme={null} FILE_KEY=$(talkvalue path import analyze --file ./contacts.csv --json | jq -r '.data.fileKey') talkvalue path import create \ --file-key "$FILE_KEY" \ --source-id 7 \ --mode UPDATE \ --mapping 0:EMAIL --mapping 1:FIRST_NAME --mapping 2:LAST_NAME ``` See [Recipe: CSV import](/cli/recipes/csv-import) for the full flow and [Column mapping](/path/import/column-mapping) for the target-field reference. ### Symptom: job status is `PARTIAL_SUCCESS` and `failedCount > 0` Some rows imported, some were rejected. **Fix:** export the rejected rows, fix the data, and re-import: ```bash theme={null} talkvalue path import failed-export "$JOB_ID" > "failed-$JOB_ID.csv" # Inspect failed-<id>.csv — same columns as the CSV you uploaded # Fix the bad rows, then re-run import create on the corrected file ``` Read the per-row codes from the job record: ```bash theme={null} talkvalue path import get "$JOB_ID" --json | jq '.data.failedRows' ``` Common `errorCode` values: * `PERSON_INVALID_EMAIL`: the email column holds a malformed address. Fix the address. * `INVALID_DATE_FORMAT`: the column mapped to `JOINED_AT` holds an unparseable date. Use ISO 8601. ### Symptom: job status is `FAILED` and `processedRows` is `0` The whole job failed before any rows landed. Usually a malformed file, an invalid `fileKey`, or a source-channel permission issue. **Fix:** 1. Re-run `import analyze`. It returns a fresh `fileKey` and surfaces file-level errors. 2. Confirm the `source-id` channel exists and you have access: `talkvalue path channel get <id>`. 3. Reduce the file to the first 10 rows and retry to isolate which rows trigger the failure. ## Unexpected output ### Symptom: `--json` or `--format` was ignored on an export command ```bash theme={null} $ talkvalue path event person export 18 --json > out.json Warning: export commands always output CSV regardless of --format ``` **Cause:** export commands (`person export`, `event person export`, `channel export`, `import failed-export`) always stream raw CSV. They ignore the global format flags. **Fix:** drop `--json` / `--format` and consume the CSV directly, or use the matching `list` command if you specifically need JSON. ### Symptom: colored output in CI logs ANSI color codes are leaking into a log aggregator that can't render them. **Fix:** ```bash theme={null} export NO_COLOR=1 # or talkvalue path person list --no-color ``` See [Environment variables](/cli/environment-variables) for the full color-control reference. ## Still stuck? * Run any command with `--help` for the full flag list. * Check the latest CLI version: `talkvalue update`. * Email [support@trytalkvalue.com](mailto:support@trytalkvalue.com) with the exact command, the stderr message, and the exit code from `echo $?`. ## Related * [Exit codes](/cli/exit-codes). Full table. * [Output format](/cli/output-format). Error envelope shape on stderr. * [Authentication](/cli/authentication). Credentials, profiles, and `TALKVALUE_TOKEN`. * [Environment variables](/cli/environment-variables). Every env var the CLI reads. * [Recipe: CSV import](/cli/recipes/csv-import). Happy-path import workflow with failure recovery. # Choose your product Source: https://docs.trytalkvalue.com/get-started/choose-your-product Decide where to start. Path for audience analytics, Badge for event check-in, Spark for community. TalkValue gives every workspace three products. Most teams start with one (the one tied to the next event on the calendar) and turn the others on later. Use the criteria below to pick where to spend your first hour. ## When to choose Path Path is **audience intelligence**: it consolidates every contact across every event, channel, and import, then shows you who's engaged, who's new, and which channels are growing your audience. * Have a CSV (or two, or twenty) of registrations and attendees and want them de-duplicated and searchable in one place. * Need to answer "Where are our registrations coming from?" with attribution across Eventbrite, Luma, social, partner referrals, and direct sign-ups. * Want to spot which companies and channels keep showing up (and which ones stopped) so your next event invite list is sharper than the last. <Card title="Open Path" icon="users" href="/path"> Import contacts, attribute registrations, and chart audience trends over time. </Card> ## When to choose Badge Badge is **on-site event check-in**: a visual badge editor, a browser-paired label printer, and a mobile staff station that runs on any phone. No app install required. * Are running a conference, summit, or partner event and need printed name badges that look on-brand. * Want check-in staff to scan QR codes or search by name from a phone, with no native app and no shared login. * Have a Zebra or Nemonic label printer (or are about to buy one) and want to connect it from the browser with no driver install. <Card title="Open Badge" icon="ticket" href="/badge"> Create events, design templates, connect a printer, and brief your staff. </Card> ## When to choose Spark Spark is **community curation**: it watches your community spaces and ships a clean, link-rich digest to Slack every day at the time you pick. * Run a Slack community for your event series and want a daily "what you missed" digest without writing it by hand. * Need to keep your community warm between events. The digest fills the gap without over-posting in the channel. * Want category-based digests (announcements, jobs, intros, etc.) instead of one undifferentiated recap. <Card title="Open Spark" icon="sparkles" href="/spark"> Set up categories, connect Slack, and schedule your first digest. </Card> ## You can use all three The three products share one workspace, one membership list, and one billing plan. Most teams turn on Path first because it backs every event and every digest, then add Badge before their next on-site event and Spark when the community needs more rhythm between events. Ready to set up? Run the [quickstart](/get-started/quickstart). # Welcome to TalkValue Source: https://docs.trytalkvalue.com/get-started/index Path, Badge, and Spark. Three products in one workspace. Start here. TalkValue gives event teams three products in one workspace: **Path** for audience analytics, **Badge** for event check-in, and **Spark** for community curation. Pick the product that matches what you need today and add the others later. <CardGroup> <Card title="Path" icon="users" href="/path"> Audience intelligence. Import contacts, attribute registrations, and analyze trends. </Card> <Card title="Badge" icon="ticket" href="/badge"> Event check-in with custom badges, a visual template editor, and a mobile staff station. </Card> <Card title="Spark" icon="sparkles" href="/spark"> Build and engage your event community across Slack, social channels, and venue displays. </Card> </CardGroup> ## Next step <Card title="Run the 5-minute quickstart" icon="rocket" href="/get-started/quickstart"> Sign up, create your workspace, start your 7-day trial, and pick your first product. </Card> Not sure which product fits your team today? [Choose your product →](/get-started/choose-your-product) # Quickstart Source: https://docs.trytalkvalue.com/get-started/quickstart From sign-up to your first product action in 5 minutes. This quickstart takes about five minutes. By the end you have a TalkValue workspace, an active 7-day Pro trial, and a first action inside Path, Badge, or Spark. Run these steps in order. They map to the screens at [app.trytalkvalue.com](https://app.trytalkvalue.com). <Note> **Prerequisites** * A work email. Google sign-in and email sign-in both work; personal Gmail is accepted. * A credit or debit card to start the trial. No charge during the 7 days. </Note> <Steps> <Step title="Sign up at app.trytalkvalue.com"> Open [app.trytalkvalue.com](https://app.trytalkvalue.com) and sign in. Pick **Continue with Google** for one-click sign-in, or enter your email to receive a magic-link code. New accounts are created on first sign-in. There's no separate sign-up form. </Step> <Step title="Create your workspace"> On the welcome screen, click **Create Workspace**, name it after your team or company, and continue. The workspace name appears on the workspace switcher chip in the top header and in the "from" line of emails TalkValue sends from your workspace. Full walkthrough: [Create your workspace](/get-started/workspace/create-workspace). </Step> <Step title="Start your 7-day Pro trial"> Add a payment method to unlock the trial. You won't be charged during the 7 days, and the workspace converts to Pro at \$299/month on day 8 unless you cancel. See [Plans and trial](/administration/billing/plans-trial-pro) for what's included and how the conversion works. </Step> <Step title="Pick your first product"> Open **Path** to import contacts and build audience analytics, **Badge** to run on-site event check-in, or **Spark** to publish a Slack digest for your community. You can use all three from the same workspace. Start with whichever is most urgent for the next event. Not sure yet? Open [Choose your product](/get-started/choose-your-product). </Step> </Steps> ## Next <CardGroup> <Card title="Invite your team" icon="user-plus" href="/get-started/workspace/invite-teammates"> Bring teammates into the workspace before the trial clock matters. </Card> <Card title="Choose your product" icon="compass" href="/get-started/choose-your-product"> Decide where Path, Badge, or Spark fits your team first. </Card> </CardGroup> # Create your workspace Source: https://docs.trytalkvalue.com/get-started/workspace/create-workspace Create your first TalkValue workspace, name it, and start your Pro trial. A workspace is where your team's events, contacts, badges, and Slack digests live together. You'll create one on your first sign-in. This page walks you through it and what happens after. <Note> **Prerequisites** * You're signed in at [app.trytalkvalue.com](https://app.trytalkvalue.com) * You don't already belong to a workspace (if you do, jump to the [workspace switcher](#what-is-a-workspace) in the top header instead) </Note> ## Create the workspace <Steps> <Step title="Click Create workspace"> On the welcome screen right after sign-in, click **Create Workspace**. If you're already inside another workspace, open the workspace switcher in the top header and pick **Create Workspace** from the menu. </Step> <Step title="Pick a workspace name"> Use your team or company name. For example, `Acme Events` or `Northstar Marketing`. The name shows on the workspace switcher chip in the top header and in the "from" line of emails TalkValue sends on your behalf, so pick something your teammates and attendees will recognize. You can rename the workspace later from **Settings → General**. </Step> <Step title="Set up billing to start your trial"> After you name the workspace, TalkValue takes you to the billing step to add a payment method and start your 7-day Pro trial. You won't be charged during the trial. Once you finish onboarding, you land on the dashboard with two product tiles: **Path** and **Badge**. Spark lives in the left icon rail and opens externally. Pick the product that matches the next event on your calendar, or run the [quickstart](/get-started/quickstart) for the full setup flow. </Step> </Steps> ## What is a workspace? A workspace is one team's TalkValue instance: one membership list, one billing plan, and one set of events, contacts, badges, and Slack digests. You can belong to multiple workspaces (for example, your own company's workspace and a client's) and switch between them from the workspace switcher chip in the top header. A few things to know: * Each workspace bills separately. The 7-day Pro trial applies per workspace. * Members and invitations are per workspace. Adding someone to one doesn't add them to the others. * Workspace name is visible to every member and on outbound emails. ## Related * [Invite teammates](/get-started/workspace/invite-teammates). Bring the rest of the team in with the right role. * [Plans and trial](/administration/billing/plans-trial-pro). What's included in the trial and what happens on day 8. * [Choose your product](/get-started/choose-your-product). Decide where to spend your first hour. # Invite teammates Source: https://docs.trytalkvalue.com/get-started/workspace/invite-teammates Send workspace invitations, set roles, and manage pending invites in TalkValue. Invitations bring teammates into your workspace with the right level of access. Invites expire in 7 days, can be revoked at any time, and use the same magic link flow members already use elsewhere. To re-send, revoke the pending invitation and send a fresh one. <Note> **Prerequisites** * You're a workspace **Admin** (Members can't invite others. See [Roles and permissions](/administration/workspace/roles-and-permissions).) * You know the email address you want to invite. Any email address works, including personal Google accounts. </Note> ## Send an invitation <Steps> <Step title="Open Settings → Members"> From the sidebar, open **Settings**, then click **Members**. You'll see the current member list and any invitations that haven't been accepted yet. </Step> <Step title="Click Invite Member"> In the top right of the members list, click **Invite Member**. A dialog opens with an email field and a role selector. </Step> <Step title="Enter the teammate's email"> Type the teammate's email address. The dialog accepts one address per send. To invite multiple people, repeat the invite flow per address. </Step> <Step title="Pick a role"> Choose the invitee's role: * **Admin**: can manage billing, members, integrations, and workspace settings. Use this for teammates who own setup or own the bill. * **Member**: can use Path, Badge, and Spark, and connect integrations. Use this for everyone else. You can change someone's role later from the same screen. </Step> <Step title="Send"> Click **Send Invitation**. The invitee receives an email from your workspace within a few seconds. The dialog closes when send succeeds. </Step> </Steps> ## What invitees see Each invitation email contains a link to accept and join. Opening the link sends a 6-digit code to the invited address and opens the **Accept invitation** screen. Enter the code to join. Existing TalkValue users join the workspace and see it in their workspace switcher. New users create an account on the spot and land in your workspace. Invitations expire **7 days** after they're sent. After that the link no longer works. Revoke the expired invitation and send a fresh one from **Settings → Members**. ## Manage pending invitations On **Settings → Members**, the bottom section lists every invitation that hasn't been accepted yet. From here you can: * **Revoke**: cancel the invitation. The link stops working immediately. * **Change role before acceptance**: revoke and re-send with the new role. ## Change a member's role After someone has accepted, change their role from the same **Settings → Members** screen: open the actions menu on their row and pick **Make Admin** or **Make Member**. The change takes effect on their next page load. See [Roles and permissions](/administration/workspace/roles-and-permissions) for the full capability matrix. ## Remove a member Removing a member from the workspace revokes their access immediately. Open the actions menu on the member's row on **Settings → Members**, click **Remove Member**, and confirm. The member keeps their TalkValue account and any other workspaces they belong to. ## Related * [Members reference](/administration/workspace/members). Full settings page reference for the members list. * [Roles and permissions](/administration/workspace/roles-and-permissions). What Admin and Member can do, capability by capability. * [Plans and trial](/administration/billing/plans-trial-pro). How members fit into the workspace plan. # Channel Attribution Source: https://docs.trytalkvalue.com/path/analytics/attribution Compare channels side by side. What each channel's audience looks like and how it acquired registrants per event. The Channel Attribution view lets you put any two or more channels side by side and read each one's full attribution story: total audience, share that has ever converted to an event, average registrants per event, and a per-event chart showing whether each event's registrants were already in the channel or joined since the last event. It's the answer when somebody asks "is the newsletter outperforming LinkedIn this quarter?" ## Open the view Open **Path → Attribution**. By default the page selects your first two channels for comparison; everything else lives in the channel toggle row above the panels. ## Toggle channels to compare The toggle row shows every channel in your workspace, color-coded with its own icon. Click any chip to add or remove it from the comparison. Each selected channel renders as one panel below. There's no hard maximum; pick the channels you want to compare. The page lays panels out two-up on wide screens and stacks them on narrow ones, so two-channel comparisons read as a head-to-head and three- or four-channel comparisons read as a quadrant. ## Read a channel panel Each panel has the same shape, so cross-panel reads are easy: * **Channel Size.** Total people attributed to this channel. The denominator. * **Members Ever Registered.** Distinct channel members who registered for at least one event, deduplicated across events. The cumulative conversion. * **Event Participation Rate.** Members Ever Registered ÷ Channel Size. The "how much of this channel ever converts" number. * **Avg Registrants per Event.** Mean number of this channel's members who registered, across every event in the current view. The per-event yield. Below the stats is the **Channel Acquisition by Event Year** chart. Each bar is one event, ordered by start date, split into two segments: * **Joined Since Last Event.** People who joined the channel in the window between the prior event and this one. The freshness signal. * **Already in Channel.** People who were already in the channel before the prior event. The retention signal. An **Acquisition Rate** line on the right axis plots the Joined Since Last Event share of each event, starting from the second event in the series. A high Joined Since Last Event share means the channel is genuinely growing your audience between events. A high Already in Channel share means the channel is re-converting the same crowd you already had: useful for retention, less useful for top-of-funnel. ## What you can learn Three reads to extract from any side-by-side: 1. **Which channel converts.** Compare Event Participation Rate. A channel with 50% participation is much harder-working than one with 5%, regardless of size. 2. **Which channel grows.** Compare the Joined Since Last Event share over time. A channel whose Joined Since Last Event segment stays tall across events is bringing in fresh audience consistently. 3. **Which channel costs more than it returns.** A channel with a low participation rate and a falling Joined Since Last Event share is a candidate to retire or rebuild. ## Filter by tag Use the **tag filter** in the page header to scope each panel to a subset of events. For example, only `Customer Day` events. Every panel's chart and table re-renders against the filtered slice. The selection is encoded in the URL as `?tagId=N`, so the filtered view is deep-linkable. Open a `?tagId=…` URL for a tag that no longer exists and Path drops the filter and shows the full view rather than error out. ## Edge cases * **One channel selected.** The page renders a single panel; useful for a deep dive, but the comparison value comes from selecting at least two. * **Channel with no registrations yet.** The panel renders its stats and the table, with every event showing a total of 0. Import people into the channel to populate the chart. * **No events match the tag filter.** Each panel shows an empty state telling you to attach events to the tag or clear the filter. ## Related * [Attribution model](/path/concepts/attribution-model). How a person gets linked to a channel. * [Channel Audience](/path/analytics/audience). Where channels share people. * [Registration trend](/path/analytics/registration-trend). Overall growth, before slicing by channel. * [Tags](/path/concepts/tags). Group events for filtered analytics. # Channel Audience Source: https://docs.trytalkvalue.com/path/analytics/audience Read the Venn-diagram overlap between two to five channels to spot concentration, redundancy, and unique reach. The Channel Audience view shows you which channels share people and which channels reach distinct audiences, using a Venn diagram of two to five channels at a time. It's the answer when somebody asks "if we cut the newsletter, how much of that audience do we already get through LinkedIn?" ## Open the view Open **Path → Audience**. The page picks your first three channels for an initial comparison; everything else lives in the toggle row above the chart. The page only renders when you have **two or more channels** in your workspace. With fewer than two, the page shows an empty state pointing you to create more channels. ## Toggle two to five channels The toggle row shows every channel in your workspace. Click any chip to add or remove it from the comparison; selections update the Venn diagram, stat cards, and detail table immediately. You can select **between two and five channels**. Adding a sixth toggle is rejected; five is the maximum the Venn diagram renders cleanly. To compare more, swap channels in and out rather than stack them. ## Read the Venn diagram The diagram shows one circle per selected channel. Each circle's size scales with the channel's total audience, so a glance tells you which channels are large and which are small. The intersections are the data: * **Two-channel overlap.** The lens shape where two circles meet shows the count of people who belong to both channels. * **Three-or-more overlap.** Every region carries a number. The center is the people in all selected channels, and each pair region is the people in both of those channels, including anyone who also belongs to a third. Circle size is the channel's full audience. * **No overlap.** Circles render side by side without intersecting. That's a real signal: those channels are reaching disjoint audiences. Three stat cards above the chart summarize the selection: Total Unique, Multi-Channel, and Overlap Rate. The table below the chart lists every intersection with its exact Overlap Count, so you read values instead of estimating from the diagram. ## What you can learn Three concrete reads: 1. **Concentration risk.** If one circle dominates the diagram and barely overlaps with others, you're depending heavily on a single channel. Losing it would cost you most of the audience it reaches. 2. **Redundancy.** Two circles that overlap on 80% of their area are reaching mostly the same people. One of them is doing the work the other is also doing: a candidate to scale back or repurpose. 3. **Unique reach.** A channel's true value is the slice that *doesn't* overlap with anything else. That slice is your durable, channel-specific audience: the people you'd lose if you turned that channel off. ## Edge cases * **Fewer than two channels selected.** The chart needs at least two to compute an overlap. The page shows an empty state until you add a second. * **One channel is empty.** A channel with zero attributed people renders as a missing circle in the diagram. The overlap regions still draw for the remaining channels. * **Same person on three channels.** They count in the all-three intersection and in each pair those channels form, so intersection counts include people who also belong to other selected channels. * **Six or more channels.** The toggle ignores the extra selection. Swap channels in and out to compare different combinations. ## Related * [Audience overlap](/path/concepts/audience-overlap). What overlap means conceptually. * [Channel Attribution](/path/analytics/attribution). How each channel converts to events. * [Registration trend](/path/analytics/registration-trend). Net-new vs. returning across all channels. * [Channels](/path/manage/channels). Create, edit, or delete a channel. # Registration trend Source: https://docs.trytalkvalue.com/path/analytics/registration-trend Read net-new vs. returning registrations across your events with a stacked-bar chart and a net-new-rate line. The Registration Trend chart shows whether your audience is growing, churning, or compounding. Each bar is one event, split into the people who'd never registered before (Net New) and the people who had (Returning). A line lays a third number on top, the percentage of the latest event that was net new, so you can see the trajectory at a glance. ## Open the chart Open **Path → Analytics**. The Registration Trend page is the default analytics view. The page renders four stat cards summarizing your audience, the chart itself, and a row-by-row table beneath. ## Chart anatomy The chart is a stacked column with an overlay line: * **X axis.** Your events, ordered chronologically by start date (oldest left, newest right). * **Y axis (left).** Registrants. The total height of each bar is total registrations for that event. * **Bar segments**: * **Net New.** People registering for one of your events for the first time. New audience. * **Returning.** People who had registered for any earlier event in your workspace. * **Y axis (right)** and **line.** The Net New Rate as a percentage. Only rendered when there are three or more events to plot, because trend lines need at least three points to read as a trend. Each bar carries a total label above it for quick reading, and a legend under the chart names each series. ## What you can learn Three concrete reads: 1. **Audience expansion.** A series of bars where Net New stays consistently tall means your top-of-funnel channels are working. A flattening Net New segment means you're recycling the same audience. 2. **Loyalty signal.** A growing Returning segment shows that past attendees are coming back; your content or programming retains people. Use it as a leading indicator for community strength. 3. **Saturation warning.** If Net New is shrinking *and* Returning is shrinking, you're losing audience faster than you're acquiring it. Time to revisit channels or programming. The stat cards above the chart unpack the same data: * **Unique Audience.** Total distinct people across every event in scope. * **Latest Registrations.** Total for your most recent event, with a delta vs. the previous event. * **Net-New Rate.** Percentage of your latest event that was first-time, with a delta vs. the previous event. * **Return Rate.** Percentage of latest-event registrants who had attended any prior event. <Note> **Ask a follow-up.** Press **Cmd+I** (Mac) or **Ctrl+I** (Windows / Linux) to open the in-app AI assistant. Ask questions like *"Which channels added the most net-new audience last quarter?"* or *"What changed between the last two events?"* and get an answer grounded in this workspace's data. </Note> ## Filter by tag Use the **tag filter** in the page header to scope every chart and stat card on the page to a slice of events. Pick `Customer Day` and the chart re-renders against only customer-day events; pick `Q2-campaign` to look at one campaign in isolation. The selection is in the URL as `?tagId=N`, so deep-linking just works. Share the URL and the recipient sees the same filtered view. Open a stale `?tagId=…` for a deleted tag and Path silently drops the filter and shows the full view: no error, no broken page. ## Edge cases * **Fewer than three events.** The Net New Rate line is hidden; three points is the minimum for a readable trend. * **No events match the filter.** The chart is replaced with an empty state telling you to attach events to the tag or clear the filter. * **Single-event view.** Bars render, but Net New Rate is 100% by definition; every registrant of your first event is "net new". The signal kicks in starting with event two. ## Related * [Channel Attribution](/path/analytics/attribution). Which channels drove the registrations you see here. * [Channel Audience](/path/analytics/audience). Where your channels share people. * [Tags](/path/concepts/tags). Group events for scoped analytics like this one. * [Events](/path/manage/events). Add or edit the events plotted here. # Attribution model Source: https://docs.trytalkvalue.com/path/concepts/attribution-model How Path links each registration to the channel that drove it. <Note> Every person who registers for an event in Path is linked to one or more **channels**, the sources that brought them in. Channels are the unit of attribution. The Attribution chart compares how each channel contributed to a given event. </Note> Attribution in Path answers a single question: **which channels drove the registrations for this event?** This page explains what a channel is, how the link is made, and how to read the multi-channel view. ## Channels are the unit of attribution A **channel** is a named, reusable source of registrations. Examples: `Newsletter, May 2026`, `LinkedIn campaign`, `Partner referral`, `SDR outbound`. TalkValue also creates a channel automatically when you import a HubSpot portal or a Slack workspace. Channels persist across events. That's what lets you compare a single channel's contribution to many events side by side and see which sources contribute consistently versus only once. ## How a registration gets attributed A person becomes attributed to a channel in one of three ways: * **Direct import.** When you import a CSV into a channel, every person in that file joins that channel. * **Imported channel.** Connect HubSpot or Slack and import a portal or workspace. TalkValue creates a channel for it and attributes every contact or member to that channel. * **Multi-channel.** The same person can belong to several channels at once. For example, someone on your newsletter who also registered through a partner page. Path keeps every link, which is what makes overlap analytics work. ## Reading the Attribution chart Open **Path → Analytics → Channel Attribution**. Each panel represents one channel; each bar inside a panel represents one event. The bar shows how many of that event's registrations came through that channel. * **Toggle channels** to compare two or more side by side. * **Filter by tag** to scope the chart to a specific group of events. For example, only `Customer Day` events. * **Drill into a channel** by opening it from the Channels page to see every person and every event the channel touched. ## Edge cases * **Person on multiple channels.** Counted under each channel in the chart. They are real contributors to each. This is the source of overlap, not a duplicate. * **Event with no channels.** The event won't appear in any channel's panel until you import people into a channel for it. * **Channels you don't want in the chart.** Untoggle them. The chart only renders the channels you select. ## Related * [Channel Attribution chart](/path/analytics/attribution). How to read the multi-channel comparison. * [Audience overlap](/path/concepts/audience-overlap). What shared people across channels mean. * [People, companies, channels, events](/platform/concepts/data-model). Entity primer. * [Tags](/path/concepts/tags). Scope attribution to a subset of events. # Audience overlap Source: https://docs.trytalkvalue.com/path/concepts/audience-overlap What shared audiences across channels mean and how to read the overlap chart. <Note> **Overlap** is the set of people who appear in two or more channels at the same time. The Audience Overlap chart in Path visualizes this with a Venn diagram comparing two to five channels at once. </Note> When the same person registers through your newsletter and a partner referral and shows up in both channel rosters, that's overlap. Path measures it so you can tell apart durable shared audiences from one-off intersections, and decide where to invest. ## Why overlap matters Overlap answers three questions: * **Channel redundancy.** If two channels share 80% of their audience, you're paying twice to reach the same people. One of them may be redundant. * **Unique reach.** A channel's true value is the audience it brings that no one else brings. The portion of a channel that *doesn't* overlap is its unique contribution. * **Audience concentration risk.** If most of your audience comes through a single channel with no overlap with anything else, losing that channel costs you the audience. ## How Path computes overlap A person is "in" a channel if they have been attributed to it, via direct import, a HubSpot or Slack channel import, or any other channel link. When you select two channels in the Audience Overlap view, Path counts the people who appear in both. With three or more channels, it counts every combination of them: people in A and B, people in all three, and so on. Counts reflect the current state of your audience. The chart reflects new imports and connected sources the next time you open it. ## Reading the chart Open **Path → Analytics → Channel Audience** and pick **two to five channels** from the toggle row. The Venn diagram, stat cards, and table update together: * **Each circle** is one channel; its size scales with the channel's total audience. * **Overlap regions** show how many people sit at each intersection. Hover over a region to see its channel combination and count, then read the exact numbers in the table below the chart. * **Stat cards** above the chart summarize the selection: Total Unique (deduplicated people across the selected channels), Multi-Channel (people in two or more of them), and Overlap Rate (their share of the total). To compare more than five channels, switch the selection. Five is the maximum the Venn diagram renders cleanly. ## Edge cases * **Just one channel selected.** The chart needs at least two channels to draw overlap. Add another from the toggle row. * **No overlap between selected channels.** Circles render side by side with no intersection. That's a real signal: your channels are reaching distinct audiences. * **Same person on three channels.** They count in the all-three intersection and in each pair those channels form. Every intersection count includes the people who also belong to other selected channels. ## Related * [Attribution model](/path/concepts/attribution-model). How a person gets linked to a channel in the first place. * [People, companies, channels, events](/platform/concepts/data-model). Entity primer. * [Tags](/path/concepts/tags). Narrow analytics to a slice of events. # Tags Source: https://docs.trytalkvalue.com/path/concepts/tags Group events and channels with tags, then scope Path views and analytics by them. <Note> **Tags** are short labels you attach to events and channels, like `Customer Day`, `Webinar`, or `Q2-campaign`. Use them to filter Path views and scope analytics charts to a specific slice of your audience. </Note> Tags are a lightweight way to group related events and channels without restructuring them. Once a tag exists, you can attach it to as many of them as you want, then scope the Path overview, Registration Trend, and Channel Attribution to the events that carry it. ## What tags do Tags do two things: * **Group related events and channels.** Attach the `Customer Day` tag to every customer-day event, or the `LinkedIn` tag to every LinkedIn-origin channel. The Events list shows the tags inline so you can see groupings at a glance. * **Scope analytics.** Pick a tag from the filter on the Path overview, Registration Trend, or Channel Attribution, and every chart re-renders against only the events that carry that tag. Path deep-links the selection. Share the URL and the recipient sees the same filtered view. If you open a `?tagId=…` URL for a tag that no longer exists, Path drops the filter and shows the full view. ## Create and attach tags You manage the tag library from the **Events** page in Path. <Steps> <Step title="Open Events and click Manage tags"> In Path, navigate to **Events** and click **Manage tags** in the page header. The Tags dialog opens with every tag in your workspace. </Step> <Step title="Create a new tag"> Type a name in the add-tag input and submit. The tag is created immediately and shows up in the list. You can rename or delete it later from the same dialog. </Step> <Step title="Attach the tag to an event"> Close the dialog, open any event from the Events list, and use the event's tag field to attach one or more tags. The new tag appears in the autocomplete as you type. </Step> <Step title="Attach the tag to a channel"> Run [`talkvalue path tag attach <sourceId> --tag-id <id>`](/cli/commands/path/tag/attach). The command takes a channel ID or an event ID, because the tag relationship is shared across both. </Step> </Steps> ## Naming tips * Keep tags short and scannable: `Customer Day`, `Webinar`, `LinkedIn`, `Q2-campaign`. * Pick a convention and stick with it. Mixing `customer-day`, `Customer Day`, and `CustomerDay` makes the filter list longer without adding information. * Use tags for cross-cutting groupings (event type, campaign, region). For one-off labels that don't repeat, you don't need a tag at all. ## Edge cases * **Delete a tag.** Removes the tag from every event and channel it was attached to. Those events and channels themselves are not affected. * **Tag is empty.** A tag with nothing attached shows up in the library and in the filter. Pick it and Path prompts you to attach events to the tag or clear the filter. ## Related * [Events](/path/manage/events). Create, tag, and filter events. * [`path tag attach`](/cli/commands/path/tag/attach). Attach a tag to a channel or an event from the CLI. * [Attribution model](/path/concepts/attribution-model). See how tag-scoped attribution works. # Column mapping Source: https://docs.trytalkvalue.com/path/import/column-mapping How Path auto-detects CSV columns and how to override the mapping manually. The Configure step of the import wizard shows a **Map Fields** table: every column in your CSV, side by side with the TalkValue field it maps to. Path auto-detects the common headers; you can override any of them, skip columns you don't want to import, and create new channels or events inline. <Note> **Before you start** * You're partway through an import. See [Import a CSV](/path/import/csv-quickstart) for the full flow. * At least one column must map to **Email**. The Continue button stays disabled until you map it. </Note> ## How auto-detection works Path inspects the headers in the first row of your CSV and suggests a TalkValue field for each one. Common patterns (`email`, `first_name`, `company`, `linkedin`, `phone`, `joined_at`, and their variations) are detected automatically. When Path is confident, the suggested field appears under a **Suggested** group at the top of the dropdown. If Path can't make a confident guess, the column shows up unmapped and you pick the right field manually. Columns left unmapped, either by Path or by you, are skipped during import. ## Supported target fields | Field | What it stores | | ---------------- | ------------------------------------------------------------------------------------------------ | | Email (Required) | Primary email address. One column must map here. | | First Name | Given name. | | Last Name | Family name. | | Full Name | Full name in a single column. Use either Full Name or the First Name + Last Name pair, not both. | | Phone | Phone number. | | Job Title | Title at the person's company. | | Company Name | Company display name. Used when the email domain isn't enough to group reliably. | | Address | Mailing or visit address. | | LinkedIn URL | LinkedIn profile URL. | | X URL | X (Twitter) profile URL. | | Joined At | Date the person joined the channel or event. | ## Override the mapping <Steps> <Step title="Find the column you want to remap"> Scroll the Map Fields table. Each row shows the source field name, two sample values from your CSV, and the current TalkValue field. </Step> <Step title="Open the field dropdown"> Click the field cell to open the picker. Suggested fields appear at the top; the full field list sits below under **All Fields**, with **-- Do not import --** as the first option. </Step> <Step title="Pick the right field, or skip"> Select the field you want. To skip the column entirely, pick **-- Do not import --**. Fields already used by another column are dimmed in the picker. Each target field can be mapped by at most one source column at a time. </Step> <Step title="Confirm Email is mapped"> Above the table, you'll see a counter like `4 of 8 fields mapped`. If Email isn't mapped yet, a red **Email mapping is required** warning appears. Map it and the Continue button enables. </Step> </Steps> ## Troubleshooting ### Path suggested the wrong field for a column Pick the correct one from the dropdown. Suggestions are convenience, not constraint; your manual choice always wins. ### A field I need isn't in the list The fields above are the full set Path maps. If your CSV has columns that don't match any of them, leave them as **-- Do not import --**. Unmapped columns are skipped; the data stays in your source file. ### Two columns hold the same data, which one do I map? Pick one. The same target field can only be mapped by one column at a time; the other gets dimmed in the dropdown. If both columns have useful values, consolidate them in the source file before re-importing. ## Related * [Import a CSV](/path/import/csv-quickstart). The full upload-to-import flow. * [Connect Eventbrite](/platform/integrations/eventbrite). Skip CSVs and sync events directly. * [Connect Luma](/platform/integrations/luma). Skip CSVs and sync events directly. # Import a CSV Source: https://docs.trytalkvalue.com/path/import/csv-quickstart Upload contacts in five steps with auto-detected column mapping. CSV import is the fastest way to bring people into Path. Upload a file, pick a channel or event, confirm the field mapping, and start the import. Most files finish in well under a minute. Prefer to sync automatically? See [Connect Eventbrite](/platform/integrations/eventbrite) or [Connect Luma](/platform/integrations/luma). <Note> **Before you start** * A TalkValue workspace with an active Pro trial. See [Plans and trial](/administration/billing/plans-trial-pro). * A CSV file with headers in the first row, encoded as UTF-8 * 10 megabytes or less of file size * A column with email addresses. Every imported person must have one. </Note> ## Run the import <Steps> <Step title="Open Path and click Import Data"> Sign in at [app.trytalkvalue.com](https://app.trytalkvalue.com), open **Path** from the left rail, and click **Import Data**. The Upload step of the import wizard opens. </Step> <Step title="Drop your CSV onto the upload area"> Drag a `.csv` file onto the dropzone, or click **Select file** to browse. If you don't have one, click **Download sample template** to grab a template with the headers Path auto-detects. The file is analyzed in place, showing the row count, column count, and a preview of the first detected columns. Click **Continue**. </Step> <Step title="Pick a target (channel or event)"> On the Configure step, choose where the contacts go: * **Channel.** A reusable source like `Newsletter` or `LinkedIn` that persists across events. * **Event.** A single dated gathering. Pick this when the file is an attendee list for one event. Pick from the list, or use the **Create channel** / **Create event** option to make a new one inline. </Step> <Step title="Confirm the column mapping"> The **Map Fields** table shows every column in your CSV with its sample values and an auto-detected TalkValue field. Suggested fields appear at the top of the dropdown. Pick a different field for any column you want to override, or set it to `-- Do not import --` to skip. **Email is required.** The Continue button is disabled until at least one column is mapped to Email. Full reference: [Column mapping](/path/import/column-mapping). </Step> <Step title="Review and start the import"> On the Review step, confirm the row count, target, and field mapping, then choose how to handle duplicates: **Update existing** or **Skip duplicates**. Click **Start Import**. Progress streams live. When it finishes, open **People** in the Path side panel to see the new contacts. </Step> </Steps> ## CSV format * **Encoding.** UTF-8. * **Headers.** First row must contain column names. Path matches on the header text. * **File size.** Up to 10 megabytes per upload. For larger files, split into multiple imports. * **Required mapping.** At least one column must map to **Email**. Other fields are optional. * **Supported target fields.** Email, First Name, Last Name, Full Name, Phone, Job Title, Company Name, Address, LinkedIn URL, X URL, Joined At. ## Troubleshooting ### The upload is rejected with a file-size error The file is larger than 10 megabytes. Split it into smaller CSVs and import each one in turn. Path matches on email, so the same person across two files lands on one record. **Update existing**, the default on the Review step, refreshes that person's data; **Skip duplicates** leaves the existing record untouched. ### Email is not auto-detected Path didn't recognize your header for the email column. Open the Map Fields table, find the column that contains email addresses, and pick **Email (Required)** from the dropdown. The Continue button enables once Email is mapped. Full reference: [Column mapping](/path/import/column-mapping). ### A row failed during import Path reports rows with invalid emails, invalid phone numbers, or unparseable dates and continues importing the rest. After the import finishes, the result screen lists the failed rows with their error reason so you can fix them in the source file and re-import. ## Related * [Column mapping](/path/import/column-mapping). Full field reference and how auto-detection works. * [Connect Eventbrite](/platform/integrations/eventbrite). Sync events and attendees automatically. * [Connect Luma](/platform/integrations/luma). Sync events and attendees automatically. * [People, companies, channels, events](/platform/concepts/data-model). Entity primer. # Path Source: https://docs.trytalkvalue.com/path/index Audience intelligence. Track contacts, channels, registrations, and trends. Path turns your event registrations into audience intelligence. Import contacts from CSV, Eventbrite, or Luma, see how each registration was attributed to a channel, and read trends across people, companies, and events. <CardGroup> <Card title="Concepts" icon="book" href="/platform/concepts/data-model"> How people, companies, channels, and events relate. </Card> <Card title="Import" icon="upload" href="/path/import/csv-quickstart"> Bring contacts in from CSV, Eventbrite, or Luma. </Card> <Card title="Analytics" icon="chart-line" href="/path/analytics/registration-trend"> Read registration trends and multi-channel attribution. </Card> </CardGroup> ## Next step <Card title="Run the Path quickstart" icon="rocket" href="/path/quickstart"> Import a CSV and see your first chart in 10 minutes. </Card> # Channels Source: https://docs.trytalkvalue.com/path/manage/channels Create or import channels, attribute people to them, and review a channel's audience and events. A **channel** is a reusable source of registrations, a touchpoint like `Newsletter`, `LinkedIn campaign`, `Partner referral`, or `SDR outbound`. Channels persist across events, so attribution and audience-overlap analytics can track the same source over time. This page covers creating channels, importing them from HubSpot or Slack, linking them to events, and reading the channel detail page. ## Create a channel Open **Path → Channels** and click **Create Channel** in the page header. A dialog opens with three fields. <Steps> <Step title="Pick an icon"> Click the icon swatch to open the emoji picker. Search for an icon that matches the channel: a megaphone, a paper plane, a partner handshake. The icon shows up everywhere the channel is referenced. </Step> <Step title="Name the channel"> Give the channel a specific, durable name. Channels persist across events. Examples: `Newsletter, May 2026`, `LinkedIn, Spring campaign`, `Partner: Acme co-marketing`. </Step> <Step title="Choose a color"> Pick from the color swatch row. The color is used in the channel chip across tables, the registration-trend chart legend, and the attribution panels. </Step> <Step title="Save"> Click **Create**. The channel is ready immediately. You'll see it in the channels list and in every channel dropdown across the app. </Step> </Steps> You can edit any channel's name, icon, or color later from its detail page. ## Link people to a channel People become attributed to a channel in three ways: * **Direct import.** When you import a CSV into a specific channel via the [import wizard](/path/import/csv-quickstart), every person in that file joins that channel. * **Imported channel.** When you connect [HubSpot](/platform/integrations/hubspot) or [Slack](/platform/integrations/slack) and import a portal or workspace, every contact or member becomes a person attributed to that channel. * **Multi-channel.** The same person can belong to many channels. That overlap is the data behind the [Audience overlap chart](/path/analytics/audience). To bulk-import existing contacts into a channel, open the channel and click **Import** in the page header. The import wizard opens pre-selected for this channel. ## Import a channel from HubSpot or Slack You can pull an entire HubSpot portal or Slack workspace into Path as a channel, with its contacts or members added as people. <Steps> <Step title="Open Path → Channels"> Click **Import Channel** in the page header. </Step> <Step title="Pick a provider"> The dialog lists **HubSpot** and **Slack**. If the provider is already connected, click **Import**. If it is not, click **Connect** to authorize it first, then **Import**. </Step> <Step title="Review the new channel"> TalkValue creates a channel named after your HubSpot portal or Slack workspace and adds every contact or member as a person attributed to it. People are matched by email, so re-importing updates existing people instead of creating duplicates. </Step> </Steps> For the full setup and the list of fields that sync, see [Connect HubSpot](/platform/integrations/hubspot) and [Connect Slack](/platform/integrations/slack). ## Channel detail page Opening a channel shows the channel name and icon plus a roster of every person attributed to it. The roster is the same table you see on the People page, scoped to this channel. You can: * **Filter the roster** by event, job title, or company to slice the audience further. * **Export the roster** to CSV from the table toolbar. * **Edit the channel.** Change its name, icon, or color from the actions menu. * **Delete the channel.** Irreversible. It removes every person's link to this channel. People who still belong to another channel or event stay in your workspace; anyone whose only link was this channel goes with it. ## Sync status and re-sync A channel imported from HubSpot or Slack shows a provider badge and a sync status on its detail page. When a sync needs attention, an alert tells you what to do: * **Sync failed.** The last sync attempt failed. Click **Re-sync** to try again. * **Import failed.** The last import did not finish. Click **Re-sync** to import again. * **Integration disconnected.** The provider was disconnected. Reconnect it on **Settings → Integrations**, then click **Re-sync** to resume. **Re-sync** re-runs the import and pulls the latest contacts or members. Existing people are updated by email, so nothing is duplicated. ## Filter by tag The Channel Attribution chart accepts a tag filter via the URL: `?tagId=N`. Open a tag-scoped channel attribution view, share the URL, and the recipient sees the same filtered comparison. If you open a `?tagId=…` URL for a tag that no longer exists, Path drops the filter and shows the full unfiltered view instead of an error. ## Related * [Attribution model](/path/concepts/attribution-model). How a person gets linked to a channel in the first place. * [Channel Attribution chart](/path/analytics/attribution). Read the multi-channel comparison. * [Audience overlap](/path/analytics/audience). See which channels share people. * [Tags](/path/concepts/tags). Scope analytics to a slice of events. * [Connect HubSpot](/platform/integrations/hubspot). Import your HubSpot contacts as a channel of people. * [Connect Slack](/platform/integrations/slack). Import your Slack members as a channel of people. # Companies Source: https://docs.trytalkvalue.com/path/manage/companies Auto-grouped company directory built from email domains, with override and per-company rollup. The Companies page is your organization directory. TalkValue groups your people into companies automatically by email domain. Every distinct work email domain becomes one company record. From here you can search the directory, override the display name, and open a company to see every person it employs. ## How companies get created TalkValue groups people by their primary email's work domain. Every `@northwind.io` address rolls up under one Northwind company record, every `@acme.com` address under one Acme record. The grouping happens on import, in real time. No separate step. The list page shows three columns: * **Domain.** The raw email domain (e.g. `northwind.io`). This is the identity of the company and cannot be changed. * **Display name.** A human-readable name that overrides the domain in tables and detail pages. Defaults to the domain without its suffix, or to the Company Name from your import when you map that column. * **People.** How many distinct people in your workspace share this domain. Search the directory by typing into the toolbar; the search matches both domain and display name. ## Override the display name The domain is not always the name you want shown. Override it so `linkedin.com` reads "LinkedIn" and `northwind-corp.io` reads "Northwind". You can override the display name from the company detail page. <Steps> <Step title="Open the company"> From the Companies list, click any row to open the detail page. </Step> <Step title="Click Edit"> The **Edit** button is in the page header. A dialog opens with a single Display Name field. </Step> <Step title="Save"> Enter the name you want shown across the app, then click **Save Changes**. The display name updates immediately in the People table, every company panel, and exports. </Step> </Steps> The domain remains the identity; changing display name does not regroup people. To move people between companies, change the source data and re-import. ## Company detail page Opening a company shows the company name, the domain (with a quick link out to the company's website), an auto-fetched logo, and a roster of every person at that company. The roster is the same table you see on the People page, scoped to just this domain. Apply the same event, channel, and job-title filters to narrow the roster to a specific segment of this company's contacts. <Note> **Logos load automatically.** TalkValue fetches a company logo from a public logo service based on the domain. If no logo is available, the page falls back to a neutral building icon. </Note> ## Edge cases * **Work domains only.** TalkValue builds the directory from work email domains, so public-provider addresses like `gmail.com` and `outlook.com` stay with the person and keep your company list focused on real organizations. * **Subdomains.** TalkValue groups by the full domain, so `eng.acme.com` and `acme.com` become two companies. Use the display-name override if you want them to read the same in the UI. * **Renamed companies.** Changing display name does not rename the underlying domain. If a company rebrands their email domain, new sign-ups land under the new domain; historical contacts stay under the old one until you re-import. ## Related * [People, companies, channels, events](/platform/concepts/data-model). Entity primer. * [People](/path/manage/people). Drill in from any company row. * [Events](/path/manage/events). See which events a company attended, indirectly via its people. # Events Source: https://docs.trytalkvalue.com/path/manage/events Create events, tag them, and review per-event attendees from one card grid. The Events page is your event registry inside Path. Every event you've created manually or imported from a connected source. From here you can create new events, tag them for grouped analytics, and open any event to see its attendees. Card status reflects timing automatically: **Upcoming**, **Ongoing**, **Past**. ## Create an event Open **Path → Events** and click **Import Event** to bring one in from Eventbrite or Luma, or use the action on the empty state to create one manually. The manual form opens in a dialog with five fields. <Steps> <Step title="Name the event"> The display name shown across the app. For example `Q2 Customer Day` or `June Product Webinar`. </Step> <Step title="Attach tags"> Pick one or more existing tags, or type a new name and use **Create "…"** to add it on the spot. Tags are how you scope analytics later. See [Tags](/path/concepts/tags) for naming tips. </Step> <Step title="Pick a time zone"> Search the time-zone combobox for the event's location. Time-zone selection is required because Path stores and renders event times in the event's local zone, not the viewer's. </Step> <Step title="Pick a date range"> Click the date picker and select the start (and optionally end) date. Single-day events pick one date; multi-day events pick a range. </Step> <Step title="Optional: location"> Add a venue or city name for display in the event card and detail page. Optional. </Step> </Steps> Click **Create** and the event lands in the Upcoming Events list, ready for attendees. ## Tag events Tags are short labels (`Customer Day`, `Webinar`, `Q2-campaign`) that group related events for filtered analytics. You can attach tags two ways: * **Inline on the event form.** Attach existing tags or create new ones while creating or editing an event. * **Manage tags dialog.** Click **Manage tags** in the Events page header to open the workspace tag library. Create, rename, and delete tags from one place; the changes propagate to every event that carries them. Once at least one event carries a tag, the tag becomes available as a filter on the Path overview, Registration Trend, and Channel Attribution analytics pages. ## Read an event card Each card shows the event's status, its tags, the date range in the event's own time zone, and the location when one is set. Open a card for the full attendee roster. Cards are split into two groups on the page: * **Upcoming Events.** Anything with a start date in the future or currently in progress. * **Past Events.** Anything whose end date has passed (or whose start date has passed if there's no end date). <Note> **Sync status shows on connected events.** Events imported from Eventbrite or Luma render a small status indicator. A FAILED or DISCONNECTED state highlights the card in destructive color so it doesn't get missed. See [Sync status](/platform/concepts/sync-status) for what each state means and how to recover. </Note> ## Event detail Click any event card to open the event page. From there you can: * See the full attendee roster as the same People table, scoped to this event. * Filter the roster by channel, job title, or company. * Export the roster to CSV. * Edit the event (name, tags, timezone, date, location) from the actions menu. * Delete the event. Irreversible. It removes every person's link to this event. People who still belong to another event or channel stay in your workspace; anyone whose only link was this event goes with it. ## Related * [Tags](/path/concepts/tags). Group events for scoped analytics. * [People](/path/manage/people). Drill into the attendee roster. * [Registration trend](/path/analytics/registration-trend). Read net-new vs. returning across all your events. * [Create a Badge event](/badge/events/create). Set up the same event in Badge for on-site check-in. # People Source: https://docs.trytalkvalue.com/path/manage/people Find, edit, merge duplicates, and export your contacts from one table. The People page is your contact database. It holds every person you've imported across every channel and event, deduplicated by email. From here you can search, filter, open a person's detail page to edit them, merge duplicates that slipped through, and export your contacts to CSV. ## Find a person Open **Path → People**. The toolbar above the table is your finder. * **Search.** Type into the search box to match name, email, or phone. * **Event.** Multi-select. Show only people who registered for one of the selected events. * **Channel.** Multi-select. Show only people attributed to one of the selected channels. * **Company Name.** Text filter that matches against the company display name. * **Job Title.** Text filter that matches against job title. Filters combine with AND; every active filter narrows the list further. The table updates as you type; pagination resets to the first page on every change. ## Edit a person Click any row to open the person's detail page. Most fields are inline-editable. Click the value to open an editor, change it, and confirm. Editable fields include: * **Name.** Display name shown in tables and exports. * **Emails.** Primary + secondary. The primary email is the dedupe key (see below). * **Phones.** Multiple phones per person. * **Company.** Pick from an existing company or attach a new one. * **Job title**, **Address**, **LinkedIn**, **X.** Single-value text fields. Changes save when you confirm; the table refreshes the next time you open it. <Note> **Email is the dedupe key.** When TalkValue imports a row with an email that already exists, it updates the existing person by default rather than creating a new one. Changing or deleting the primary email does not undo previously deduplicated records. For that, use Merge. </Note> ## Merge duplicates Sometimes the same person ends up as two records, typically when one record was created from a CSV with `maya.chen@northwind.io` and another came in through Eventbrite as `maya@northwind.io`. The fix is to merge them. <Steps> <Step title="Open the person who should remain"> Open the detail page of the record you want to keep, the target. </Step> <Step title="Start the merge"> Open the actions menu and choose **Merge person**. A search dialog opens. </Step> <Step title="Pick the duplicate"> Search for the duplicate by name or email and select it. TalkValue shows a side-by-side preview: source on the left, target on the right, merged result on the bottom. Single-value fields take the target's value by default; multi-value fields like emails and phones are combined. </Step> <Step title="Confirm"> Use the swap button if you want the source's values to win instead. Click **Merge records**. The source record is removed; every event registration, channel attribution, and activity log from the source rolls up onto the target. </Step> </Steps> A merge history block appears on the target's detail page. You can undo any merge from there; TalkValue restores the source record and unlinks the rollup. ## Export to CSV Click **Export CSV** in the table toolbar to download your contacts. Columns: Name, First Name, Last Name, Email, Emails, Company, Job Title, Phone, Phones, Address, Avatar URL, LinkedIn URL, X URL. The export covers every person in your workspace. To download one channel or one event, open it and use **Export CSV** on its roster; that file also carries a Joined At column. ## Related * [People, companies, channels, events](/platform/concepts/data-model). Entity primer. * [Companies](/path/manage/companies). Review the auto-grouped company a person belongs to. * [Events](/path/manage/events). See which events a person is attached to. * [Import a CSV](/path/import/csv-quickstart). Add more people to this list. # Path quickstart Source: https://docs.trytalkvalue.com/path/quickstart Import a CSV and see your first analytics chart. This quickstart imports a CSV into TalkValue Path and shows your first analytics chart. It takes about ten minutes. If you'd rather pull events and attendees automatically, see [Connect Eventbrite](/platform/integrations/eventbrite) or [Connect Luma](/platform/integrations/luma). <Note> **Before you start** * A TalkValue workspace with an active Pro trial. See [Plans and trial](/administration/billing/plans-trial-pro). * A CSV of contacts with at least an email column (UTF-8, headers in the first row) * 10 megabytes or less of file size </Note> <Steps> <Step title="Open Path and start an import"> Sign in at [app.trytalkvalue.com](https://app.trytalkvalue.com), open **Path** from the left rail, and click **Import Data** from the side panel (or from the empty-state CTA on the Path overview). The import wizard opens with three steps: Upload, Configure, Review. </Step> <Step title="Upload your CSV"> Drop your CSV onto the upload area, or click **Select file** to browse. If you don't have a CSV, click **Download sample template** to get one. It contains the headers TalkValue recognizes automatically. TalkValue analyzes the file and shows the detected columns, total rows, and file size. Click **Continue**. </Step> <Step title="Pick a target and confirm the mapping"> Choose where the contacts go. A **Channel** (a reusable source like `Newsletter` or `LinkedIn`) or an **Event** (a one-time gathering with a date). Pick from the list, or create a new one inline. TalkValue auto-detects headers like `email`, `first_name`, and `company`. Review the **Map Fields** table and pick the right TalkValue field for any unmapped column. **Email** is required. Click **Continue**. </Step> <Step title="Review and start the import"> Confirm the row count, target, and field mapping on the review screen, then click **Start Import**. Progress streams live as the import runs. When it completes, head to **People** in the Path side panel to see the new contacts. Full reference: [Import a CSV](/path/import/csv-quickstart). </Step> <Step title="Open Analytics and read your first chart"> Click **Registration Trend** under Analytics in the Path side panel. Each bar shows registrations per event, split into **Net new** (first-time contacts) and **Returning** (people who registered before). Read the [Registration trend](/path/analytics/registration-trend) page for the chart anatomy and what each segment tells you about your audience. </Step> </Steps> ## What's next <CardGroup> <Card title="Learn the core entities" icon="book" href="/platform/concepts/data-model"> People, companies, channels, and events. What each one tracks and how they connect. </Card> <Card title="Read multi-channel attribution" icon="chart-pie" href="/path/analytics/attribution"> See which channels drove each event's registrations, side by side. </Card> </CardGroup> # Data model Source: https://docs.trytalkvalue.com/platform/concepts/data-model The shared vocabulary behind TalkValue: people, companies, channels, and events, and how Path and Badge each use them. <Note> TalkValue organizes your audience around four entities: **people** belong to **companies**, and people link to **channels** and to **events**. Both products share this vocabulary. Path tracks the audience graph across events; Badge tracks the attendees of a single event. </Note> Path and Badge both organize around people and events, using the same vocabulary. Path imports your contacts and answers audience questions across every event and channel. Badge takes one event's registrations and runs the on-site check-in for it. The four entities below are the shared mental model; each product surfaces the slice it needs. ## People A **person** is one individual in your audience, identified by email. People have a primary email plus optional fields like first name, last name, phone, job title, LinkedIn URL, and address. When TalkValue imports the same email twice, it updates the existing person rather than creating a duplicate. Example: Maya Chen, `maya@northwind.io`, Product Lead at Northwind. She registered for your last two events and is on your monthly newsletter. ## Companies A **company** is the organization a person works for, identified by work email domain. TalkValue groups people automatically by that domain. Every `@northwind.io` address rolls up under one Northwind company record, and you can edit the display name from the company detail page. Example: Northwind has 14 people across three event registrations. Opening the Northwind page shows every Northwind contact in one list. ## Channels A **channel** is a reusable source of registrations, a recurring touchpoint that brings people in. Newsletters, partner referrals, LinkedIn campaigns, and SDR outbound are all channels. Channels persist across events, which is what lets attribution and audience overlap analytics work. Example: a `LinkedIn, Spring campaign` channel brought 230 people in across three events this quarter. ## Events An **event** is a single gathering at a specific time, like a webinar, a meetup, or a conference. Every event has a name, timezone, and start time. Path events also record an end time and a location. Each event has its own attendee count and rolls up into your registration trend, attribution, and audience-overlap charts. Example: `Q2 Customer Day` on May 22 in San Francisco, with 312 registrations attributed across four channels. ## How they relate A person joins channels and registers for events. TalkValue records each link separately, so one person can hold several channel links and several event links at the same time. The person also rolls up to a company by work email domain. The attribution and overlap charts read across those links. ``` Channel ──┐ ├──► Person ──► Company Event ──┘ (email) (domain) ``` ## Related * [Attribution model](/path/concepts/attribution-model). How Path links a registration to its channel. * [Audience overlap](/path/concepts/audience-overlap). What it means when the same person appears in multiple channels. * [Tags](/path/concepts/tags). Group events and channels for scoped analytics. * [Events, attendees, templates](/badge/concepts/events-attendees-templates). How Badge applies people and events to on-site check-in. * [Import a CSV](/path/import/csv-quickstart). Bring your first set of people in. # Sync status Source: https://docs.trytalkvalue.com/platform/concepts/sync-status What PENDING, ACTIVE, FAILED, and DISCONNECTED mean and how to recover from each. <Note> Every synced event and channel has one of four sync statuses: **PENDING** while an import or retry is running, **ACTIVE** while data is flowing live from the provider, **FAILED** when the last sync attempt errored, or **DISCONNECTED** when the integration credential is severed. </Note> TalkValue tracks the health of the link between a synced item and its provider (Eventbrite, Luma, Slack, or HubSpot) with a single sync status. The same four states apply wherever a provider feeds TalkValue: Badge events, Path events, and Path channels. The status drives the badge on the item card, the alert at the top of the detail page, and what recovery action you're offered. Each value maps to a specific recovery action, summarized below. The examples here follow a Badge event. In Path, you recover with the **Re-sync** button in the event or channel header. ## The four states ### `PENDING` An import or re-import job is in progress, or a retry is queued. Attendees are streaming in but the live count may not match the provider yet. You'll see this immediately after **Import Event** or after a **Retry** triggered from a failed event. Wait for the job to finish. The event page shows a progress view while a job is running. **Edge case:** if `PENDING` persists with no active job (the initial import failed before completing), the event page surfaces an **Import failed** alert with a **Retry** button. See [Recovering from disconnect](/badge/events/recovering-from-disconnect). ### `ACTIVE` The integration is healthy and attendee data is syncing live. New registrations, cancellations, and field edits made on the provider side flow through automatically. The event card shows a green **Synced** indicator. In Badge, the event's **Attendees** table auto-refreshes every 30 seconds while this state holds. No action needed. This is the desired steady state during the event window. ### `FAILED` The last sync attempt errored, usually a transient provider issue or a temporary network problem. The event page shows a **Sync failed** alert with a **Retry** button. Click **Retry** in the alert, then **Reconnect with this account** in the dialog to re-run the sync. If it keeps failing across multiple retries, contact support. ### `DISCONNECTED` The integration credential linking this event to its provider has been severed, usually because the workspace admin revoked it on the provider side or the OAuth token expired and was not refreshed. The event page shows an **Integration disconnected** alert with a **Reconnect** button. Recovery: reconnect the provider in **Settings → Integrations**, then return to the event, click **Reconnect**, and confirm with **Reconnect with this account**. Full walkthrough in [Recovering from disconnect](/badge/events/recovering-from-disconnect). ## Where the status appears * **Event list card.** Color-coded badge on each card. * **Event detail page.** Alert banner at the top when status is `FAILED`, `DISCONNECTED`, or `PENDING` without an active job; **Synced** indicator pill in the header when `ACTIVE`. * **Reconnect dialog.** The alert's action button opens a dialog that re-pairs the event with a connected account without leaving the page. It is titled **Reconnect Event**, or **Set Up Sync** when an import stopped partway. ## Recovery summary | Status | What it means | Recovery | | ----------------------- | ------------------------------ | ---------------------------------------------------- | | `PENDING` (job running) | Import or retry in progress | Wait | | `PENDING` (no job) | Initial import failed | **Retry** in the event alert | | `ACTIVE` | Live sync healthy | None | | `FAILED` | Last sync errored | **Retry** in the event alert | | `DISCONNECTED` | Integration credential severed | Reconnect the provider, then **Reconnect** the event | ## Related * [Recovering from disconnect](/badge/events/recovering-from-disconnect). Full reconnect walkthrough for `DISCONNECTED` and stuck `FAILED` states. * [Connect Eventbrite](/platform/integrations/eventbrite). Re-authorize the Eventbrite integration in Settings. * [Connect Luma](/platform/integrations/luma). Reconnect the Luma integration in Settings. * [Add an event](/badge/events/create). Pick a CONNECTED integration when adding a new event. # Connect Eventbrite Source: https://docs.trytalkvalue.com/platform/integrations/eventbrite Authorize Eventbrite once, sync events and attendees into Path and Badge, and manage the connection from Settings → Integrations. Connecting Eventbrite lets TalkValue sync your events and attendees automatically. No CSV exports, no manual uploads. After authorizing access once, anyone in your workspace can import an Eventbrite event into [Path](/path) or [Badge](/badge) with a single click. TalkValue brings in the event and every registrant. <Note> **Before you start** * An Eventbrite account that owns or has access to at least one event. * A TalkValue workspace with an active Pro plan or trial. See [Plans and trial](/administration/billing/plans-trial-pro). </Note> ## Connection model * **One Eventbrite account per workspace.** To switch accounts, disconnect the current one and connect the new one. * **Workspace-scoped.** The connection belongs to the workspace, not to the member who connected it. The authorization flow hands you off to Eventbrite, asks you to grant TalkValue access, and redirects back. What TalkValue receives: * **Read access to your events**: name, start and end time, timezone. * **Read access to your attendees**: every field you collect on the Eventbrite registration form. TalkValue cannot post or edit anything in your Eventbrite account. ## Connect <Steps> <Step title="Open Settings → Integrations"> Sign in at [app.trytalkvalue.com](https://app.trytalkvalue.com), open the side panel, and navigate to **Settings → Integrations**. You'll see a card for each supported provider, including Eventbrite. </Step> <Step title="Click Connect on the Eventbrite card"> Click the **Connect** button on the Eventbrite card. TalkValue opens an authorization flow that hands off to Eventbrite. </Step> <Step title="Authorize TalkValue in Eventbrite"> Sign in to Eventbrite if prompted, then review the requested access and approve. Eventbrite redirects you back to TalkValue automatically. </Step> <Step title="Confirm the connection"> Back in **Settings → Integrations**, the Eventbrite card now shows a green **Connected** badge with the email of the member who connected it and the connection date. You're ready to import. </Step> <Step title="Import an Eventbrite event into Path"> Open **Path → Events** and click **Import Event**. The dialog lists your connected providers. Pick **Eventbrite**, browse your Eventbrite events, and click **Import** next to the one you want. Path imports the event and its attendees. </Step> </Steps> ## What syncs When you import an Eventbrite event, TalkValue brings in: * The **event itself**: name, start time, end time, and timezone. * Every **attendee**: email, name, and the fields Eventbrite collects during registration. ## Status states The Eventbrite card on **Settings → Integrations** is in one of three states: * **Not connected.** The card shows a **Connect** button. Click it to start the authorization flow. * **Connected.** A green **Connected** badge appears in the top right, with the email of the member who connected it and the connection date underneath. The card has an external link to Eventbrite and a **Disconnect** button. * **Reconnect required.** An amber **Reconnect required** badge replaces the green one. The card description reads: *"Authentication expired or revoked. Connect a new Eventbrite account above, then remove this entry."* This state appears when Eventbrite invalidates the token, for example after a password change on Eventbrite, or when the Eventbrite account owner revokes TalkValue access from Eventbrite's app settings. ## Reconnect When the card shows **Reconnect required**, TalkValue keeps the disconnected entry visible so you can finish the cleanup deliberately. Click **Connect** on the connectable Eventbrite card above the disconnected one, run through the Eventbrite authorization again, then click **Remove** on the disconnected entry once the new connection is in place. Events and attendees you already imported stay in your workspace through the disconnect. ## Disconnect On the connected Eventbrite card, click **Disconnect**. A confirmation dialog opens with the message: *"This will remove the connection to your Eventbrite account. You can reconnect at any time, but you'll need to re-import your events."* Confirm to flip the card to the not-connected state. Already-imported events stay in your workspace; new Eventbrite events won't appear until you reconnect. ## Troubleshooting ### The Eventbrite card shows "Reconnect required" The authorization token expired or was revoked from the Eventbrite side. Click **Connect** to reauthorize TalkValue, then remove the disconnected entry. See [Reconnect](#reconnect) for the full pattern. ### An event I expected to see is missing from the import dialog Check that the event is owned by (or shared with) the Eventbrite account you connected. If you have multiple Eventbrite accounts, disconnect and reconnect with the right one. ## Related * [Connect Luma](/platform/integrations/luma). Same flow for Luma. * [Eventbrite field mapping](/platform/integrations/eventbrite-fields). Which Eventbrite fields land in which TalkValue fields. * [Import attendees into Badge](/badge/events/import-attendees). Using the same connection to populate a check-in event. * [Recovering from disconnect](/badge/events/recovering-from-disconnect). What happens to a Badge event when its integration goes into the reconnect state. * [Import a CSV](/path/import/csv-quickstart). The manual import path. * [Attribution model](/path/concepts/attribution-model). How channels attribute registrations to your events. # Eventbrite field mapping Source: https://docs.trytalkvalue.com/platform/integrations/eventbrite-fields How Eventbrite event and attendee fields map into TalkValue entities when you import. When you import an Eventbrite event, TalkValue pulls in two layers: the event itself and every registered attendee. Here's how each field maps. ## Event mapping Each imported Eventbrite event becomes an [Event](/platform/concepts/data-model) in Path. Badge events use the same model. | Eventbrite field | TalkValue field | Notes | | ------------------- | ---------------- | --------------------------------------------------------------------- | | Event name | `event.name` | Visible in the Events list, attribution charts, and audience filters. | | Start date and time | `event.startAt` | Stored with timezone for accurate time-zone-aware charts. | | End date and time | `event.endAt` | Optional in Eventbrite, optional in TalkValue. | | Timezone | `event.timeZone` | Used to display the event's date range in the event's own time zone. | Every attendee Path discovers through this Eventbrite event is linked to that event. Add those people to a channel to see the event in the [Attribution model](/path/concepts/attribution-model). ## Attendee mapping Every Eventbrite attendee becomes a [Person](/platform/concepts/data-model). If a person already exists with the same email, TalkValue updates that record instead of creating a duplicate. | Eventbrite field | TalkValue field | Notes | | ---------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | | Email | `person.email` | The primary identity key. People are deduplicated by email. | | First name | `person.firstName` | Optional. | | Last name | `person.lastName` | Optional. | | Company / Organization | `person.company` *(also rolls up via email domain)* | Path also auto-groups people by work email domain into a [Company](/platform/concepts/data-model) record. | | Job title | `person.jobTitle` | Optional. | | Cell phone | `person.phone` | Optional. | The required Eventbrite fields (name + email) always land in the matching TalkValue fields; optional fields are imported when present. ## Re-import behavior You can re-import the same Eventbrite event. Path updates existing people in place by email, adds new registrants, and refreshes event metadata. TalkValue never deletes people; it merges and updates them. ## What is not imported * **Refunded or canceled registrations.** Only currently valid attendees are pulled in. * **Eventbrite order or payment information.** TalkValue does not store Eventbrite order IDs, ticket types, prices, or transaction history. * **Marketing settings** from Eventbrite (opt-in flags, email subscription state). Manage those separately in your email tool. ## Related * [Eventbrite integration](/platform/integrations/eventbrite). Connection model, status states, reconnect, disconnect. * [Import a CSV](/path/import/csv-quickstart). Manual import path with explicit column mapping. * [Column mapping](/path/import/column-mapping). The CSV-side counterpart for picking which columns map to which fields. * [People, companies, channels, events](/platform/concepts/data-model). The Path entity model the import lands in. # Connect HubSpot Source: https://docs.trytalkvalue.com/platform/integrations/hubspot Connect HubSpot to import your contacts into Path as a channel of people, then manage status, reconnect, and disconnect. Connecting HubSpot lets Path import your HubSpot contacts as people, grouped into a channel that represents your HubSpot portal. Authorize access once, then import with a single click. <Note> **Before you start** * A HubSpot account. * A TalkValue workspace with an active Pro plan or trial. See [Plans and trial](/administration/billing/plans-trial-pro). </Note> ## Connection model * **One HubSpot account per workspace.** To switch accounts, disconnect the current one and connect the new one. * **Workspace-scoped.** The connection belongs to the workspace, not to the member who connected it. The authorization flow hands you off to HubSpot, asks you to grant TalkValue access, and redirects back. TalkValue receives **read access to your contacts**: the fields it maps onto a person. TalkValue cannot post or edit anything in your HubSpot account. ## Connect <Steps> <Step title="Open Settings → Integrations"> Sign in at [app.trytalkvalue.com](https://app.trytalkvalue.com), open the side panel, and navigate to **Settings → Integrations**. You'll see a card for each supported provider, including HubSpot. </Step> <Step title="Click Connect on the HubSpot card"> Click the **Connect** button on the HubSpot card. TalkValue opens an authorization flow that hands off to HubSpot. </Step> <Step title="Authorize TalkValue in HubSpot"> Sign in to HubSpot if prompted, then grant TalkValue read access and approve. HubSpot redirects you back to TalkValue automatically. </Step> <Step title="Confirm the connection"> Back in **Settings → Integrations**, the HubSpot card now shows a green **Connected** badge with the email of the member who connected it and the connection date. You're ready to import. </Step> <Step title="Import your HubSpot portal into Path"> Open **Path → Channels** and click **Import Channel**. In the dialog, pick **HubSpot** and click **Import**. TalkValue confirms that the import has started, and the new channel appears in your Channels list. </Step> </Steps> ## What syncs When you import HubSpot into Path, TalkValue brings in: * Your **HubSpot portal** as a channel, named `HubSpot (<portal ID>)`. * Your **contacts** as people, with these fields: | HubSpot contact | TalkValue person | | --------------- | -------------------- | | Email | Email (identity key) | | First name | First name | | Last name | Last name | | Phone | Phone | | Job title | Job title | | Company | Company | | Profile photo | Avatar | People are matched by **Email** within your workspace. Re-importing the same portal updates existing people in place and adds new ones. Nothing is duplicated. TalkValue also groups people into companies automatically by work email domain. ## Status states The HubSpot card on **Settings → Integrations** is in one of three states: * **Not connected.** The card shows a **Connect** button. Click it to start the authorization flow. * **Connected.** A green **Connected** badge appears in the top right, with the email of the member who connected it and the connection date underneath. The card has an external link to HubSpot and a **Disconnect** button. * **Reconnect required.** An amber **Reconnect required** badge replaces the green one. The card description reads: *"Authentication expired or revoked. Connect a new HubSpot account above, then remove this entry."* This state appears when HubSpot invalidates or revokes access. ## Reconnect When the card shows **Reconnect required**, TalkValue keeps the disconnected entry visible so you can finish the cleanup deliberately. Click **Connect** on the connectable HubSpot card above the disconnected one, run through the HubSpot authorization again, then click **Remove** on the disconnected entry once the new connection is in place. People and channels you already imported stay in your workspace through the disconnect. ## Disconnect On the connected HubSpot card, click **Disconnect** and confirm. Already-imported data stays in your workspace. New contacts won't sync until you reconnect by clicking **Connect** again. ## Troubleshooting ### The HubSpot card shows "Reconnect required" Authentication expired or was revoked from the HubSpot side. Connect a new HubSpot account on the card above, then remove the old entry. See [Reconnect](#reconnect) for the full pattern. ### Some contacts are missing from the import Each contact needs an email, since Email is the identity key. Add an email to the contact in HubSpot, then re-sync. Archived contacts are excluded. ## Related * [HubSpot field mapping](/platform/integrations/hubspot-fields). The full contact-to-person field reference. * [Connect Slack](/platform/integrations/slack). The other channel-import provider for Path. * [Channels](/path/manage/channels). Where imported channels appear and how to re-sync them. * [Import a CSV](/path/import/csv-quickstart). The manual import path. # HubSpot field mapping Source: https://docs.trytalkvalue.com/platform/integrations/hubspot-fields How HubSpot portal and contact fields map into TalkValue channels and people when you import. When you import from HubSpot into TalkValue, the integration pulls in two layers: your portal and every contact inside it. Your portal becomes a channel, and your contacts become people. Here's how each field maps. ## Portal mapping Your HubSpot portal becomes a [channel](/platform/concepts/data-model) in Path. The channel name is `HubSpot (<portal ID>)`. Every contact imported through that channel is attributed to it, so the [Attribution model](/path/concepts/attribution-model) works without extra setup. ## Contact mapping Every HubSpot contact becomes a [Person](/platform/concepts/data-model). People are matched by email within your workspace, so a contact that already exists is updated in place instead of duplicated. | HubSpot field | TalkValue field | Notes | | ------------- | --------------- | -------------------------------------------------------------------------------------------------- | | Email | Email | The identity key. People are matched by email. A contact with no email is not imported. | | First name | First name | Optional. | | Last name | Last name | Optional. | | Phone | Phone | Optional. | | Job title | Job title | Optional. | | Company | Company | TalkValue also groups people into [companies](/platform/concepts/data-model) by work email domain. | | Profile photo | Avatar | Optional. | A contact must have an email to be imported. ## Re-import behavior You can re-import the same HubSpot portal. TalkValue updates existing people in place by email, adds new contacts, and refreshes the channel. TalkValue never deletes people. ## What is not imported * **Archived contacts.** Only active contacts are pulled in. * **Contacts without an email.** Email is the identity key, so a contact with no email is skipped. * **Address.** * **HubSpot deal, lifecycle-stage, marketing, or list data.** TalkValue reads only the contact fields listed above. ## Related * [HubSpot integration](/platform/integrations/hubspot). Connection model, status states, reconnect, disconnect. * [Import a channel from HubSpot](/platform/integrations/hubspot). Connect HubSpot and start the channel import. * [Import a CSV](/path/import/csv-quickstart). Manual import path with explicit column mapping. * [Column mapping](/path/import/column-mapping). The CSV-side counterpart for picking which columns map to which fields. * [People, companies, channels, events](/platform/concepts/data-model). The Path entity model the import lands in. # Connect Luma Source: https://docs.trytalkvalue.com/platform/integrations/luma Connect Luma once, then import events and attendees into Path and Badge, and manage the connection from Settings → Integrations. The Luma integration links your TalkValue workspace to one Luma account. Once connected, anyone in your workspace can import a Luma event into [Path](/path) or [Badge](/badge) in a single click. No CSV exports, no manual uploads. TalkValue brings in the event and every registrant. <Note> **Before you start** * A Luma account that owns or has access to at least one event. * A TalkValue workspace with an active Pro plan or trial. See [Plans and trial](/administration/billing/plans-trial-pro). </Note> ## Connection model * **One Luma account per workspace.** To switch accounts, disconnect the current one and connect the new one. * **Workspace-scoped.** The connection belongs to the workspace, not to the member who connected it. Connecting gives TalkValue read access to your Luma account. What TalkValue receives: * **Read access to your events**: name, start and end time, timezone. * **Read access to your guests**: every field you collect on the Luma registration form. TalkValue cannot post or edit anything in your Luma account. ## Connect <Steps> <Step title="Open Settings → Integrations"> Sign in at [app.trytalkvalue.com](https://app.trytalkvalue.com), open the side panel, and navigate to **Settings → Integrations**. You'll see a card for each supported provider, including Luma. </Step> <Step title="Click Connect on the Luma card"> Click the **Connect** button on the Luma card. TalkValue opens the Luma connection dialog. </Step> <Step title="Complete the Luma connection"> Fill in the connection dialog and submit it. TalkValue returns you to **Settings → Integrations** when the connection is ready. </Step> <Step title="Confirm the connection"> Back in **Settings → Integrations**, the Luma card now shows a green **Connected** badge with the email of the member who connected it and the connection date. You're ready to import. </Step> <Step title="Import a Luma event into Path"> Open **Path → Events** and click **Import Event**. The dialog lists your connected providers. Pick **Luma**, browse your Luma events, and click **Import** next to the one you want. Path imports the event and its attendees. </Step> </Steps> ## What syncs When you import a Luma event into Path, TalkValue brings in: * The **event itself**: name, start time, end time, and timezone. * Every **attendee**: email, name, and the fields Luma collects during registration. For the exact field-by-field map, see [Luma field mapping](/platform/integrations/luma-fields). ## Status states The Luma card on **Settings → Integrations** is in one of three states: * **Not connected.** The card shows a **Connect** button. Click it to start the connection. * **Connected.** A green **Connected** badge appears in the top right, with the email of the member who connected it and the connection date underneath. The card has an external link to Luma and a **Disconnect** button. * **Reconnect required.** An amber **Reconnect required** badge replaces the green one. The card description reads: *"Authentication expired or revoked. Connect a new Luma account above, then remove this entry."* This state appears when the Luma credential stops working, for example after the Luma account owner rotates or revokes it in Luma's settings. ## Reconnect When the card shows **Reconnect required**, TalkValue keeps the disconnected entry visible so you can finish the cleanup deliberately. Click **Connect** on the connectable Luma card above the disconnected one, run through the Luma connection again, then click **Remove** on the disconnected entry once the new connection is in place. Events and guests you already imported stay in your workspace through the disconnect. ## Disconnect On the connected Luma card, click **Disconnect**. A confirmation dialog opens with the message: *"This will remove the connection to your Luma account. You can reconnect at any time, but you'll need to re-import your events."* Confirm to flip the card to the not-connected state. Already-imported events stay in your workspace; new Luma events won't appear until you reconnect. ## Troubleshooting ### The Luma card shows "Reconnect required" The Luma credential stopped working or was revoked from the Luma side. Click **Connect** to reconnect TalkValue, then remove the disconnected entry. Full pattern: [Reconnect](#reconnect). ### An event I expected to see is missing from the import dialog Check that the event is owned by (or shared with) the Luma account you connected. If you have multiple Luma accounts, disconnect and reconnect with the right one. ## Related * [Luma field mapping](/platform/integrations/luma-fields). Which Luma fields land in which TalkValue fields. * [Connect Eventbrite](/platform/integrations/eventbrite). Same flow for Eventbrite. * [Import a CSV](/path/import/csv-quickstart). The manual import path. * [Import attendees into Badge](/badge/events/import-attendees). Using the same connection to populate a check-in event. * [Recovering from disconnect](/badge/events/recovering-from-disconnect). What happens to a Badge event when its integration goes into the reconnect state. * [Attribution model](/path/concepts/attribution-model). How channels attribute registrations to your events. # Luma field mapping Source: https://docs.trytalkvalue.com/platform/integrations/luma-fields How Luma event and guest fields map into TalkValue entities when you import. When you import a Luma event, TalkValue pulls in two layers: the event itself and every registered guest. Here's how each field maps. ## Event mapping Each imported Luma event becomes an [Event](/platform/concepts/data-model) in Path. Badge events use the same model. | Luma field | TalkValue field | Notes | | ------------------- | ---------------- | --------------------------------------------------------------------- | | Event name | `event.name` | Visible in the Events list, attribution charts, and audience filters. | | Start date and time | `event.startAt` | Stored with timezone for accurate time-zone-aware charts. | | End date and time | `event.endAt` | Optional in Luma, optional in TalkValue. | | Timezone | `event.timeZone` | Used to display the event's date range in the event's own time zone. | Every guest Path discovers through this Luma event is linked to that event. Add those people to a channel to see the event in the [Attribution model](/path/concepts/attribution-model). ## Guest mapping Every Luma guest becomes a [Person](/platform/concepts/data-model). If a person already exists with the same email, TalkValue updates that record instead of creating a duplicate. | Luma field | TalkValue field | Notes | | ----------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | | Email | `person.email` | The primary identity key. People are deduplicated by email. | | First name | `person.firstName` | From the guest's first-name field. | | Last name | `person.lastName` | Optional. | | Company | `person.company` *(also rolls up via email domain)* | Path also auto-groups people by work email domain into a [Company](/platform/concepts/data-model) record. | | Job title | `person.jobTitle` | Optional. | | Phone | `person.phone` | Optional. | | LinkedIn | `person.linkedInUrl` | From the LinkedIn registration question. | | X (Twitter) | `person.xUrl` | From the Twitter registration question. | The required Luma fields (name + email) always land in the matching TalkValue fields; optional fields are imported when present. ## Re-import behavior You can re-import the same Luma event. Path updates existing people in place by email, adds new guests, and refreshes event metadata. TalkValue never deletes people; it merges and updates them. ## What is not imported * **Waitlist entries that never got approved.** Only confirmed guests are pulled in. * **Luma payment information.** TalkValue does not store Luma order IDs, ticket types, prices, or transaction history. * **Marketing settings** from Luma (opt-in flags, email subscription state). Manage those separately in your email tool. ## Related * [Luma integration](/platform/integrations/luma). Connection model, status states, reconnect, disconnect. * [Import a CSV](/path/import/csv-quickstart). Manual import path with explicit column mapping. * [Column mapping](/path/import/column-mapping). The CSV-side counterpart for picking which columns map to which fields. * [People, companies, channels, events](/platform/concepts/data-model). The Path entity model the import lands in. # Connect Slack Source: https://docs.trytalkvalue.com/platform/integrations/slack Connect Slack to import your workspace members into Path as a channel, then manage status, reconnect, and disconnect. Connecting Slack lets [Path](/path) import your Slack workspace members as people, grouped into a channel that represents your Slack workspace. Authorize access once, then import with a single click. <Note> **Before you start** * A Slack workspace you can authorize. * A TalkValue workspace with an active Pro plan or trial. See [Plans and trial](/administration/billing/plans-trial-pro). </Note> ## Connection model * **One Slack workspace at a time.** To switch, disconnect the current one and connect another. * **Workspace-scoped.** The connection belongs to the TalkValue workspace, not to the member who connected it. ### Authorization The authorization flow hands you off to Slack, asks you to grant TalkValue access, and redirects back. TalkValue receives **read access to your workspace members**: the fields it maps into a person, such as Email, Name, Phone, Job title, and profile photo. TalkValue cannot post or edit anything in your Slack workspace. ## Connect <Steps> <Step title="Open Settings → Integrations"> Sign in at [app.trytalkvalue.com](https://app.trytalkvalue.com), open the side panel, and navigate to **Settings → Integrations**. You'll see a card for each supported provider, including Slack. </Step> <Step title="Click Connect on the Slack card"> Click the **Connect** button on the Slack card. TalkValue opens an authorization flow that hands off to Slack. </Step> <Step title="Authorize TalkValue in Slack"> Sign in to Slack if prompted, then grant TalkValue read access and approve. Slack redirects you back to TalkValue automatically. TalkValue cannot post or edit anything in your Slack workspace. </Step> <Step title="Confirm the connection"> Back in **Settings → Integrations**, the Slack card now shows a green **Connected** badge with the email of the member who connected it and the connection date. You're ready to import. </Step> <Step title="Import your Slack workspace into Path"> Open **Path → Channels** and click **Import Channel**. In the **Import Channel** dialog, pick **Slack** and click **Import**. Path confirms that the import has started, and the new channel appears in your Channels list. </Step> </Steps> ## What syncs When you import Slack into Path, TalkValue brings in: * Your **Slack workspace** as a channel. The channel name is the Slack workspace name. * Your **Slack members** as people, with these fields: | Slack member | TalkValue person | | ------------- | -------------------- | | Email | Email (identity key) | | Name | Name | | Phone | Phone | | Title | Job title | | Profile photo | Avatar | **Email** is the identity key. For **Name**, TalkValue uses the member's full name; if that is blank, it falls back to the display name, then the username. Members are matched by email within your workspace, so re-importing updates existing people in place and adds new ones. Nothing is duplicated. TalkValue also groups people into companies automatically by work email domain. TalkValue imports active members who have an email. ## Status states The Slack card on **Settings → Integrations** is in one of three states: * **Not connected.** The card shows a **Connect** button. Click it to start the authorization flow. * **Connected.** A green **Connected** badge appears in the top right, with the email of the member who connected it and the connection date underneath. The card has an external link to Slack and a **Disconnect** button. * **Reconnect required.** An amber **Reconnect required** badge replaces the green one. The card description reads: *"Authentication expired or revoked. Connect a new Slack account above, then remove this entry."* This state appears when Slack invalidates or revokes access. ## Reconnect When the card shows **Reconnect required**, TalkValue keeps the disconnected entry visible so you can finish the cleanup deliberately. Click **Connect** on the connectable Slack card above the disconnected one, run through the Slack authorization again, then click **Remove** on the disconnected entry once the new connection is in place. Members you already imported stay in your workspace through the disconnect. ## Disconnect On the connected Slack card, click **Disconnect**. A confirmation dialog opens. Confirm to flip the card to the not-connected state. Already-imported members and channels stay in your workspace; new Slack members won't sync until you reconnect. ## Troubleshooting ### The Slack card shows "Reconnect required" Authentication expired or was revoked from the Slack side. Connect a new Slack account on the card above, then remove the old entry. See [Reconnect](#reconnect) for the full pattern. ### Some members are missing from the imported channel Members without an email are not imported, since email is the identity key. Bots, apps, the Slackbot user, and deactivated members are also skipped. ## Related * [Slack field mapping](/platform/integrations/slack-fields). Exactly how Slack member fields map to TalkValue people. * [Connect HubSpot](/platform/integrations/hubspot). The other channel-import connection for Path. * [Channels](/path/manage/channels). Where imported Slack workspaces appear and sync. * [Import a CSV](/path/import/csv-quickstart). The manual import path. # Slack field mapping Source: https://docs.trytalkvalue.com/platform/integrations/slack-fields How Slack workspace and member fields map into TalkValue channels and people when you import. When you import from Slack into TalkValue, the integration pulls in two layers: your workspace, which becomes a channel, and your members, who become people. Here's how each field maps. ## Workspace mapping Your Slack workspace becomes a channel in Path. The channel name is the Slack workspace name. Every member imported through this connection is attributed to that channel, so the [Attribution model](/path/concepts/attribution-model) works without extra setup. ## Member mapping Each Slack member becomes a person. People are matched by email, so if a person already exists with the same email, TalkValue updates that record instead of creating a duplicate. | Slack field | TalkValue field | Notes | | ------------- | --------------- | ---------------------------------------------------------------------------------------------- | | Email | Email | The identity key. People are matched by email, and a member needs an email to be imported. | | Name | Name | TalkValue uses the member's full name, falling back to the display name and then the username. | | Phone | Phone | Optional. | | Title | Job title | Optional. | | Profile photo | Avatar | Optional. | Slack members have no company field. TalkValue still groups people into [companies](/platform/concepts/data-model) by email domain. ## Re-import behavior You can re-import the same Slack workspace. TalkValue updates existing people in place by email, adds new members, and refreshes the channel. People are never duplicated and never deleted, only updated in place. ## What is not imported * **Deactivated members.** Only active members are pulled in. * **Bots and apps.** Automated users are skipped. * **The Slackbot system user.** This built-in account is never imported. * **Members without an email.** Email is the identity key, so a member needs one to be imported. * **Address.** Slack address details are not stored. ## Related * [Slack integration](/platform/integrations/slack). Connection model, status states, reconnect, disconnect. * [Connect Slack](/platform/integrations/slack). Connect Slack and import a channel from Path. * [Import a CSV](/path/import/csv-quickstart). Manual import path with explicit column mapping. * [People, companies, channels, events](/platform/concepts/data-model). The Path entity model the import lands in. # Digest schedule Source: https://docs.trytalkvalue.com/spark/digest-schedule Set the delivery time and timezone for your daily Slack digest, and turn automatic publishing on or off. The digest schedule decides when Spark posts the day's stories to your Slack channel. The default is 9:00 AM in the America/New\_York timezone. Change the timezone to match where your community lives. <Note> **Before you start** * Slack must be connected and a delivery channel picked. See [Connect Slack](/spark/slack-integration) if you haven't set it up yet. * At least one category must be active. See [Set up categories](/spark/setup-categories). </Note> ## Where the schedule lives The schedule controls live in the **News** page header, not under Settings. Open **News** and look at the digest title. To the right of the title: * **Automatic daily publishing is on.** You'll see an `auto` chip with a pencil icon to edit the time, a **Turn Off** button, and a **Next: `<date and time>`** line showing the upcoming delivery slot. There's no manual publish button in this mode — the digest sends itself on schedule. * **Automatic publishing is off.** You'll see a manual **Publish to Slack** button. It activates once the digest has at least one story; while the digest is empty, the button is disabled with the reason in a tooltip. To switch on automatic delivery, use the schedule prompt in the news view (above the digest). While a publish is in flight (scheduled or manual), the header shows **Publishing to Slack…** and story changes are held until the send completes. ## Set the time and timezone <Steps> <Step title="Open the schedule dialog"> From the News page header, click the pencil icon next to the `auto` chip (when on), or click **Change Time** in the off-state alert to open the schedule dialog. Inside the dialog, click **Enable auto-publish** to save. </Step> <Step title="Pick the hour, minute, and AM/PM"> The dialog uses a 12-hour clock. Minutes are selectable in 15-minute increments: `:00`, `:15`, `:30`, `:45`. </Step> <Step title="Pick the timezone"> The timezone picker lists common timezones (US, Europe, Asia, Australia/NZ) with the current short-name abbreviation alongside each. Search by city to narrow the list. </Step> <Step title="Save"> Click **Enable auto-publish** (first-time setup) or **Save** (changing an existing schedule). Spark recomputes the next delivery slot based on the new time and timezone immediately. </Step> </Steps> ## Defaults New workspaces start with: * **Time:** 9:00 AM * **Timezone:** America/New\_York * **Max items per digest:** 10 Spark caps each digest at 10 stories so the Slack message stays within Slack's per-message size limit. ## Turn off automatic publishing Click **Turn Off** on the News page header to switch back to manual publishing. With auto-publish off, the digest still gets curated daily, but it waits in the News page until you click **Publish to Slack** yourself. Use manual mode when you want to review or edit each day's selection before it goes out. ## Related * [Connect Slack](/spark/slack-integration). Required before any schedule can deliver. * [Set up categories](/spark/setup-categories). Categories drive what's in each scheduled digest. * [Spark quickstart](/spark/quickstart). Full setup flow including the first scheduled delivery. # Spark Source: https://docs.trytalkvalue.com/spark/index Manage and engage your event community across Slack, social channels, and venue displays. Spark helps you build and grow the community around your events. Keep members engaged between events with a daily Slack digest, measure your community's reach across social channels, and bring the conversation onto the venue floor with live displays during your events. ## Three surfaces <CardGroup> <Card title="Slack digest" icon="slack" href="/spark/slack-integration"> A daily message of curated industry news delivered to your community's Slack channel. Pick 1 to 3 categories from 8 to focus the feed. </Card> <Card title="Reach" icon="chart-line" href="/spark/reach/overview"> Track your community's social reach and benchmark against competitors you choose. </Card> <Card title="Walls" icon="tv" href="/spark/walls/overview"> Live Slack channel display for venue TVs, bringing the community conversation into the event itself. </Card> </CardGroup> ## Get started with the Slack digest The Slack digest is the first surface most teams set up. The full quickstart takes about 5 minutes. <Card title="Run the Spark quickstart" icon="rocket" href="/spark/quickstart"> Connect Slack and pick your categories. </Card> # Spark quickstart Source: https://docs.trytalkvalue.com/spark/quickstart Sign in, pick categories, connect Slack, then publish your first curated industry-news digest and set the daily schedule. This walkthrough takes you from an empty Spark workspace to a curated industry-news digest landing in your Slack channel. Most teams finish in under 5 minutes. <Note> **Before you start** * A TalkValue workspace on the Pro plan. Spark is included with TalkValue Pro. * A Slack workspace where you can install apps (or where a workspace admin can approve installs for you). * The Slack channel you want the digest delivered to. </Note> ## Run the full flow <Steps> <Step title="Sign in and start the onboarding wizard"> Sign in at [app.trytalkvalue.com](https://app.trytalkvalue.com) and open Spark. New workspaces open the **Set up your digest** wizard automatically. The first step asks for your community's website URL. Spark analyzes the page to suggest categories that match. </Step> <Step title="Review the suggested categories"> The wizard's analyzer reads your site and pre-selects up to three categories from the eight available. Adjust the picks if needed. Every Spark digest needs at least one category and accepts at most three. See [Set up categories](/spark/setup-categories) for the full list and what each one means. </Step> <Step title="Connect Slack"> The next step opens Slack's OAuth flow. Approve the install (or send the install request to your workspace admin if your Slack workspace restricts third-party apps), then come back to Spark. See [Connect Slack](/spark/slack-integration) for the OAuth screen, the permissions Spark requests, and what each connection state means. </Step> <Step title="Pick the delivery channel"> Once Slack is connected, choose the channel the digest should be posted in. The picker lists every channel Spark can see: public channels by default, private channels once the bot is invited. </Step> <Step title="Watch the first collection run"> Spark starts fetching and ranking stories the moment you save your categories. This usually takes a few minutes. The **News** page shows the collection in progress and switches to the daily digest view once stories are ready. </Step> <Step title="Publish your first digest and set the schedule"> Open **News**, review the stories Spark selected, and click **Publish to Slack**. The **Turn on automatic daily publishing** prompt then appears above the digest. Click **Use Default** to publish every day at 9:00 AM in the **America/New\_York** timezone, or **Change Time** to pick your own hour, minute, and zone. See [Digest schedule](/spark/digest-schedule). </Step> </Steps> ## What's next <CardGroup> <Card title="Set up categories" icon="list" href="/spark/setup-categories"> The eight categories you can pick from, and how to change them later. </Card> <Card title="Connect Slack" icon="slack" href="/spark/slack-integration"> OAuth flow, channel picker, permissions, and connection states. </Card> <Card title="Digest schedule" icon="clock" href="/spark/digest-schedule"> Pick the time and timezone for daily delivery. </Card> <Card title="Reach overview" icon="chart-line" href="/spark/reach/overview"> Measure your community's social reach once the digest is running. </Card> </CardGroup> # Competitor reach Source: https://docs.trytalkvalue.com/spark/reach/competitors Track competitor LinkedIn pages, compare weekly engagement to your own page, and drill into per-competitor post performance. Competitor reach lets you put your LinkedIn page side by side with up to ten competitor pages on weekly engagement, then drill into any one competitor for a deeper post-by-post view. Add competitors by LinkedIn company URL. Spark backfills the last 90 days and refreshes daily. <Note> **Before you start** * Connect Zernio to plot your own LinkedIn page next to the competitors on the comparison chart. See [Reach overview](/spark/reach/overview) for connection setup. * You'll need the LinkedIn company URLs of the pages you want to track (the `https://www.linkedin.com/company/<slug>` form). </Note> ## Add competitors <Steps> <Step title="Open Reach → Competitors"> Open **Reach** in the side panel, then click **Competitors**. The first visit shows an empty state with a **Manage competitors** button that opens the add form. </Step> <Step title="Paste a LinkedIn company URL"> The **Add competitor** form takes a single LinkedIn company URL. Paste it and click **Add competitor**. Spark validates the URL, registers the page, and starts collecting the first snapshot in the background. </Step> <Step title="Repeat up to 10 competitors"> You can track up to **10 competitor pages per workspace**. The header on the add form shows your current count vs. the cap. Remove a page to free a slot. </Step> </Steps> ## Read the competitor list Once you have one or more competitors registered, the page shows: * **Competitor card grid.** One card per competitor showing **Posts (90d)**, **Likes (90d)**, **Comments (90d)**, and **week-over-week engagement change**. * **Comparison chart.** A multi-line chart of weekly engagement across the last 90 days. Your LinkedIn page is plotted alongside every competitor on the same axis, so you can read relative performance at a glance. ## Per-competitor deep dive Click any competitor card to open the deep-dive page at `/reach/competitors/<pageId>`. The deep dive shows: * **KPI strip.** Four 90-day metrics: **Posts**, **Avg likes per post**, **Avg comments per post**, and **Top engagement**. * **Posting cadence chart.** How many posts the page publishes each week. * **Engagement trend chart.** Weekly engagement for that page in isolation. * **Top posts list.** The best-performing original posts and reposts. * **Post type donut.** Distribution of post formats (text, image, video, document). * **All posts table.** Paginated full list of posts collected in the window. ## Refresh cadence Spark refreshes competitor data daily at 06:00 UTC. New competitors get a 90-day backfill on first add. Expect the first snapshot to land within an hour. ## Remove a competitor Open **Manage competitors** from the Competitors page header. Each row has a remove action. Confirming removes the page and its historical data from the comparison chart immediately. ## Related * [Reach overview](/spark/reach/overview). Your own platform metrics on one page. * [Spark quickstart](/spark/quickstart). Full Spark setup if you're starting from scratch. # Reach overview Source: https://docs.trytalkvalue.com/spark/reach/overview Track your community's social reach: followers, posts, engagement, weekly trend, and per-platform breakdown on one page. Reach measures how your community's social presence is performing across the platforms you operate. It pulls metrics from your connected social accounts, rolls them up into one dashboard, and lets you scope the date range to spot trends. The page is titled **Insights** in the app, under the **Reach** section of the side panel. <Note> **Before you start** Reach requires a Zernio connection. Zernio is the social-data provider that powers the metrics on this page. Connect it from **Settings → Integrations → Zernio**. </Note> ## What you see The page is laid out top to bottom in five sections, each answering a specific question. ### Pulse KPIs **Four stat cards at the top:** **Followers**, **Posts published**, **Reach**, and **Engagement**, each with the current period's value and a delta vs. the previous period. The delta arrow is positive (up) or negative (down) depending on the comparison. ### Top posts A ranked list of the best-performing posts in the active date range, scored by **likes + comments + shares**. Useful for spotting what landed and reusing that angle. ### Weekly trend chart **A stacked bar chart** showing engagement per platform over the last 8 weeks. This chart is independent of the page-level period filter. Hover any week to see the absolute number for that week. ### Per-platform grid One card per connected platform (LinkedIn, X, Instagram, and so on), each showing the platform's **Followers**, **Posts**, **Reach**, and **Engagement** for the period, plus a small 8-week engagement sparkline. Use this when one channel is masking weakness in another within the rolled-up KPI cards. ### Recent activity A paginated, all-time list of the latest posts across connected platforms with engagement counts (most recent first). Click any row to open the original post. ## Change the date range The scope selector in the top-right of the page header lets you pick the comparison window. The default is the last 30 days. Picking a different scope re-fetches every section on the page. ## Empty and not-yet-synced states * **No connection.** Reach shows a connect prompt when Zernio has never been linked. Open **Settings → Integrations → Zernio** to set it up. * **First sync running.** Reach shows a **First sync in progress** state while the first Zernio pull runs. This usually takes a minute or two. * **Connected but no data.** Some accounts post infrequently or are brand new. Wait for the next sync window. Zernio refreshes on its own schedule. ## Related * [Competitor reach](/spark/reach/competitors). Benchmark your numbers against competitor LinkedIn pages. * [Spark quickstart](/spark/quickstart). Full Spark setup if you're starting from scratch. # Set up categories Source: https://docs.trytalkvalue.com/spark/setup-categories Pick 1 to 3 of the 8 categories that match your community. What each one covers, and how to change them later. Every Spark digest is built around the categories you select. Pick at least one and at most three. Three is the maximum because more categories dilute the daily ranking and the digest becomes noisy. Categories are grouped into three families and you can mix freely across families. ## The eight categories ### Technology * **AI & Machine Learning.** Artificial intelligence, machine learning models, LLMs, and real-world AI applications. * **Developer Tools.** Frameworks, CLIs, IDEs, open-source projects, and tooling that improve developer productivity. * **Data & Analytics.** Data engineering, analytics workflows, databases, and practical insights from metrics. * **Knowledge Graphs.** Knowledge graphs, ontologies, taxonomies, semantic web, linked data, graph databases, entity resolution, and knowledge representation. ### Events & Marketing * **Events & Community.** Event technology, conferences, exhibitions, trade shows, community building, community-led growth, hybrid events, attendee experience, and event platforms. * **AI & Marketing.** AI tools for marketers, AI agents, marketing automation, generative AI for content, personalization engines, MarTech, and AI-powered analytics and attribution. ### Business & Growth * **Startups & Business.** Startup execution, product strategy, developer careers, hiring, and the business of technology. * **Creator & Growth.** Creator economy, community monetization, audience growth, no-code automation, content strategy, newsletter growth, and event marketing ROI. ## Pick your first set During onboarding, Spark analyzes the website URL you provide and pre-selects up to three categories that match. Review the picks, add or remove as needed, then continue. If you skip the website analysis or want to start over, the picker opens with no categories selected. Pick at least one. The digest cannot run without an active category. <Note> **One to three is the hard limit.** The picker hides the remaining categories once you reach three and disables the remove button once you reach one. This is intentional: the digest ranker compares stories across your active categories, and too many categories produce a thin, repetitive feed. </Note> ## Change categories later Open the **News** page, then **Manage sources**. The same picker opens. Add or remove categories and save. The next collection cycle uses the updated set, and the change reflects in the next morning's digest. Sources are derived from your categories automatically. Each category brings a curated bundle of trusted publication sources (industry blogs, subreddits, arXiv categories, news sites) so you don't have to manage source URLs yourself. ## Related * [Spark quickstart](/spark/quickstart). Full setup flow. * [Connect Slack](/spark/slack-integration). Connect the workspace and channel that receives the digest. * [Digest schedule](/spark/digest-schedule). Set the delivery time after categories are live. # Connect Slack Source: https://docs.trytalkvalue.com/spark/slack-integration OAuth flow, channel picker, required permissions, and what each connection status means. The Slack connection delivers each daily digest to your workspace. Connect once at the workspace level, then pick the channel the daily digest is posted to. <Note> **Before you start** * You need permission to install apps in your Slack workspace, or a workspace admin who can approve the install for you. * Pick the destination channel ahead of time. Spark posts to one channel per workspace. </Note> ## Connect the workspace <Steps> <Step title="Open Settings → Integrations → Slack"> From the dashboard, open **Settings**, then **Integrations**, then **Slack**. The status card shows **Connect Slack** when no workspace is linked. </Step> <Step title="Click Connect Slack Workspace"> The button opens Slack's OAuth flow in a new tab. Sign in to Slack if prompted. </Step> <Step title="Approve the install"> Slack lists the permissions Spark requests (see below) and asks you to approve. If your workspace restricts third-party app installs, Slack shows a **Request to install** screen instead. Submit the request and ask a workspace admin to approve it. </Step> <Step title="Confirm the connection"> Once Slack confirms the install, your browser is redirected back to the Slack settings page in Spark. The status card now shows the workspace name and a **Connected** indicator. </Step> </Steps> ## Pick the delivery channel The channel picker appears below the workspace card once Slack is connected. Open it, then pick the channel the digest should be posted in. Spark loads the channel list lazily, so the first open may take a second while it fetches your workspace's channels. You can change the channel at any time from the same picker. Spark immediately posts subsequent digests to the new channel. ## Required permissions Spark requests these Slack OAuth scopes during the install: * **`chat:write`**: Post the daily digest message to the selected channel. * **`chat:write.public`**: Post to public channels without Spark being invited first. * **`channels:read`**: List public channels in the channel picker. * **`groups:read`**: List private channels Spark has been invited to. * **`channels:history`** and **`groups:history`**: Receive new messages from the channels Spark mirrors on a [wall](/spark/walls/overview). * **`im:write`**: Send announcements as direct messages to workspace members. * **`users:read`**: Look up display names so upvotes and wall messages show real names instead of raw Slack user IDs. ## Status states The Slack settings card shows one of five states. Each state suggests the action that moves you forward. * **`disconnected`**: No workspace is linked. Click **Connect Slack Workspace** to start the OAuth flow. * **`approval_required`**: Slack told us your workspace admin must approve the install before it completes. Send the install request from Slack's approval screen, then retry from the Spark settings card. * **`connected_unconfigured`**: Workspace is linked but no delivery channel is picked. Use the channel picker to choose one. Digests will not publish until this is set. * **`ready`**: Workspace is linked, a channel is picked, and Spark can deliver. No action needed. * **`invalid`**: The bot token was revoked or expired. This happens when a workspace admin removes the app on Slack's side. Click **Reconnect Slack Workspace** to re-authorize. ## Reconnect or disconnect Click **Reconnect Slack Workspace** from the `invalid` state to re-run the OAuth flow. The new install replaces the previous credential without losing your channel selection. Click **Disconnect** from any connected state to remove the link. Digests pause until you reconnect. Reconnecting to the same Slack workspace restores your channel selection; connecting a different workspace opens the channel picker for a fresh choice. ## Related * [Set up categories](/spark/setup-categories). Pick the topics that drive what gets curated for the channel. * [Digest schedule](/spark/digest-schedule). Set the time the digest hits the channel each day. * [Spark quickstart](/spark/quickstart). Full setup walkthrough. # Create a wall Source: https://docs.trytalkvalue.com/spark/walls/create-wall Pick the Slack channel, set event branding, and generate the public display URL. The full form reference. A wall mirrors one Slack channel and produces one public display URL. Create a fresh wall for each event you want to project. The channel pick is locked once the wall is created, so a different event gets a different wall. <Note> **Before you start** * Slack must be connected. See [Connect Slack](/spark/slack-integration). * The Spark bot must be a member of the channel you want to mirror, so invite it before you create the wall. The channel picker lists joined channels first and marks the rest with `· invite Spark first`. </Note> ## Open the create form <Steps> <Step title="Open Walls in the side panel"> From the dashboard, open **Walls**. The page lists every wall in the workspace. </Step> <Step title="Click Create wall"> The button opens the create form. The form pre-loads the channels the Spark bot can see in your Slack workspace. </Step> </Steps> ## Fill out the form The form fields: * **Slack channel** *(required)*. Pick the channel to mirror. Each entry shows the channel name, a lock icon for private channels, and an `· invite Spark first` hint for channels the bot hasn't been invited to yet. The pick is permanent on the wall, so create a new wall to mirror a different channel. * **Event name** *(required)*. The title shown on the wall. Up to 120 characters. * **Venue / date** *(optional)*. A short subtitle under the title. Useful for venue name and date range. Up to 160 characters. * **QR target URL** *(optional)*. Where the on-wall QR code points. Common targets: a Slack invite URL, a Discord invite, an event landing page. Must be a valid URL. * **QR label**. Fixed to `Scan to join` when you create the wall. You can change it later from the wall's **Settings** page (max 40 characters). * **Logo image URL** *(optional)*. A public URL to your event or sponsor logo. Must be a valid URL. * **Theme** *(required, defaults to `clean_slate`)*. Visual style. Four presets: * `clean_slate`: neutral, professional default. * `graphite`: high-contrast dark gray. * `claude`: warm cream and orange. * `ocean_breeze`: blue and teal. * **Dark mode** *(toggle, on by default)*. Inverts each theme for low-light venue use. ## Save and pick up the URL Click **Create wall**. Spark generates a random display token, persists the wall, and routes you to the wall detail page. The detail page shows the public URL plus a QR code that encodes the URL for easy phone capture. The wall is immediately live. Open the URL on any browser and the channel's last 50 messages render. New messages flow in as they arrive. ## Edit a wall later Open **Walls**, then click **Settings** on the row for the wall you want to change. From the wall detail page you can update the branding fields, regenerate the display token, or delete the wall entirely. ## Related * [Walls overview](/spark/walls/overview). What walls are and when to use one. * [Display mode](/spark/walls/display-mode). Open the URL on a venue TV. * [Connect Slack](/spark/slack-integration). Wall creation depends on a live Slack connection. # Display mode Source: https://docs.trytalkvalue.com/spark/walls/display-mode Open the public wall URL on a venue TV browser. Get the URL, go fullscreen, and let the live Slack feed run. A wall's display mode is a webpage at a public URL. Open it in any modern browser on the device driving the screen, go fullscreen, and the wall renders the live Slack feed. <Note> **Before you start** * The wall must already exist. See [Create a wall](/spark/walls/create-wall). * The TV or kiosk device needs internet access and a modern browser. Chrome, Safari, or Edge all work. </Note> ## Open the wall on the TV <Steps> <Step title="Copy the display URL from the wall detail page"> Open **Walls** in the Spark dashboard, then click **Settings** on the wall you want to display. The wall detail page shows the public URL in a copy field plus a QR code that encodes the same URL. </Step> <Step title="Send the URL to the TV device"> Use whatever channel you normally use for venue setup: email it to the AV team, message it in a setup Slack channel, paste it into a kiosk-management tool, or scan the QR with the TV's connected phone and share-to-browser. </Step> <Step title="Open the URL in a browser on the TV"> The page loads with the wall's branding and the channel's most recent 50 messages already rendered. New messages animate in as they arrive in Slack. </Step> <Step title="Go fullscreen"> Use the browser's fullscreen command: `F11` on Windows or Linux, `Control + Command + F` in Safari, the fullscreen menu item in Chrome. The address bar and tabs hide so the screen reads as a venue display rather than a webpage. </Step> </Steps> ## How the live feed stays connected The wall page keeps an open connection to TalkValue that pulls new messages within seconds of them arriving in Slack. Each connection holds for up to 25 minutes, then the page reconnects automatically, so you don't need to refresh during an event. If the TV's network drops, the page reconnects on its own when connectivity returns. The last 50 messages always re-render from the server snapshot so you don't see a gap on screen. ## Troubleshooting * **The wall shows no messages.** Confirm the Spark bot is a member of the mirrored Slack channel. Once you invite it, messages start mirroring from that point. * **The screen goes blank or stops updating.** The page reconnects on its own when connectivity returns; no action needed. * **The address bar still shows.** Re-issue the browser's fullscreen command. On a kiosk device, set the browser to launch in fullscreen or kiosk mode. ## QR-to-join pattern Many event walls include a QR that attendees scan to join the Slack workspace or a related space. Set the target when you create the wall, and set the label from the wall's **Settings** page: * **QR target URL.** Paste your Slack invite URL or community signup link. * **QR label.** A short call to action. New walls use `Scan to join`; change it from **Settings** (up to 40 characters). Attendees scan the QR with their phone camera and land on the destination. No app install needed. ## No login required The display URL is public. Anyone with the URL can view it, with no Spark or Slack login. That means: * You can hand the URL to an AV team or contractor without provisioning accounts. * You should not paste the URL into public chats or social posts. It bypasses your dashboard's access controls. * If a URL leaks, regenerate the display token from the wall settings. The old URL stops working immediately. ## Related * [Walls overview](/spark/walls/overview). What walls are and how the live feed works. * [Create a wall](/spark/walls/create-wall). Set the channel and branding before display mode. # Walls overview Source: https://docs.trytalkvalue.com/spark/walls/overview Live Slack channel display for venue TVs. Mirror one Slack channel to a public, no-login URL you can open on any screen. Walls turn a Slack channel into a venue-ready display. Each wall mirrors exactly one Slack channel: as messages arrive in Slack, they animate onto a fullscreen page you can open on any TV browser, projector, or kiosk. The page is at a public URL with a unique token (`/w/<displayToken>`). No login required to view it, so you can hand the URL to an AV team or load it on a TV without an admin signing in. ## When to use a wall * **Conference day.** Show the official event Slack channel on a sponsor TV so attendees see live questions, talk reactions, and announcements. * **Hackathon.** Point a wall at the `#submissions` channel so the room sees teams check in as they finish. * **User group meetup.** Project the `#meetup-chat` channel during talks so remote and in-room conversations mix. Walls are designed for short, event-day runs. Each wall is per-event, and you can delete it when the event is over. ## How a wall stays live Each wall keeps an open connection to TalkValue. When a new Slack message arrives in the mirrored channel, the page animates the message in within seconds. Deleting a message in Slack removes it from the wall over that same connection. The connection holds for up to 25 minutes per session, then the page reconnects automatically, so long-running displays don't need a manual refresh cycle. ## Branding a wall Each wall has its own branding controls: event name, venue/date line, optional logo image URL, optional QR code with a custom label, four theme presets, and a dark-mode toggle. Pick the combination during creation and update anytime from the wall's settings page. See [Create a wall](/spark/walls/create-wall). ## Public URL safety The wall URL contains a random display token, so the page is not discoverable from a directory or by guessing. If you ever need to invalidate a URL (for example, an old TV is still pointed at it after an event), regenerate the token from the wall settings. The old URL stops working immediately and a new one takes its place. ## Related * [Create a wall](/spark/walls/create-wall). The form fields and Slack channel pick. * [Display mode](/spark/walls/display-mode). Open the wall on a venue TV.