> ## Documentation Index
> Fetch the complete documentation index at: https://docs.worldvisagroup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How do contexts work in WorldVisa?

> Learn how contexts work in WorldVisa, how they differ from payloads, and how they scope, personalize, and filter notifications across workflows and Inbox.

A *context* is user-defined metadata you attach when triggering a workflow. Contexts let you scope, personalize, and filter notifications without duplicating subscribers, workflows, or templates.

Common context types include `tenant`, `app`, `region`, or any key that matches your product model. Each context entry is either a simple identifier or a rich object with an `id` and optional `data` fields.

![WorldVisa contexts feature showing tenant-scoped notification isolation in the dashboard](https://mintcdn.com/wv-enterprise/l3bkwl1N_3mOn9aW/images/developers/inbox/Contexts.png?fit=max\&auto=format\&n=l3bkwl1N_3mOn9aW\&q=85\&s=a4ce939968ecb928b59953258712906a)

## How contexts fit into WorldVisa's model

When you [trigger](https://docs.worldvisagroup.com/developers/concepts/trigger.md) a workflow, you pass:

* A **subscriber** (who receives the notification)
* A **payload** (event-specific data for this run)
* An optional **context** (shared metadata that scopes and personalizes the notification)

Contexts are persistent. Unlike a payload, which exists only for a single workflow execution, context data is stored in WorldVisa and reused across triggers, templates, the Inbox, and the Activity Feed.

> [!NOTE]
>
> You can pass up to five context keys per trigger. Each context `data` object is limited to 64KB. See [Manage contexts](https://docs.worldvisagroup.com/developers/workflow/advanced-features/contexts/manage-contexts.md) for schema details.

## Context vs payload

| | Payload | Context |
| - | - | - |
| **Scope** | Single workflow execution | Persistent across triggers |
| **Typical use** | Order ID, message text, action URL | Tenant name, app branding, region |
| **In templates** | `{{payload.field}}` | `{{context.tenant.data.name}}` |
| **Inbox filtering** | Not used for scoping | Exact-match filtering |
| **Auto-created** | No | Yes, on first reference |
| **Data upsert on reuse** | No | Yes on workflow trigger when `data` is provided; no on Inbox |

Use the payload for data that changes on every event. Use context for metadata that defines *where* or *for whom* a notification belongs.

## Context structure

Each key in the `context` object is a context type. WorldVisa supports three formats per key:

```ts theme={null}
context: {
  // Simple string: type and id only
  tenant: "acme-corp",

  // Object with id
  app: { id: "billing" },

  // Object with id and metadata
  region: {
    id: "us-east",
    data: {
      name: "US East",
      timezone: "America/New_York",
    },
  },
}
```

Contexts are **auto-created** the first time WorldVisa sees them (via a workflow trigger or the Inbox).

During **workflow triggers**, existing context `data` is **upserted** when you include a `data` object inline - similar to subscriber fields. Passing only a string identifier (for example, `tenant: "acme-corp"`) references the context without changing stored `data`.

**Inbox** and other subscriber-facing APIs only find or create contexts and do **not** update existing `data`. You can also manage context data through the Contexts API or the WorldVisa dashboard.

## What you can use contexts for

> [card] [Multi-tenancy](https://docs.worldvisagroup.com/developers/concepts/tenants.md)
>
> Isolate notifications per organization, workspace, or customer using a `tenant` context, without prefixing subscriber IDs or duplicating workflows.

> [card] App or feature scoping
>
> Route notifications to the right Inbox by scoping with an `app` or feature key when one subscriber uses multiple products.

> [card] [Dynamic branding](https://docs.worldvisagroup.com/developers/workflow/advanced-features/contexts/contexts-in-workflows.md)
>
> Store logos, colors, and plan names in context `data` and reference them in templates with `{{context}}`.

> [card] [Conditional workflow logic](https://docs.worldvisagroup.com/developers/workflow/add-and-configure-steps/step-conditions.md)
>
> Branch workflow steps based on context values, such as sending enterprise-only emails when `context.tenant.data.plan` is `enterprise`.

> [card] [Provider routing](https://docs.worldvisagroup.com/developers/integrations/integration-conditions.md)
>
> Select a tenant-specific email, SMS, chat, or push integration with conditions on `context.tenant.id`.

## How context scoping works

### In workflows and templates

Context data is available in every template editor through the `{{context}}` helper. The same paths work in [step conditions](https://docs.worldvisagroup.com/developers/workflow/add-and-configure-steps/step-conditions.md).

```liquid theme={null}
Welcome to {{context.tenant.data.name}}! Your {{context.tenant.data.plan}} plan is active.
```

### In the Inbox

The Inbox uses **exact-match** filtering. The `context` prop on `<Inbox />` must match the context used at trigger time, key for key and value for value. Notifications triggered with a tenant context only appear in an Inbox initialized with the same tenant context.

| Workflow context | Inbox context | Displayed? |
| - | - | - |
| `{ tenant: "acme" }` | `{ tenant: "acme" }` | Yes |
| `{ tenant: "acme" }` | `{ tenant: "globex" }` | No |
| `{ tenant: "acme" }` | `{}` | No |

When a subscriber switches tenants in your app, re-render the Inbox with the new context. WorldVisa refetches notifications and reconnects the WebSocket scope automatically.

> [!WARNING]
>
> Because `context` is set on the client, secure it with `contextHash` in production. See Inbox with context.

## Trigger a workflow with context

```bash theme={null}
curl -L -g -X POST "${WV_API_URL}/v1/events/trigger" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H "Authorization: ApiKey ${WV_API_KEY}" \
-d '{
    "name": "invoice-paid",
    "to": { "subscriberId": "user-123" },
    "payload": { "amount": "$250" },
    "context": {
        "tenant": {
            "id": "acme-corp",
            "data": {
                "name": "Acme Corporation",
                "plan": "enterprise"
            }
        }
    }
}'
```

## Next steps

> [card] [Multi-tenancy](https://docs.worldvisagroup.com/developers/concepts/tenants.md)
>
> Implement tenant isolation with contexts end to end.

> [card] [Manage contexts](https://docs.worldvisagroup.com/developers/workflow/advanced-features/contexts/manage-contexts.md)
>
> Create, update, and delete contexts through the API or dashboard.

> [card] [Contexts in workflows](https://docs.worldvisagroup.com/developers/workflow/advanced-features/contexts/contexts-in-workflows.md)
>
> Personalize templates and add conditional logic with context data.

## Frequently asked questions

> [accordion] Should I create and update contexts ahead of time or pass context data on every trigger?
>
> Both patterns are supported.
>
> **Inline on workflow trigger (server-side):** When you trigger a workflow with a rich context object that includes `data`, WorldVisa creates the context if it is missing or replaces stored `data` if it already exists. This works like subscriber upsert and is useful when your backend already has the latest tenant metadata at trigger time. Pass only the context `id` as a string when you want to reference existing data without changing it.
>
> **Ahead of time via API or dashboard:** Create contexts with initial `data` before you need them, then update context data when metadata changes (for example, tenant name or plan). Use this when you want a single source of truth outside of triggers.
>
> **Inbox:** Session initialization can auto-create missing contexts but never updates existing context `data`. Do not rely on the Inbox to refresh tenant metadata.
>
> Recommended approach for multi-tenant apps:
>
> 1. Create the context with initial `data` before you need it, or pass `data` on your first server-side trigger.
> 2. Keep metadata current through [workflow triggers with inline `data`](https://docs.worldvisagroup.com/developers/workflow/trigger-workflow#trigger-a-workflow-with-context), the Contexts API, or the dashboard.
> 3. Pass only context keys and `id` values to the Inbox unless you are creating a context for the first time.

> [accordion] Why are notifications sent but not showing in the Inbox after I added context?
>
> Inbox notifications are scoped per context. If you trigger a workflow with `context` but initialize `<Inbox />` without the same context (or vice versa), the notification will not appear in that Inbox session, even though the in-app job may report success.
>
> Pass the same context to both your workflow trigger and the Inbox `context` prop. See Inbox with context for the matching rules and troubleshooting steps.


## Related topics

- [How do subscribers work in WorldVisa?](https://docs.worldvisagroup.com/developers/concepts/subscribers.md)
- [How do workflows work in WorldVisa?](https://docs.worldvisagroup.com/developers/concepts/workflows.md)
- [How WorldVisa Console works](https://docs.worldvisagroup.com/developers/how-worldvisa-console-works.md)
- [Multi-tenancy](https://docs.worldvisagroup.com/developers/concepts/tenants.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.