---
title: Core concepts
description: Understand sites, visitors, surveys, events and the decisions that make a survey appear.
url: https://docs.userreason.com/get-started/concepts/
updated: 2026-10-16
---

# Core concepts

UserReason asks for feedback inside your app. Your app supplies context and reports actions; a published survey decides what to ask, who to ask and when.

## Workspaces and sites

A **workspace** groups your team's sites and access permissions. A **site** is one integration with its own public site ID, surveys, events and visitors. Initialize the SDK with the site ID. Keep development and production in separate sites so testing does not affect real visitors or responses.

A site's allowed origins can restrict which browser origins use it. Origins include the scheme, hostname and port, such as `https://app.example.com`. A public site ID provides no management access.

## Visitors and identity

The SDK starts with an anonymous visitor. Use [identify()](https://docs.userreason.com/sdk/identity/index.md) after sign-in to associate activity with your application's account ID, and `reset()` on sign-out. **Traits** describe the visitor, such as their plan; **event properties** describe one occurrence, such as an export's format.

Browser-supplied IDs and traits can be changed by the visitor. Backend assertions provide verified identity and traits when targeting requires trusted facts.

## Surveys and publishing

A **survey** combines questions and presentation with audience, triggers, sampling and frequency rules. Its management ID is the campaign ID; SDK notifications and responses use `surveyId` for the underlying question set.

The app calls these **surveys**. Existing technical names stay the same: use the `userreason prompt` CLI commands, the `prompt_*` MCP tools, and API fields such as `prompt_id`. In a question definition, `prompt` is the question text. Documentation addresses under `/prompts/` also stay the same.

Creating or updating a draft does not change what visitors see. **Publish** makes the draft live. **Pause** stops delivery, **resume** enables it again, and **archive** retires it. Existing responses retain the question version that was shown.

See [Your first survey](https://docs.userreason.com/get-started/first-prompt/index.md) for the complete flow, or [Survey definition](https://docs.userreason.com/prompts/definition/index.md) for the JSON format.

## When a survey appears

| Decision | Question it answers | Example |
| - | - | - |
| Trigger | Is this a suitable moment? | After `onboarding.completed` |
| Audience | Does this visitor qualify? | The visitor has the `pro` plan |
| Sampling | Is this visitor in the selected cohort? | Ask 10% of eligible visitors |
| Frequency | Has this visitor already been asked enough? | At most one completed response |
| Display availability | Can the SDK show it now? | No other UserReason survey is open |

These checks work together. An event can be recorded even when no survey appears. A published survey can also be ineligible for the current visitor. [Targeting and frequency](https://docs.userreason.com/prompts/targeting/index.md) explains each check.

## Three different SDK actions

- [event()](https://docs.userreason.com/sdk/events/index.md) reports a fact from your app and checks matching event triggers.
- [show()](https://docs.userreason.com/sdk/show/index.md) requests one particular survey using a page-load opportunity. Its rules still apply.
- [on()](https://docs.userreason.com/sdk/notifications/index.md) listens for SDK notifications such as `shown`, `submitted` and `error`.

Sending an application event and listening for an SDK notification are separate operations. A successful `ready()` means configuration and a visitor session loaded; it does not mean a survey should appear.
