snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-17 23:28:13 +05:00
commit e7da97194a
32688 changed files with 4208681 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
---
title: AI Agents
description: Integrate AI capabilities directly into your automation workflows.
---
## Overview
Integrate AI capabilities directly into your automation workflows for intelligent data processing and decision-making.
## Capabilities
| Feature | Description |
|---------|-------------|
| **AI actions** | Add AI-powered steps to any workflow |
| **Data enrichment** | Automatically enhance records with external data |
| **Classification** | Categorize records based on content analysis |
| **Summarization** | Generate summaries from text fields |
| **Custom prompts** | Define exactly how AI processes your data |
## Use Cases
- **Lead scoring**: Automatically score and prioritize inbound leads
- **Data cleanup**: Standardize company names and contact information
- **Email drafts**: Generate follow-up emails based on meeting notes
- **Record routing**: Assign records to the right team member based on content
## Related
- [Workflows Overview](/user-guide/workflows/overview) — automation basics
- [AI Permissions](/user-guide/ai/capabilities/permissions-access-control) — access control for AI agents

View File

@@ -0,0 +1,35 @@
---
title: AI Chatbot
description: An intelligent assistant that helps you interact with your CRM data using natural language.
---
## Overview
Ask questions in natural language and the assistant retrieves and explains your CRM data for you.
## Capabilities
| Feature | Description |
|---------|-------------|
| **Natural language queries** | Ask questions in plain English instead of building filters |
| **Full data access** | Query records, relationships, and metrics across your workspace |
| **Page context** | Reference "this company" or "this opportunity" based on your current view |
| **Conversational** | Follow-up questions maintain context from previous queries |
## Example Interactions
### Finding Records
- "Show me all opportunities over $50,000"
- "Find contacts I haven't emailed in 2 weeks"
- "List companies in the healthcare industry"
### Getting Insights
- "What's my total pipeline value?"
- "How many deals closed last month?"
- "Which stage has the most stuck opportunities?"
### Using Page Context
- "Summarize my interactions with this person" (on a contact page)
- "What opportunities are linked to this company?" (on a company page)
- "When was this deal last updated?" (on an opportunity page)

View File

@@ -0,0 +1,134 @@
---
title: MCP Server
description: Connect AI assistants to your Twenty workspace using the Model Context Protocol.
---
Twenty exposes an [MCP](https://modelcontextprotocol.io/) server so that AI assistants — Claude Desktop, Claude Code, Cursor, ChatGPT, and others — can read and write your CRM data through natural language.
Use your **workspace URL** (the URL you use to access Twenty) as the MCP endpoint. On Twenty Cloud, your workspace URL might be `https://{mycompany}.twenty.com` or a custom domain. The server is available at:
| Environment | MCP Endpoint |
|-------------|-------------|
| **Cloud** | `https://{your-workspace-url}/mcp` (e.g. `https://mycompany.twenty.com/mcp`) |
| **Self-Hosted** | `https://{your-domain}/mcp` |
## Authentication Methods
You have two ways to authenticate your MCP client: **OAuth** (recommended) or **API Key**.
### Option A — OAuth (Recommended)
With OAuth, your MCP client opens a browser window for you to log in. No secrets are stored in config files, and tokens refresh automatically.
<Note>
OAuth requires an MCP client that supports the [MCP Authorization specification](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization). Claude Desktop, Claude Code, Cursor, and ChatGPT support it.
</Note>
Add this to your MCP client configuration, replacing `{your-workspace-url}` with your workspace host (e.g. `mycompany.twenty.com`):
```json
{
"mcpServers": {
"twenty": {
"type": "streamable-http",
"url": "https://{your-workspace-url}/mcp"
}
}
}
```
That's it — no API key needed. When the client connects for the first time it will:
1. Discover Twenty's OAuth metadata via `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server`
2. Register itself as an OAuth client via dynamic client registration (RFC 7591)
3. Open your browser to authorize access
4. Receive tokens and connect to the MCP server
Subsequent connections reuse the stored tokens and refresh them automatically.
### Option B — API Key
If your MCP client does not support OAuth, or you prefer static credentials, pass an API key in the `Authorization` header:
```json
{
"mcpServers": {
"twenty": {
"type": "streamable-http",
"url": "https://{your-workspace-url}/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
<Warning>
Your API key grants access to workspace data. Keep it out of version control and shared dotfiles.
</Warning>
To create an API key, go to **Settings → MCP & APIs → API → + Create key**. See [APIs](/developers/extend/api#create-an-api-key) for details.
## Quick Start
### 1. Copy the config
Go to **Settings → MCP & APIs → MCP** in Twenty. Choose your authentication method (OAuth or API Key), copy the JSON snippet (it will already use your workspace URL), and paste it into your MCP client's config file.
| Client | Config file location |
|--------|---------------------|
| **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
| **Claude Code** | `~/.claude.json` (user) or `.mcp.json` (project) |
| **Cursor** | `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` globally |
| **ChatGPT** | Turn on Developer Mode in **Settings → Apps & Connectors → Advanced settings**, then use **Create** in **Settings → Apps & Connectors** to add the MCP server |
### 2. Connect
Restart your MCP client (or reload the config). If using OAuth you will be redirected to Twenty to authorize access. If using an API key the connection is immediate.
### 3. Start using it
Ask your AI assistant to interact with your CRM:
- *"Show me the 5 most recently created companies"*
- *"Create a new person named Jane Doe at Acme Corp"*
- *"Find all open opportunities worth more than $10k"*
## Available Tools
Once connected, the MCP server exposes tools that mirror the Twenty API. The recommended workflow is:
1. **`learn_tools`** — get the input schema for specific tools
2. **`execute_tool`** — run a tool
You don't need to remember tool names. Ask your AI assistant what it can do and it will call `learn_tools` automatically.
## Permissions
MCP connections inherit the permissions of the authenticated user (OAuth) or the role assigned to the API key. To restrict what the MCP server can do:
- **OAuth**: The user's workspace role applies.
- **API Key**: Assign a role to the API key under **Settings → Members → Roles**. See [Permissions](/user-guide/permissions-access/capabilities/permissions).
## Self-Hosted Configuration
For self-hosted instances, replace `{your-workspace-url}` with your server URL. Make sure `SERVER_URL` in your environment matches the public URL of your Twenty instance — this is used to generate the OAuth discovery metadata.
```bash
SERVER_URL=https://twenty.yourcompany.com
```
The MCP endpoint, OAuth endpoints, and discovery metadata all derive from this value.
## Troubleshooting
**"Unauthorized" or 401 errors**
- OAuth: re-authorize by clearing the stored tokens in your MCP client and reconnecting.
- API Key: verify the key is valid and hasn't expired. Regenerate it if needed.
**OAuth flow doesn't open a browser**
- Ensure your MCP client supports MCP Authorization. Fall back to the API Key method if it doesn't.
**Connection timeout**
- Confirm the MCP endpoint URL is reachable from your machine. For self-hosted instances, check that the server is running and `SERVER_URL` is set correctly.

View File

@@ -0,0 +1,36 @@
---
title: Permissions & Access Control
description: Control what AI agents can access and modify in your workspace.
---
## Overview
AI agents respect your existing permission structure. This is particularly important for teams who want to control exactly what automated AI processes can access or modify in their workspace.
## Assign a Role to an AI Agent
1. Go to **Settings → Members → Roles**
2. Click on the role you want to assign
3. Open the **Assignment** tab
4. Under **AI Agents**, click **+ Assign to AI agent**
5. Select the AI agent from the list
6. Confirm the assignment
## Why Assign Roles to AI Agents?
| Benefit | Description |
|---------|-------------|
| **Security** | Limit what data AI agents can access or modify |
| **Compliance** | Ensure AI only processes the data it needs |
| **Control** | Prevent unintended actions from AI automations |
| **Auditability** | Track which actions were performed by which agent |
<Note>
For AI agents running within workflows, role assignment ensures the agent cannot access or modify data outside its intended scope—even if the workflow has broader permissions.
</Note>
## Related
- [Permissions](/user-guide/permissions-access/capabilities/permissions) — detailed information on creating and managing roles
- [AI Agents](/user-guide/ai/capabilities/ai-agents) — AI capabilities in workflows

View File

@@ -0,0 +1,32 @@
---
title: AI FAQ
description: Frequently asked questions about AI features in Twenty.
---
<AccordionGroup>
<Accordion title="What AI capabilities are available?">
Two main capabilities of AI are:
1. **AI Chatbot**: A context-aware assistant that can access your Twenty data and help you with queries
2. **AI Agents in Workflows**: Intelligent automation that can process data, make decisions, and execute tasks within your workflows
</Accordion>
<Accordion title="Do AI agents have access to all my data?">
AI agents operate under the permission system. You can assign specific roles to AI agents under **Settings → Members → Roles**, giving you full control over what data they can access and what actions they can perform.
</Accordion>
<Accordion title="How do AI credits work?">
AI actions consume workflow credits based on the complexity of the task and the AI model used.
</Accordion>
<Accordion title="Can I use my own AI models?">
On cloud, you can use only AI models provided by Twenty. On your self-hosted instance, you can use your own AI models after obtaining an Organization license.
</Accordion>
<Accordion title="I don't see a role I assigned to an AI agent, where is it?">
By default, the Roles list is filtered to roles assignable to workspace members. If a role is assignable only to AI agents, you need to change the filter to include AI-agent roles.
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,54 @@
---
title: AI
description: AI-powered features in Twenty.
---
<Frame>
<img src="/images/user-guide/workflows/robot.png" alt="AI" />
</Frame>
## Features
Currently, Twenty offers:
### 1. AI Chatbot
A conversational assistant that understands your context and has access to all your Twenty data.
**Key capabilities:**
- **Full data access**: Query any record, relationship, or metric in your workspace
- **Page context awareness**: Reference "this company" or "this opportunity" based on where you are in Twenty
- **Natural language**: Ask questions and get answers without navigating menus
**Example prompts:**
- "What opportunities are closing this month?"
- "Which deals have been in Negotiation for more than 30 days?"
- "Summarize my interactions with this person"
### 2. AI Agents in Workflows
Extend your workflows with AI-powered actions and autonomous agents.
**Key capabilities:**
- **AI actions**: Use AI to enrich data, classify records, generate summaries, and more
- **Autonomous agents**: Let agents execute multi-step tasks within a workflow
- **Custom prompts**: Define exactly how AI should process your data
**Use cases:**
- Automatically categorize inbound leads
- Enrich company data from public sources
- Generate follow-up email drafts based on meeting notes
- Score opportunities based on engagement patterns
## Permissions and Access Control
AI agents are managed through the existing permissions system:
1. Go to **Settings → Members → Roles**
2. Configure which data each AI agent can access
3. Set read/write permissions per object
This ensures AI agents respect your data governance policies and only access what they need.
- Follow our [GitHub](https://github.com/twentyhq/twenty) for development updates
- Join our [Discord](https://discord.gg/UfGNZJfAG6) to share feedback and feature requests

View File

@@ -0,0 +1,84 @@
---
title: Credits
description: One simple balance that powers your workflows, AI agents, and AI chat — what a credit is worth, how far it goes, and how to manage it.
---
## What are credits?
Credits are a single balance that powers everything we run on your behalf that has a real cost: **workflow automations**, **AI agents**, and the **AI chat**. Instead of juggling separate quotas for "automation runs" and "AI tokens," you have one simple balance to keep an eye on.
**1 credit = $1 of usage.** A credit is just a dollar of work, so your balance is easy to reason about — no abstract units to convert.
## How far does a credit go?
Cost scales with the work. Everyday automation and quick AI messages cost a tiny fraction of a credit; large, multi-step AI agent tasks cost more. Here's the rough shape:
| What you do | Roughly costs | What that means |
|-------------|---------------|-----------------|
| Run a standard workflow step (search, create, or update records) | $0.0001 | **10,000 runs per credit** |
| Trigger an app's logic function | $0.0001 + $0.0001 per second of runtime | **Thousands of runs per credit** |
| Call an external API or run a code node | A small fraction of a credit | Thousands per credit |
| Send a quick AI chat message or simple AI step | A fraction of a cent | Hundreds per credit |
| Run a large AI agent task (e.g. "configure 10 workspace objects") | Can run to **~$1 or more** | A few per credit |
| Run an AI web search | A fixed per-search cost | Hundreds of searches per credit |
<Note>
For most teams, standard automations are effectively free — you'll only make a noticeable dent in your balance when you lean on AI features or run heavy code nodes. That's by design: the included credits are meant to let you build without watching a meter.
</Note>
<Note>
Not every app charges for its runs. Call Recorder, Last Contact and Fathom react to every email, calendar event and recording imported into your workspace, and Slack runs on every Slack event its bot subscribes to, so their logic function runs are free. You are still charged for the metered work they do, such as recorded call minutes or the AI credits behind Slack assistant answers.
</Note>
## How logic function runs are metered
Logic function pricing mirrors AWS Lambda: a flat charge per invocation plus a duration charge for the time your code actually runs, billed per millisecond.
- **Per invocation**: $0.0001
- **Per duration**: $0.0001 per second of runtime ($0.0000001 per millisecond)
A typical function that finishes in under a second costs at most double the flat invocation charge. Long-running functions pay for the compute they use: a function running for a full minute adds $0.006, and one hitting the 15-minute timeout adds $0.09. A function that times out is billed for its full elapsed time, just like on AWS.
## How AI usage is metered
When an action calls an AI model, we measure the exact tokens used and price them at **the model provider's published rates**, then convert that dollar amount straight into credits — so what you spend tracks the real cost of the work, not a marked-up internal rate. A short chat message costs a fraction of a cent. A large agent task — say, configuring 10 workspace objects — makes many model calls over a growing context, so it can add up to a dollar or more. You're billed for what you actually use, down to the token.
Cost varies by model: a lightweight model is dramatically cheaper per message than a top-tier reasoning model. You can see the per-action breakdown — including which model was used — in **Settings → Billing**.
## What's included
Every subscription includes credits, and the amount depends on your **billing cycle**, not your plan:
| Billing Cycle | Included Credits | Equivalent Usage |
|---------------|------------------|------------------|
| Monthly | 5 / month | ~$5 of usage each month |
| Yearly | 50 / year | ~$50 of usage each year |
These credits are designed to cover everyday automation comfortably. Five credits cover tens of thousands of standard automation steps or hundreds of quick AI messages — though a handful of large, multi-step agent tasks can use them up faster. You can top up at any time (see below).
## Credit rollover
Unused credits roll over automatically to the next billing period.
- **Cap**: Rollover is capped at one period's full allocation, so you'll never carry over more than your billing cycle provides per period.
- **Visibility**: When you have rollover credits, they appear as a separate **Rollover Credits** line in **Settings → Billing**, alongside your **Total Available** balance.
## Monitoring usage
Keep track of your balance and where it's going:
1. Go to **Settings → Billing**
2. See your **remaining credits** and **usage for the current period**
3. Drill into the breakdown to see which workflows and AI actions are consuming credits — and which models AI actions used
Reviewing this regularly makes it easy to spot a heavy workflow early and decide whether to optimize it or top up.
## Need more credits?
If you run out — or want a buffer before a big automation push — you can buy additional credit packs at any time:
1. Go to **Settings → Billing**
2. Click the **Increase** button
3. Select the amount you need and accept the changes
Purchased credits are added to your available balance immediately.

View File

@@ -0,0 +1,90 @@
---
title: Pricing Plans
description: Learn about Twenty's pricing plans and how to switch between them.
---
## Overview
Twenty offers flexible pricing to fit teams of all sizes, whether you prefer cloud hosting or self-hosting.
## Cloud Plans
### Pro (Cloud)
For teams ready to scale:
- All core CRM features
- Email and calendar sync
- Workflows and automations
- Standard support
<Note>
Premium features (SSO, row-level permissions, AI usage data and more) are not included in the Pro plan.
</Note>
### Organization (Cloud)
For larger teams with advanced needs:
- Everything in Pro
- **Premium features**: SSO integration, row-level permissions, AI usage data and more
- Priority support
## Self-Hosted Plans
### Free (Self-Hosted)
Host Twenty on your own infrastructure at no cost:
- All Pro features included
- Community support via Discord
- Full control over your data
### Organization (Self-Hosted)
For teams who need premium features while self-hosting:
- All Pro features
- **Premium features**: SSO integration, row-level permissions, AI usage data and more
- Twenty team support
- No requirement to publish custom code as open-source before distributing
## Premium Features
Premium features are only available on the Organization plans (Cloud or Self-Hosted):
- **SSO integration**: Single Sign-On with your identity provider
- **Row-level permissions**: Fine-grained access control at the record level
- **AI usage data**: Track AI consumption across the workspace
- **Audit logs**: Check what each workspace member has been doing
- **Email campaigns**: Plan which emails should be sent (available soon)
- **Unlimited workspaces**: Create as many workspaces as you want (self-hosted only)
- **Private source code**: No requirement to publish changes to a publicly available repository (self-hosted only)
## Switching Plans
### Upgrade to Organization
1. Go to **Settings → Billing → Plans**
2. Click **Switch to Organization**
3. Confirm your upgrade
### Downgrade to Pro
1. Go to **Settings → Billing → Plans**
2. Click **Switch to Pro**
3. Confirm your downgrade
### Switch to Yearly Billing
1. Go to **Settings → Billing**
2. Click **Upgrade to Yearly**
3. Save with annual billing
### Switch to Monthly Billing
1. Go to **Settings → Billing**
2. Click **Downgrade to Monthly**
3. Save with monthly billing
## Get an Organization Key
The Organization (Self-Hosted) plan runs on your own infrastructure. To get started, [install Twenty with Docker Compose](/developers/self-host/capabilities/docker-compose), then follow the steps below to activate your Organization license.
If you already have a self-hosted Twenty instance, you can get your Organization key directly from its settings:
1. Go to **Settings → Admin Panel → Organization**
<img src="/images/user-guide/billing/organization-key.png" alt="Organization key" />
2. Click **Get Organization Key**
3. When you are redirected to Stripe, enter your payment details and confirm
4. When your Organization key is displayed, paste it into the Organization settings page and activate the Organization license

View File

@@ -0,0 +1,105 @@
---
title: Billing FAQ
description: Frequently asked questions about Twenty pricing and billing.
---
## Pricing
<AccordionGroup>
<Accordion title="Can I use Twenty for free while self-hosting?">
Yes, you can use Twenty for free while self-hosting. You will get access to everything included in the Pro (Cloud) plan, except the support from our core team. Support is accessible via our Discord community.
If you want to self-host and need the Premium features (SSO, row-level permissions and more), you can choose the paid Organization (Self-Hosted) license. This also includes support from the Twenty team and removes the requirement to publish custom code as open-source before distributing.
</Accordion>
<Accordion title="What are the Premium features?">
Premium features are only available on the Organization plans (Cloud or Self-Hosted):
- **SSO integration**: Single Sign-On with your identity provider
- **Row-level permissions**: Fine-grained access control at the record level
- **AI usage data**: Track AI consumption across the workspace
- **Audit logs**: Check what each workspace member has been doing
- **Email campaigns**: Plan which emails should be sent (available soon)
- **Unlimited workspaces**: Create as many workspaces as you want (self-hosted only)
- **Private source code**: No requirement to publish changes to a publicly available repository (self-hosted only)
</Accordion>
<Accordion title="Are the Cloud and Self-Hosted Organization plans the same?">
They offer the same premium features. However, a cloud subscription cannot be used for self-hosted deployments. Self-hosted requires an Organization key.
</Accordion>
<Accordion title="Do you offer free seats for view-only users?">
We do not offer free seats. Pricing is per user and each user needs a license to access Twenty.
</Accordion>
<Accordion title="Where can I switch my subscription to the Organization plan?">
You can do so under `Settings → Billing → Plans`. Then click on `Switch to Organization`.
</Accordion>
<Accordion title="Where can I switch my subscription to the Pro plan?">
You can do so under `Settings → Billing → Plans`. Then click on `Switch to Pro`.
</Accordion>
<Accordion title="Where can I switch my subscription to yearly?">
You can do so under `Settings → Billing`. Then click on `Upgrade to yearly`.
</Accordion>
<Accordion title="Where can I switch my subscription to monthly?">
You can do so under `Settings → Billing`. Then click on `Downgrade to monthly`.
</Accordion>
<Accordion title="Where can I see my credit usage?">
You will find this under `Settings → Billing`.
</Accordion>
<Accordion title="How many workflow credits do we have?">
The number of credits depends on your billing cycle, not your plan:
- **Monthly subscriptions**: 5 credits per month
- **Yearly subscriptions**: 50 credits per year
</Accordion>
<Accordion title="How does workflow credit consumption work?">
Each workflow action consumes credits based on its complexity:
- **Basic internal operations** (such as search, update, or create records) consume very few credits
- **More complex operations** like code nodes and requests to external services consume more credits
- **AI prompts** also consume more credits based on usage
- **Apps** also consume more credits similarly to code nodes
Credits are deducted in real-time when workflows or apps execute. You can monitor your usage in **Settings → Billing** to track consumption and remaining credits.
</Accordion>
<Accordion title="Can I buy more workflow credits?">
You can buy additional credits under `Settings → Billing`.
</Accordion>
<Accordion title="Can I buy more workflow credits only for 1 month?">
Yes, go to `Settings → Billing`, click the `Increase` button, choose how many credits you want, and confirm. They'll be applied for the current billing period. Then click the `Increase` button again, change the value back to the original, and confirm — the downgrade will be applied starting the next billing period.
</Accordion>
</AccordionGroup>
## Billing
<AccordionGroup>
<Accordion title="Where can I manage the Billing details?">
You can do so under `Settings → Billing`.
</Accordion>
<Accordion title="Where can I update my payment method?">
You can do so under `Settings → Billing`. Then click on `View billing details`. You'll be able to add a new payment method there.
</Accordion>
<Accordion title="Where can I update my billing information?">
You can do so under `Settings → Billing`. Then click on `View billing details`. You'll be able to edit the billing information there.
</Accordion>
<Accordion title="Where can I access my invoices?">
You can do so under `Settings → Billing`. Then click on `View billing details`. You'll see all your invoices at the bottom of the screen.
</Accordion>
<Accordion title="Why are my seats different from the number of users in my workspace?">
Workspace seat counts are synchronized with the payment system every 6 hours; invoices are adjusted based on the difference.
</Accordion>
<Accordion title="Why did I get an invoice for a new workspace member?">
When a new workspace member is added to the workspace, an invoice is sent to cover the difference. When a workspace member is removed, the change is applied in the next standard monthly/yearly invoice.
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,39 @@
---
title: Billing
description: Understand Twenty pricing and manage your subscription.
---
Twenty offers flexible pricing plans to fit your team's needs. Manage your subscription, track workflow credits, and access invoices all from **Settings → Billing**.
## What's in this section
<CardGroup cols={2}>
<Card title="Pricing Plans" icon="tags" href="/user-guide/billing/capabilities/pricing-plans">
Learn about Twenty's pricing plans and what's included.
</Card>
<Card title="FAQ" icon="circle-question" href="/user-guide/billing/how-tos/billing-faq">
Frequently asked questions about pricing and billing.
</Card>
</CardGroup>
## At a glance
| Plan | Key Features |
|------|--------------|
| **Free (Self-Hosted)** | All Pro features, community support |
| **Pro (Cloud)** | Everything apart from the Premium features (SSO, row-level permissions and more), standard support |
| **Organization (Cloud)** | All from Pro + the Premium features (SSO, row-level permissions and more), priority support |
| **Organization (Self-Hosted)** | All from Pro + the Premium features (SSO, row-level permissions and more), Twenty team support, not required to publish your custom code as open-source before distributing |
## Quick answers
**Where do I manage billing?**
Go to **Settings → Billing** to view your plan, update payment methods, and access invoices.
**Can I use Twenty for free?**
Yes! Self-host Twenty and get all Pro features at no cost.
**How do I upgrade?**
Go to **Settings → Billing** and click **Switch to Organization** or **Switch to Yearly**.
For more questions, see the [Billing FAQ](/user-guide/billing/how-tos/billing-faq).

View File

@@ -0,0 +1,44 @@
---
title: Calendar
description: Understanding calendar integration features in Twenty.
---
**Note**: To connect your calendar and configure sync settings, visit [Email & Calendar Setup](/user-guide/calendar-emails/overview).
## How Calendar Integration Works
Twenty automatically syncs your calendar events and links them to the relevant CRM records, giving you a complete view of your meeting history with contacts and companies.
## Calendar Tab
Next to the Emails tab on records, you'll find a `Calendar` tab that contains the history of meetings scheduled with the record.
### Available For
- **People**: View all meetings scheduled with a specific contact
- **Companies**: See all meetings related to a company and its employees
- **Opportunities**: Access meeting history related to the company linked to the opportunity
### Viewing Meeting History
1. **Navigate to a Record**: Go to any Person, Company, or Opportunity record
2. **Select the Calendar Tab**: Click on the `Calendar` tab next to the Emails tab
3. **Browse Meeting History**: View all scheduled meetings and their details
4. **Access Meeting Context**: See meeting participants, times, and related information
## Visibility Settings
Calendar data follows the same visibility settings as emails, ensuring consistent privacy controls across both communication channels.
## What Gets Synced
- **External Meetings**: All meetings with contacts outside your organization
- **Automatic Linking**: Meetings connect to existing People and Company records based on attendee email addresses
- **Meeting Details**: Subject, time, duration, and participants
- **Updates**: New calendar events sync automatically
## What Doesn't Get Synced
- **Internal Meetings**: Meetings with only colleagues (same domain) remain private
- **Private Events**: Events marked as private in your calendar

View File

@@ -0,0 +1,89 @@
---
title: Mailbox
description: Understanding email integration features in Twenty.
---
**Note**: To connect your email accounts and configure sync settings, visit [Email & Calendar Setup](/user-guide/calendar-emails/overview).
## How Email Integration Works
Twenty automatically links emails from your connected mailboxes to the relevant CRM records, keeping all communication history in one place.
### Objects Where Emails Can Be Found
Email conversations appear in three main objects:
- **People**: View all emails exchanged with a specific contact
- **Companies**: See all emails related to a company and its employees
- **Opportunities**: Access email threads related to the company linked to the opportunity. Email threads from individual people on the opportunity are not shown yet.
### Viewing Email Threads
1. **Navigate to a Record**: Go to any Person, Company, or Opportunity record
2. **Select the Emails Tab**: Click on the `Emails` tab to view synced emails
3. **Open an Email Thread**: Click on any email to open and read the full conversation
4. **Browse History**: Scroll through the complete email history with that contact
<img src="/images/user-guide/emails/show-inbox.png" style={{width:'100%'}}/>
## What You'll See
### Email Thread View
When you open an email thread, you can:
- **Read Full Conversations**: See the complete email exchange
- **View Participants**: See all people involved in the email thread
- **Check Timestamps**: Know exactly when each email was sent
- **Access Context**: Understand the full communication history
### Email Visibility
Depending on your mailbox settings, you might see:
- **Full Content**: Complete email text and details
- **Subject + Metadata**: Subject line, sender, recipient, and timestamp
- **Metadata Only**: Basic information without email content
## Email Sync Behavior
### Sync Rate
Twenty imports emails at approximately **400 messages per minute**. This rate is currently limited by Gmail API rate limiting (and applies similarly to other providers).
For reference:
- 1,000 emails → ~2.5 minutes
- 10,000 emails → ~25 minutes
- 50,000 emails → ~2 hours
### What Gets Synced
- **External Emails**: All emails with contacts outside your organization
- **Automatic Linking**: Emails connect to existing People and Company records
- **Multiple Addresses**: Emails from any address link to the same contact record
- **Updates**: New emails appear immediately
### What Doesn't Get Synced
- **Internal Emails**: By default, emails between colleagues (same domain) remain private (configured in Settings → General → Security)
- **Group Emails**: Distribution lists and group emails are excluded
- **Excluded Folders**: Folders you've chosen not to sync (configured under Settings → Accounts → Email)
### Internal Emails
Choose if internal emails are synchronized in Twenty:
1. Go to **Settings → General → Security**
2. Toggle **Sync Internal Emails** on/off
### Selective Folder Sync
Control which email folders sync with Twenty:
1. Go to **Settings → Accounts** and select your connected email account
2. Configure folders under the Email section
3. Choose specific folders to include or exclude (Inbox, Sent, Archive, custom folders)
## Troubleshooting Email Sync
### Common Sync Issues
- **Sync Delays**: Emails appear immediately, but initial imports take longer
- **Missing Emails**: Check if:
- Folders are excluded in Message Folder settings
- Contact auto-creation is disabled (emails need existing Twenty records)
- Email is from colleagues (same domain) or group lists
- Mailbox is still completing initial sync
### Email Limitations
- **System Folders**: Some email folders may not be available for sync
- **Aliases**: Only true mailboxes can be connected (not email aliases)

View File

@@ -0,0 +1,44 @@
---
title: Can I Book Meetings from Twenty?
description: Information about booking meetings directly from Twenty.
---
## Current Status
Yes. Twenty's calendar integration syncs and displays your existing events, and you can also create a new event straight from a record page. The event is created on your connected calendar, not just inside Twenty.
## How to create a meeting from Twenty
Prerequisite: a connected Google, Microsoft or CalDAV account with calendar sync enabled
1. Open a Person, Company or Opportunity record
2. Click the **Create calendar event** action
3. Pick the calendar account to create the event on
4. Add guests, a title, a location and a description
5. Set the start and end (or toggle **All day**) and check the time zone
6. Toggle **Invitations** to email guests, and **Video call** to add a meeting link
7. Click **Create event**
The record you started from is linked to the event automatically, so the meeting shows up on its timeline.
<Note>
The action is hidden if your role doesn't have the "Create calendar event" permission, and disabled if the record has no email address to invite.
</Note>
## Scheduling Meetings via Workflows
You can also create events automatically with workflows:
1. Create a new workflow
2. Select any trigger depending on your needs
3. Add the **Create Calendar Event** node
4. Configure all necessary data
5. Activate the workflow
## What You Can Do
- **Create events** on your connected calendar from a record
- **View meeting history** on People, Companies, and Opportunities records
- **See upcoming meetings** with contacts in your CRM
- **Track meeting context** alongside email communications
- **Auto-create contacts** from meeting participants

View File

@@ -0,0 +1,50 @@
---
title: Can I Send Emails from Twenty?
description: Information about sending emails directly from Twenty.
---
## Current Status
Twenty's email integration is designed to **sync and display** your email history as well as compose and send emails.
When you view an email thread on a record page and click **Reply**, you're able to directly compose and send an email.
## How to send a message from Twenty
Prerequisite: a connected mail account with the ability to send emails
1. Open the Command menu with the **Ctrl+K** or **Cmd+K** shortcut
2. Click the "Compose email" option
3. Choose recipients, add subject, body and attachments to your email
4. Click the "Send" button to send the email
## What You Can Do Today
- **View email history** on People, Companies, and Opportunities records
- **Read full email threads** with contacts in your CRM
- **Track communication context** alongside calendar events
- **Auto-create contacts** from email interactions
- **Reply via redirect** — click Reply to jump to your mailbox
## Sending Emails via Workflows
You **can send emails automatically using workflows**. This is useful for:
- Automated follow-ups
- Notifications to contacts
- Triggered communications based on record changes
Emails sent via workflows go through your connected mailbox account.
→ Learn about the [Send Email action](/user-guide/workflows/capabilities/workflow-actions#send-email)
## Email Sequences and Newsletters
For email sequences and newsletters, we recommend using workflows to connect Twenty to a dedicated email marketing tool.
<Warning>
Mass emails should not be sent directly from your mailbox to protect your domain reputation. Use a dedicated tool for bulk communications.
</Warning>
→ See [How to send emails from workflows](/user-guide/workflows/capabilities/send-emails-from-workflows) for setup instructions
## Future Plans
Native email composition from within Twenty is on our roadmap. Join our [GitHub discussions](https://github.com/twentyhq/twenty/discussions) to share your use case and help prioritize this feature.

View File

@@ -0,0 +1,33 @@
---
title: Can I Track Email Activity on All Objects?
description: Understanding email activity tracking across different objects.
---
## Supported Objects
Email activity is currently available on **three standard objects**:
| Object | What You See |
|--------|--------------|
| **People** | All emails exchanged with that specific contact |
| **Companies** | All emails with anyone from that company (based on email domain) |
| **Opportunities** | Emails related to the company linked to the opportunity |
## Why Only These Objects?
People, Companies, and Opportunities are the core relationship objects where email context adds the most value. Email threads are automatically linked based on:
- **Email address** → matched to People records
- **Email domain** → matched to Company records
- **Company relation** → linked to Opportunities
## Custom Objects
**Email tracking is not available on custom objects** at this time.
If you need email context on a custom object, consider:
- Using a relation field to link your custom object to People or Companies
- Viewing email history on the linked People/Company record
## Future Plans
Extending email visibility to custom objects is being considered. Share your use case on our [GitHub discussions](https://github.com/twentyhq/twenty/discussions) to help prioritize this feature.

View File

@@ -0,0 +1,39 @@
---
title: Connect Several Mailboxes per User
description: Connect multiple email accounts for a single user.
---
## Overview
Twenty supports **unlimited email accounts per user**. This is useful if you manage multiple inboxes, such as:
- Personal work email + shared team inbox
- Multiple client-facing email addresses
- Different email accounts for different roles
## How to Add Multiple Mailboxes
1. Go to **Settings → Accounts**
2. Click **Add account**
3. Connect an additional Google or Microsoft account, or any other mail provider supporting IMAP/SMTP protocols
4. Configure sync settings for this mailbox
5. Repeat for each mailbox you want to connect
## Managing Multiple Accounts
Each connected mailbox has its own settings:
- **Email visibility**: Choose what teammates can see
- **Contact auto-creation**: Enable/disable per mailbox
- **Folder selection**: Choose which folders to sync
## How Emails Appear
Emails from all your connected mailboxes are synced to Twenty and appear on:
- **People records**: Based on the contact's email address
- **Company records**: Based on the email domain
- **Opportunities**: Based on the linked company
<Note>Each email shows which mailbox it was sent from or received in, so you can track which account was used for each communication.</Note>
## Important Notes
<Warning>Only true mailboxes can be connected. Email aliases that forward to another mailbox cannot be connected separately — they'll sync through the main mailbox.</Warning>

View File

@@ -0,0 +1,118 @@
---
title: Forward a Shared Inbox from Any Email Provider
description: Point a shared inbox at a Twenty email channel, whatever mail provider you use.
---
Twenty receives shared inbox mail by having your provider send a copy of every incoming message to a private address that Twenty generates for you. Once that is in place, the inbox appears in your workspace.
Microsoft 365 and Google Workspace each have their own guide:
- [Microsoft 365](/user-guide/calendar-emails/how-tos/forward-a-shared-inbox-from-microsoft-365)
- [Google Workspace](/user-guide/calendar-emails/how-tos/forward-a-shared-inbox-from-google-workspace)
This page covers every other provider.
## Part 1: Create the channel in Twenty
1. Go to **Settings → Communication**.
2. Click **Add email channel**.
<img
src="/images/user-guide/emails/inbound-channels/03-twenty-add-email-channel.png"
style={{ width: '100%' }}
/>
3. In **Source Email Address**, type the shared address you want to receive mail at, for example `contact@yourcompany.com`.
4. In **Display Name**, type the name recipients see.
5. Click **Save**.
<img
src="/images/user-guide/emails/inbound-channels/04-twenty-new-channel-form.png"
style={{ width: '100%' }}
/>
6. Twenty now shows a **Forwarding address**. It ends in `@inbound.twenty.com`. Click **Copy**.
<img
src="/images/user-guide/emails/inbound-channels/05-twenty-forwarding-address.png"
style={{ width: '100%' }}
/>
<Note>
Each channel gets its own forwarding address. Never point two mailboxes at the
same one, or their mail will land in the same place.
</Note>
## Part 2: Choose the right kind of forwarding
Most providers offer more than one way to pass mail on, and only one of them works here.
Twenty reads the `From` header of each message it receives to determine who wrote it. That is how a message is linked to the right person and company.
- **Automatic forwarding on the mail server** leaves the original sender in place. Your customer remains the sender, the message is linked to their record, and replies go back to them. Some providers call this **Redirect**, others call it **Forwarding**. This is the option to use.
- **Forwarding as an attachment**, or any rule that composes a new message, replaces the sender with your own address. Every conversation then appears to come from you, and no message is matched to a contact.
Use the automatic forwarding setting in your mail account or on your mail server. Do not use a rule that resends the message as a new email.
<Warning>
Also avoid rules that strip attachments or convert messages to plain text.
Twenty stores each message exactly as it arrives.
</Warning>
Where the option exists, choose the one that **keeps a copy** in the original mailbox, so your team can continue to use the inbox as before.
## Part 3: Find your provider
Follow your provider's instructions, using the forwarding address you copied in Part 1 as the destination.
| Provider | Their guide |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Amazon SES | [Forward incoming email to an external destination](https://aws.amazon.com/blogs/messaging-and-targeting/forward-incoming-email-to-an-external-destination/) |
| Amazon WorkMail | [Email rules](https://docs.aws.amazon.com/workmail/latest/userguide/email-rules.html) |
| Bluehost | [Create account and domain forwarders](https://www.bluehost.com/help/article/create-account-and-domain-forwarders) |
| cPanel | [Forwarders](https://docs.cpanel.net/cpanel/email/forwarders/) |
| DreamHost | [Add a forward-only email address](https://help.dreamhost.com/hc/en-us/articles/215724207-Add-a-forward-only-email-address) |
| Exchange (self-hosted) | [Configure email forwarding for a mailbox](https://learn.microsoft.com/en-us/exchange/recipients/user-mailboxes/email-forwarding) |
| GoDaddy | [Forward incoming email to another address](https://www.godaddy.com/help/forward-incoming-email-to-another-email-address-32282) |
| iCloud Mail | [Forward email on iCloud.com](https://support.apple.com/en-us/102376) |
| Namecheap | [Set up free email forwarding](https://www.namecheap.com/support/knowledgebase/article.aspx/308/2214/how-to-set-up-free-email-forwarding) |
| OVHcloud | [Email redirection](https://help.ovhcloud.com/csm/en-emails-redirection) |
| Rackspace | [Set up Rackspace email forwarding](https://docs.rackspace.com/docs/set-up-rackspace-email-forwarding) |
| Zoho Mail | [Email forwarding](https://www.zoho.com/mail/help/email-forwarding.html) |
If your provider is not listed, you can still connect it. In almost every mail product the setting appears under a name such as **Forwarding**, **Redirect**, **Forwarders**, **Aliases**, **Rules** or **Filters**, in either the mailbox settings or the domain settings.
## Part 4: Test it
Send an email from an outside address (a personal Gmail works) to `contact@yourcompany.com`. It should appear in Twenty within a minute or two.
## Troubleshooting
<Accordion title="Nothing arrives">
Compare the forwarding address character for character with the one in Twenty.
A single wrong character means the mail goes nowhere and is silently dropped.
</Accordion>
<Accordion title="Mail arrives, but every message shows your own address as the sender">
The rule is rebuilding the message rather than passing it along, so your
address ends up in the `From` header. Switch to your provider's plain
forwarding or redirect setting, and turn off any option that forwards as an
attachment.
</Accordion>
<Accordion title="The sender receives a bounce about forwarding not being allowed">
Your provider blocks automatic forwarding to outside domains. Look for a
security or anti-spam setting that allows external forwarding, and enable it
for this mailbox only.
</Accordion>
<Accordion title="Mail no longer appears in the original inbox">
The rule moves messages on rather than copying them. Change it to keep a copy,
or add a second rule that delivers to the inbox.
</Accordion>
<Accordion title="The channel receives mail but cannot send">
Receiving and sending are separate. Sending requires your domain to be
verified under the channel's **Sending domain** section, which means adding
the DNS records Twenty lists there.
</Accordion>

View File

@@ -0,0 +1,151 @@
---
title: Forward a Shared Inbox from Google Workspace
description: Send mail from a Google Group into a Twenty email channel.
---
An email channel gives your workspace a shared address, like `sales@yourcompany.com`. Mail sent to that address has to reach Twenty somehow.
On Google Workspace that address is almost always a **Google Group**. You connect it by adding Twenty's private forwarding address as a member of the group. Every message the group receives is then copied to Twenty, and your team continues to receive it as before.
<Note>
This applies to new mail only. Twenty will not see messages the group received
before you set this up.
</Note>
## Before you start
You need two things:
- **Access**: you must own the group, or be a Super Admin or Groups Admin in Google Workspace.
- **A group that accepts outside addresses**: Twenty's forwarding address is external, so the group has to accept external members and accept mail from outside your company. Part 2 covers both.
## Part 1: Create the channel in Twenty
1. Go to **Settings → Communication**.
2. Click **Add email channel**.
<img
src="/images/user-guide/emails/inbound-channels/03-twenty-add-email-channel.png"
style={{ width: '100%' }}
/>
3. In **Source Email Address**, type the group address, for example `sales@yourcompany.com`.
4. In **Display Name**, type the name recipients see.
5. Click **Save**.
<img
src="/images/user-guide/emails/inbound-channels/04-twenty-new-channel-form.png"
style={{ width: '100%' }}
/>
6. Twenty now shows a **Forwarding address**. It looks like `ch_2cd282d193b5@inbound.twenty.com`. Click **Copy**.
<img
src="/images/user-guide/emails/inbound-channels/05-twenty-forwarding-address.png"
style={{ width: '100%' }}
/>
<Note>
Each channel gets its own forwarding address. Never point two groups at the
same one, or their mail will land in the same place.
</Note>
## Part 2: Check the group's settings
Two settings decide whether this works at all. Set them correctly before you continue.
1. Open [Google Groups](https://groups.google.com) and click your group.
2. Click **Group settings** in the left sidebar.
3. Find **External members** and turn **Allow external members** on.
<img
src="/images/user-guide/emails/inbound-channels/google-03-allow-external-members.png"
style={{ width: '100%' }}
/>
Google turns this off for the whole organization by default, so expect it to be locked the first time. If you see the notice shown above, only a Workspace admin can unlock it, by allowing group owners to add external members across the organization. Ask them, then return here.
4. Scroll down to **Who can post** and drag the slider all the way to the right, onto the globe. That is **Anyone on the web**.
<img
src="/images/user-guide/emails/inbound-channels/google-04-who-can-post.png"
style={{ width: '100%' }}
/>
Without this, mail from outside your company never reaches the group, so it never reaches Twenty either. This is also blocked across the organization by default, and again only an admin can change it.
5. Click **Save changes**.
<Warning>
If the group carries Google's **Security** label, stop here. Google does not
allow non-Google accounts in a security group, and the label is permanent once
applied. Create a new group without it.
</Warning>
## Part 3: Add Twenty to the group
1. Click **Members** in the left sidebar.
2. Click **Add members**.
<img
src="/images/user-guide/emails/inbound-channels/google-02-members-add-button.png"
style={{ width: '100%' }}
/>
3. Paste the forwarding address you copied from Twenty into **Group members**.
4. Leave **Subscription** on **Each email**. This is what makes Google send every message through.
5. Leave **Directly add members** ticked, so Google adds the address rather than sending an invitation that cannot be accepted.
6. Click **Add members**.
<img
src="/images/user-guide/emails/inbound-channels/google-05-add-forwarding-address.png"
style={{ width: '100%' }}
/>
That completes the setup. Twenty is now a member of the group like any other.
## If you do not have a group yet
1. In [Google Groups](https://groups.google.com), click **Create group**.
2. Fill in the **Group name** and the **Group email** prefix.
<img
src="/images/user-guide/emails/inbound-channels/google-01-create-group.png"
style={{ width: '100%' }}
/>
3. Click **Next** twice, then **Create group**.
4. Now follow Part 2 and Part 3.
## Part 4: Test it
Send an email from an outside address (a personal Gmail works) to `sales@yourcompany.com`. It should appear in Twenty within a minute or two.
## Troubleshooting
<Accordion title="An error occurred: 1 user is outside of your organization">
The group does not accept external members. Return to Part 2, step 3. If the
setting is locked, only a Workspace admin can unlock it.
<img
src="/images/user-guide/emails/inbound-channels/google-06-external-member-error.png"
style={{ width: '100%' }}
/>
</Accordion>
<Accordion title="The group receives mail but Twenty does not">
Open the member in the group and check its subscription is **Each email**, not
**No email**, **Digest** or **Abridged**.
</Accordion>
<Accordion title="Colleagues' emails arrive but customers' emails do not">
**Who can post** is not set to **Anyone on the web**. See Part 2, step 4.
</Accordion>
<Accordion title="The channel receives mail but cannot send">
Receiving and sending are separate. Sending requires your domain to be
verified under the channel's **Sending domain** section, which means adding
the DNS records Twenty lists there.
</Accordion>
Using a different provider? See [Microsoft 365](/user-guide/calendar-emails/how-tos/forward-a-shared-inbox-from-microsoft-365) or [any other mail provider](/user-guide/calendar-emails/how-tos/forward-a-shared-inbox-from-any-mail-provider).

View File

@@ -0,0 +1,143 @@
---
title: Forward a Shared Inbox from Microsoft 365
description: Send mail from a Microsoft 365 shared mailbox into a Twenty email channel.
---
An email channel gives your workspace a shared address, like `contact@yourcompany.com`. Mail sent to that address has to reach Twenty somehow. You do that by forwarding the mailbox to the private address Twenty gives you.
Setup has two halves: create the channel in Twenty, then point Microsoft at it.
## Part 1: Create the channel in Twenty
1. Go to **Settings → Communication**.
2. Click **Add email channel**.
<img
src="/images/user-guide/emails/inbound-channels/03-twenty-add-email-channel.png"
style={{ width: '100%' }}
/>
3. In **Source Email Address**, type the shared address you want to receive mail at, for example `contact@yourcompany.com`.
4. In **Display Name**, type the name recipients see, for example `Twenty Contact`.
5. Click **Save**.
<img
src="/images/user-guide/emails/inbound-channels/04-twenty-new-channel-form.png"
style={{ width: '100%' }}
/>
6. Twenty now shows a **Forwarding address**. It looks like `ch_2cd282d193b5@inbound.twenty.com`. Click **Copy**.
<img
src="/images/user-guide/emails/inbound-channels/05-twenty-forwarding-address.png"
style={{ width: '100%' }}
/>
<Note>
Each channel gets its own forwarding address. Never point two mailboxes at the
same one, or their mail will land in the same place.
</Note>
## Part 2: Create the shared mailbox
Skip this part if `contact@yourcompany.com` already exists in Microsoft 365.
1. Open the [Exchange admin center](https://admin.cloud.microsoft/exchange).
2. Go to **Recipients → Mailboxes**.
3. Click **Add a shared mailbox**.
<img
src="/images/user-guide/emails/inbound-channels/01-exchange-add-shared-mailbox.png"
style={{ width: '100%' }}
/>
4. Fill in the **Display name**.
5. Fill in the **Email address** and pick your domain.
6. Click **Create**. It takes a minute to appear in the list.
<img
src="/images/user-guide/emails/inbound-channels/02-exchange-shared-mailbox-form.png"
style={{ width: '100%' }}
/>
## Part 3: Forward the mailbox to Twenty
1. In **Recipients → Mailboxes**, click the mailbox to open it.
2. Click **Email forwarding**.
<img
src="/images/user-guide/emails/inbound-channels/06-exchange-email-forwarding-link.png"
style={{ width: '100%' }}
/>
3. Turn **Forward all emails sent to this mailbox** on.
4. Choose **Forward to an external email address** and paste the forwarding address you copied from Twenty.
5. Tick **Deliver message to both forwarding address and mailbox** so your team keeps a copy in Outlook.
6. Click **Save**.
<img
src="/images/user-guide/emails/inbound-channels/07-exchange-manage-forwarding.png"
style={{ width: '100%' }}
/>
<img
src="/images/user-guide/emails/inbound-channels/08-exchange-forwarding-saved.png"
style={{ width: '100%' }}
/>
Microsoft says changes can take up to 5 minutes to apply.
## Part 4: Allow forwarding to external addresses
This step is easy to miss. Without it, no mail reaches Twenty.
By default, Microsoft 365 blocks automatic forwarding to addresses outside your organization. The mail is rejected and the original sender receives a bounce that reads:
```
5.7.520 Access denied, Your organization does not allow external forwarding.
```
To allow it:
1. Open the [Microsoft Defender portal](https://security.microsoft.com).
2. Go to **Email & collaboration → Policies & rules → Threat policies → Anti-spam**.
3. Open your **Anti-spam outbound policy**, or create a new one that applies only to your shared mailboxes.
4. Click **Edit protection settings**.
5. Set **Automatic forwarding rules** to **On - Forwarding is enabled**.
6. Save.
<Warning>
Turning this on for your whole tenant lets any compromised account forward
mail out. Create a policy scoped to only the shared mailboxes you are
connecting, rather than editing the default one.
</Warning>
## Part 5: Test it
Send an email from an outside address (a personal Gmail works) to `contact@yourcompany.com`. It should appear in Twenty within a minute or two.
## Troubleshooting
<Accordion title="Senders get a 5.7.520 bounce">
External forwarding is still blocked. Repeat Part 4 and confirm the policy you
edited applies to this mailbox.
</Accordion>
<Accordion title="Nothing arrives, and there is no bounce either">
Compare the forwarding address in Exchange character for character with the
one in Twenty. A single wrong character means the mail is delivered nowhere
useful and silently dropped.
</Accordion>
<Accordion title="Mail no longer appears in Outlook">
**Deliver message to both forwarding address and mailbox** was left unticked.
Tick it and save.
</Accordion>
<Accordion title="The channel receives mail but cannot send">
Receiving and sending are separate. Sending requires your domain to be
verified under the channel's **Sending domain** section, which means adding
the DNS records Twenty lists there.
</Accordion>
Using a different provider? See [Google Workspace](/user-guide/calendar-emails/how-tos/forward-a-shared-inbox-from-google-workspace) or [any other mail provider](/user-guide/calendar-emails/how-tos/forward-a-shared-inbox-from-any-mail-provider).

View File

@@ -0,0 +1,46 @@
---
title: I Don't See Emails on Records
description: Troubleshooting missing emails on records.
---
## Common Reasons
### 1. Initial Sync Still in Progress
Email sync takes time, especially for large mailboxes. Twenty imports emails at approximately **400 messages per minute** (limited by Gmail API rate limiting).
- **Calendar sync**: Completes in minutes
- **Email sync**: Depends on mailbox size (e.g., 10,000 emails ≈ 25 minutes, 50,000 emails ≈ 2 hours)
**Solution**: Wait for the initial import to complete. You can estimate timing based on your mailbox size.
### 2. Contact Doesn't Exist in Twenty
Emails only appear on existing People records. If the contact wasn't created yet:
- Enable **Contact Auto-Creation** in your mailbox settings
- Or manually create the Person record first
**Solution**: Go to **Settings → Accounts**, select your mailbox, and enable contact auto-creation.
### 3. Internal Emails Are Excluded
Emails between colleagues (same email domain) are never synced to maintain privacy.
**Solution**: This is expected behavior. Only external emails are synced.
### 4. Email Is from a Group or Distribution List
Group emails and distribution lists are excluded from sync.
**Solution**: This is expected behavior.
### 5. Folder Not Selected for Sync
If you're using the Message Folder feature, some folders might be excluded.
**Solution**: Go to **Settings → Accounts**, select your mailbox, and check folder sync settings.
### 6. Wrong Email Address on Record
The Person record might have a different email address than the one used in the email.
**Solution**: Add the correct email address to the Person record.
## Still Not Working?
1. Try disconnecting and reconnecting your mailbox
2. Contact support if issues persist

View File

@@ -0,0 +1,58 @@
---
title: Limit Emails Imported
description: Control which emails are imported into Twenty.
---
## Overview
By default, Twenty syncs all external emails from your connected mailbox. You can limit what gets imported using **folder selection** and **visibility settings**.
## Method 1: Folder Selection (Recommended)
Control which email folders sync with Twenty:
1. Go to **Settings → Accounts**
2. Select your connected email account
3. Choose which folders to sync:
| Folder | Description |
|--------|-------------|
| **Inbox** | Primary incoming emails |
| **Sent** | Outgoing emails you've sent |
| **Archive** | Archived messages |
| **Custom Folders** | Any specific folders you want |
4. Exclude folders you don't want synced (Spam, Trash, personal folders)
<Note>This gives you precise control over which emails appear in your CRM without syncing everything.</Note>
## Method 2: Contact Auto-Creation Settings
Control when contacts are created from emails:
1. Go to **Settings → Accounts**
2. Select your connected mailbox
3. Choose an option:
- **Deactivated**: No contacts created, but emails still sync to existing contacts
- **Sent & Received**: Create contacts from all external emails
- **Sent Only**: Only create contacts from emails you send
## Internal Emails
Messages between colleagues (same domain) can be synchronized in Twenty:
1. Go to **Settings → General → Security**
2. Toggle **Sync Internal Emails** on/off
<Note>By default, this option is turned off.</Note>
## What's Always Excluded
These emails are never synced, regardless of settings:
- **Group emails**: Distribution lists and group messages
- **Spam/Trash**: System folders are typically excluded
## Important Note
<Note>We don't provide a CC email address for selective syncing yet. Use the folder selection feature above to achieve the same level of control.</Note>

View File

@@ -0,0 +1,135 @@
---
title: Calendar & Emails
description: Connect your email and calendar accounts to Twenty.
---
## Connection Options
### Google Account (Gmail & Google Calendar)
1. Go to **Settings → Accounts**
2. Click **Add account**
3. Select **Continue with Google**
4. Authorize Twenty to access your Gmail and Google Calendar
5. Configure email sync settings (visibility, auto-creation) → click **Next**
6. Configure calendar sync settings (visibility, auto-creation) → click **Add Account**
7. Your emails and calendar events will start syncing automatically
### Microsoft Account (Outlook & Microsoft Calendar)
1. Go to **Settings → Accounts**
2. Click **Add account**
3. Select **Continue with Microsoft**
4. Authorize Twenty to access your Outlook and Microsoft Calendar
5. Configure email sync settings (visibility, auto-creation) → click **Next**
6. Configure calendar sync settings (visibility, auto-creation) → click **Add Account**
7. Your emails and calendar events will start syncing automatically
### IMAP/SMTP/CalDAV Setup (Other Providers)
For other email and calendar providers:
1. Go to **Settings → Accounts**
2. Configure IMAP settings to sync incoming email and SMTP settings to send email
3. Configure CalDAV settings for calendar
4. Test the connection
<Note>
**Self-hosting on an internal network**: By default, Twenty refuses outbound connections to private/internal IP addresses (SSRF protection). If your mail, calendar or identity provider server runs on a local/private IP (e.g. an on-premise server on a LAN), connections to it will be blocked. To allow them, list the hostnames or IP literals in the following environment variable on the server:
```
OUTBOUND_HTTP_ALLOWED_INTERNAL_HOSTS=mail.internal,keycloak,192.168.1.10
```
Entries are matched on the hostname only (`keycloak`, not `http://keycloak:8080/realms/…`), without wildcards. Every other outbound request (HTTP workflow actions, webhooks, SSO and IMAP/SMTP/CalDAV connections) stays protected, and even an allowed host can never reach the cloud metadata address range. Set it to `*` to disable the protection entirely, which is only appropriate on trusted, isolated networks. If you previously set `OUTBOUND_HTTP_SAFE_MODE_ENABLED=false`, remove it: while it is set, the protection stays fully off and the list is ignored.
</Note>
### Multiple Mailboxes
- **Unlimited Accounts**: Connect multiple email accounts per user
- **Account Management**: Switch between different mailboxes
- **Sync Settings**: Configure different settings per mailbox
<Warning>
Only true mailboxes can be connected (e.g., support@domain.com with its own inbox). Email aliases that forward to another mailbox cannot be connected to Twenty.
</Warning>
## Email Configuration
### Message Visibility
Choose different levels of visibility for your emails:
- **Metadata Only**: Share only basic information (sender, recipient, date, time)
- **Subject and Metadata**: Share subject line along with metadata
- **All Email Content**: Share entire email content including attachments
### Contact Auto-Creation
- **Deactivated**: No automatic contact creation
- **For messages sent and received**: Create contacts for all external email interactions
- **For messages sent only**: Create contacts only for emails you send
- **Note**: By default, internal emails (where all participants share your domain) are not synced to protect privacy
<Note>When enabled, contacts are automatically linked to their Company records based on their email domain. If the company doesn't exist yet, Twenty creates it for you.</Note>
<Note>
**Syncing internal emails**: The "internal emails not synced" behavior is the default, but it can be turned off. The toggle lives in advanced settings:
1. Open **Settings** and enable the **Advanced** toggle at the bottom of the settings page
2. Go to **General → Security**
3. Enable the **Sync Internal Emails** toggle to include emails where all participants share the same domain
This is a workspace-wide setting (useful for universities or shared-domain organizations).
</Note>
### Control which emails get synced with Message Folder Selection
Control which email folders sync with Twenty:
1. Go to **Settings → Accounts** and select your connected email account
2. Choose which folders to sync:
- **Inbox**: Primary incoming emails
- **Sent**: Outgoing emails you've sent
- **Custom Folders**: Any specific folders you want to include
- **Exclude Folders**: Skip folders like Spam, Trash, or personal folders
This gives you precise control over which emails appear in your CRM without syncing everything.
**What Gets Synced:**
- **External Emails**: All emails with external contacts from selected folders
- **Internal Emails**: Not synced by default (same domain emails remain private). Enable the **Advanced** toggle at the bottom of **Settings**, then turn on **Sync Internal Emails** under **General → Security** to include them workspace-wide.
- **Attachments**: Coming in H1 2026
**Note**: We don't provide a CC email address for selective syncing. Instead, use the Message Folder feature above to achieve the same level of control over which emails sync with Twenty.
## Calendar Configuration
### Event Visibility
Choose what will be visible to other users in your workspace:
- **Everything**: The whole event's details will be shared with your team
- **Metadata**: Only date and participants will be shared with your team
### Contact Auto-Creation for Meetings
- **Yes**: Automatically create contacts for meeting participants not in your CRM
- **No**: Only link meetings to existing contacts
<Note>When enabled, contacts are automatically linked to their Company records based on their email domain. If the company doesn't exist yet, Twenty creates it for you.</Note>
### Control which events get synced
- **Meeting Import**: Automatically import calendar events
- **Contact Linking**: Link meetings to People and Company records
**What Gets Synced:**
- **Meetings**: Calendar events with external participants
- **Contact Linking**: Events automatically linked to CRM records
- **Team Events**: Shared calendar visibility
## Sync Frequency
**Updates every 5 minutes**: Both email and calendar data sync automatically every 5 minutes after the initial import.
<Note>
**Initial sync timing**: Calendar sync completes quickly (usually within minutes), while email sync takes longer for large mailboxes. Twenty imports emails at approximately **400 messages per minute** (limited by Gmail API rate limiting), so a mailbox with 10,000 emails takes about 25 minutes. Don't worry if you see contacts from calendar events appearing before your email contacts; this is normal behavior.
</Note>
## Next Steps
- [Mailbox capabilities](/user-guide/calendar-emails/capabilities/mailbox)
- [Troubleshoot missing emails](/user-guide/calendar-emails/how-tos/i-dont-see-emails-on-records)

View File

@@ -0,0 +1,271 @@
---
title: Chart Settings
description: Configure your charts to display data exactly how you need it.
---
import { ChartIcon } from '/snippets/chart-icon.mdx';
## Accessing Chart Settings
1. Click the **Edit** button in the top-right corner of your dashboard
<img src="/images/user-guide/dashboard/dashboard-edit.png" alt="Edit mode" />
2. The dashboard enters edit mode
3. Click on any widget to select it
4. The settings panel opens on the right
Settings are organized into sections:
- **Data**: What data to pull and how to filter it
- **X axis**: How to group and sort categories (bar/line charts)
- **Y axis**: What to measure and how to display it (bar/line charts)
- **Style**: Colors, labels, and visual options
<Note>
Some settings only appear when other settings are configured. For example, **Date granularity** only appears when you select a date field.
</Note>
---
## Data Settings
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="database" />Source </span>
Choose which object to pull data from.
1. Click **Source**
2. Select an object (Opportunities, People, Companies, etc.)
All your standard and custom objects are available. Changing the source resets other settings since field options depend on the selected object.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-source.png" alt="Source" />
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="filter" />Filter </span>
Limit which records are included in the chart.
1. Click **Filter**
2. The filter builder opens
3. Click **+ Add filter**
4. Select a field, condition, and value
5. Add more filters as needed
Filters work the same as in table views. Use them to focus on specific segments of your data.
**Example**: Filter opportunities where Stage equals "Won" to show only closed deals.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-filters.png" alt="Filter" />
<Tip>
For date fields, try **Is relative** to create dynamic filters like "Past 7 days" or "This month" that automatically update.
</Tip>
<Tip>
Advanced filters are supported—add multiple filter rules and combine them with **And** or **Or** logic.
</Tip>
---
## X Axis Settings
These settings control the horizontal axis of bar and line charts—typically how your data is grouped into categories.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="axis-x" />Data on display </span>
Select the field to group your data by. This determines the categories shown on the X axis.
**Example**: Select "Stage" to see data grouped by pipeline stage, or "Created date" to see data over time.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-x-data-on-display.png" alt="Data on display" />
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="calendar" />Date granularity </span>
When grouping by a date field, choose the time period for grouping.
| Option | Groups data by | Example output |
|--------|---------------|----------------|
| **Day** | Each calendar day | Jan 1, Jan 2, Jan 3... |
| **Week** | Calendar weeks | Week 1, Week 2, Week 3... |
| **Month** | Calendar months | January, February, March... |
| **Quarter** | Fiscal quarters | Q1, Q2, Q3, Q4 |
| **Year** | Calendar years | 2023, 2024, 2025 |
| **Day of week** | Weekday (aggregated) | Monday, Tuesday... (all Mondays combined) |
| **Month of year** | Month (aggregated) | January, February... (all Januaries combined) |
| **Quarter of year** | Quarter (aggregated) | Q1, Q2, Q3, Q4 (all Q1s combined) |
The "of week/year" options aggregate across all time. Use **Day of week** to see which weekday typically gets the most deals. Use **Month** to see trends month by month.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="arrows-sort" />Sort by </span>
Control the order of categories on the X axis.
- **Position** – Uses the order defined in your Select field settings
- **Alphabetical** – A to Z (or chronological for dates)
- **By value** – Ordered by the metric (highest or lowest first)
- **Manual** – Drag to set your own order
<img src="/images/user-guide/dashboard/dashboard-chart-settings-x-sort.png" alt="Sort by" />
**Tip**: For pipeline stages, use **Position** to show stages in your sales process order (Lead → Qualified → Proposal → Won).
<Note>
The options shown depend on your field type. Select fields have all options; date and text fields show fewer.
</Note>
<Tip>
With **Manual** sorting, drag categories to create a custom order—perfect for highlighting specific segments or telling a story with your data.
</Tip>
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="eye-off" />Omit zero values </span>
Hide categories that have zero or no data.
- **On**: Categories with no records are hidden
- **Off**: All categories are shown, even if empty
Use this to clean up charts with sparse data.
---
## Y Axis Settings
These settings control what you're measuring and how it's displayed.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="axis-y" />Data on display </span>
Select the field and operation to calculate your metric.
- **Counts** – Count all, Count empty, Count not empty, Count unique values
- **Math** – Sum, Average, Min, Max (number fields)
- **Percentages** – Percent empty, Percent not empty
Boolean fields add Count true/false. Aggregate charts with date fields show Earliest/Latest.
**Example**: Select "Amount" with Sum to see total deal value per category, or Count all to see number of deals.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-y-data-on-display.png" alt="Data on display" />
<Note>
The options shown depend on your field and chart type. If you don't see an expected operation, check your field type.
</Note>
### Ratio
For Select, Multi-select, or Boolean fields, you can calculate the percentage of a specific value.
1. Select a Select, Multi-select, or Boolean field
2. Enable **Ratio**
3. Choose the option to measure
**Example**: Show "Won" deals as a percentage of all opportunities. If you have 10 Won out of 50 total, the chart shows 20%.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="filters" />Group by </span>
Add a second dimension to create multiple series (multiple bars or lines).
1. Set your X axis field first
2. Click **Group by**
3. Select a second field
**Example**: Group deals by Stage (X axis) AND by Owner (Group by) to see each person's pipeline breakdown side by side.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-y-group-by.png" alt="Group by" />
When Group by is set, you'll see multiple colors in your chart and a legend appears.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="calendar" />Date granularity </span>
When Group by is a date field, choose the time period (same options as X axis).
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="arrows-sort" />Sort by </span>
When **Group by** is set, control the order of grouped series (e.g., which owner's bar appears first within each category).
Same options as X axis sorting—Position, Alphabetical, and Manual—except **value-based sorting is not available** for secondary grouping.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="chart-bar-popular" />Cumulative </span>
Show running totals instead of individual values.
- **Off**: Each bar/point shows its own value
- **On**: Each bar/point shows the sum of all previous values plus its own
**Example**: January = 10, February = 15
- Cumulative off: Shows 10 and 15
- Cumulative on: Shows 10 and 25 (10 + 15)
Use cumulative to track progress toward a goal over time.
<img src="/images/user-guide/dashboard/dashboard-chart-settings-y-cumulative.png" alt="Cumulative" />
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="math-min" />Min range / <ChartIcon icon="math-max" />Max range </span>
Set fixed minimum and maximum values for the Y axis.
- Leave blank for automatic scaling
- Enter a number to fix the boundary
**When to use:**
- Set Min to 0 for accurate visual comparisons
- Set both for consistent scales across multiple charts
- Focus on a specific value range by setting both
---
## Style Settings
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="color-swatch" />Colors </span>
Set the color scheme for your chart. Choose from a variety of color palettes.
<Note>
When grouping by a Select field, the chart automatically uses the colors defined for each option in your field settings.
</Note>
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="gizmo" />Axis name </span>
Choose which axis labels to show: **None**, **X axis**, **Y axis**, or **Both** (bar and line charts only).
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="stack-2" />Stacked bars / Stacked lines </span>
When Group by is set, choose how multiple series are displayed.
- **Off (Grouped)**: Series appear side by side. Use when comparing exact values between groups.
- **On (Stacked)**: Series stack on top of each other. Use when showing composition—how parts make up a whole.
**Example**: Deals by stage, grouped by owner
- Grouped: See each owner's exact numbers side by side
- Stacked: See total deals per stage, with each owner's contribution stacked
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="badge-2k" />Data labels </span>
Show values directly on chart elements (bars, points, slices).
- **On**: Values appear on the chart
- **Off**: No values shown (cleaner look)
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}> <ChartIcon icon="text-caption" />Legend </span>
Show or hide the legend (only appears when Group by is set).
- **On**: Legend shows what each color represents
- **Off**: No legend displayed
<Tip>
**Hover** over a legend item to highlight that group. **Click** to temporarily hide it from the chart.
</Tip>
---
## Chart-Specific Notes
### Pie charts
- <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="chart-pie" size={16} /></span> **Each slice represents** – Define how slices are grouped
- <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="eye-off" size={16} /></span> **Hide empty category** – Remove zero-value slices
- <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="number-123" size={16} /></span> **Show value in center** – Display the aggregate value (sum, average, count, etc.)
### Aggregate charts
- <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="caret-left" size={16} /></span> **Prefix** – Add text before the number (e.g., `$`)
- <span style={{ display: 'inline-flex', verticalAlign: 'middle' }}><ChartIcon icon="caret-right" size={16} /></span> **Suffix** – Add text after the number (e.g., `%`)

View File

@@ -0,0 +1,84 @@
---
title: Dashboards
description: Create and organize dashboards with tabs to visualize your CRM data.
---
## Overview
Dashboards in Twenty are organized in a hierarchy: **Dashboards → Tabs → Widgets**. Each dashboard can contain multiple tabs, and each tab contains widgets (charts, numbers, iFrames).
## Creating a Dashboard
1. Go to **Dashboards** in the sidebar
2. Click **+ New Record**
<img src="/images/user-guide/dashboard/dashboard-create-new.png" alt="Create a new dashboard" />
3. Give your dashboard a name
4. Start adding tabs and widgets
## Working with Tabs
Tabs help you organize your dashboard into logical sections.
### Creating Tabs
1. In edit mode, click **+** in the tab bar, and a side panel will open on the right
2. Name your tab (e.g., "Pipeline Overview", "Team Performance")
3. Add widgets to the tab
### Reordering Tabs
1. In edit mode, click and hold on the tab you want to move
2. Drag and drop to the new position
3. You can also click on the tab and use the command menu to move the tab to the left or right
### Deleting Tabs
1. In edit mode, click on the tab you want to delete
2. Click the **Delete** button in the command menu
### Duplicating Tabs
1. Click on the tab you want to duplicate
2. Click the **Duplicate** button in the side panel
<img src="/images/user-guide/dashboard/dashboard-tabs.png" alt="Dashboard tab" />
## Dashboard Layout
### Arranging Widgets
- Drag and drop to position
- Resize for emphasis
- Group related charts together
### Duplicating a Dashboard
1. Select the dashboard you want to duplicate
2. Open the command bar with **Cmd + K** (or **Ctrl + K** on Windows)
3. Select **Duplicate dashboard**
<img src="/images/user-guide/dashboard/dashboard-duplicate.png" alt="Duplicate a dashboard" />
### Best Practices
- **Logical flow**: Arrange from overview to detail
- **Visual hierarchy**: Larger charts for key metrics
- **Consistent styling**: Use matching colors and fonts
## Visibility & Access
### Dashboard Visibility
Dashboards are visible to everyone who has access to your Twenty workspace. There is no private dashboard option at the moment.
### Favorites
You can add dashboards to your favorites for quick access. This is a personal setting—your favorites are not visible to other users.
To add a dashboard to favorites, open the dashboard and click the star icon.
### Timezone Behavior
Dashboards currently display data based on the timezone of the user viewing them. This means the same dashboard may show different metrics for team members in different regions (e.g., APAC vs. US).
<Note>
**Coming soon**: We will add the ability to set a specific timezone for a dashboard, so all users see consistent data regardless of their location.
</Note>
<Note>
**Coming soon**: Dashboard-level filters will allow you to apply filters across all widgets at once, making it faster to explore your data.
</Note>

View File

@@ -0,0 +1,159 @@
---
title: Widgets
description: Explore the widget types and visualization options in Twenty.
---
import { ChartIcon } from '/snippets/chart-icon.mdx';
## Available Widgets
Twenty provides various widget types to visualize your CRM data.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="chart-bar-popular" />Bar Charts</span>
Display data as horizontal or vertical bars.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-bar-chart.png" alt="Bar chart" />
</Frame>
**Best for:**
- Comparing values across categories
- Showing rankings
- Tracking metrics by time period
**Example uses:**
- Deals by stage
- Revenue by sales rep
- Contacts added per month
<Note>
**Display limits**: Bar charts can show a maximum of 100 bars, and 50 groups per bar when using Group By. If you see the warning "Undisplayed data: max X bars per chart", add filters to narrow down your data or change the grouping (e.g., group by week instead of days).
</Note>
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="chart-pie" />Pie Charts</span>
Show proportions of a whole.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-pie-chart.png" alt="Pie chart" />
</Frame>
**Best for:**
- Showing composition or distribution
- Comparing parts to whole
- Highlighting major segments
**Example uses:**
- Deal distribution by source
- Contact breakdown by industry
- Pipeline composition by owner
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="chart-line" />Line Charts</span>
Display trends over time.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-line-chart.png" alt="Line chart" />
</Frame>
**Best for:**
- Tracking changes over time
- Identifying trends
- Comparing multiple metrics
**Example uses:**
- Monthly deal count trend
- Revenue growth over quarters
- Activity levels over time
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="sum" />Aggregate Charts</span>
Display single key values prominently.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-aggregate-chart.png" alt="Aggregate chart" />
</Frame>
**Best for:**
- Highlighting KPIs
- Showing totals or averages
- Quick status checks
**Example uses:**
- Total pipeline value
- Number of open opportunities
- Conversion rate
**Advanced options:**
- **Ratio**: For Select fields, calculate ratios between values. Go to **Data on display** → select your field → enable the **Ratio** option.
- **Prefix & Suffix**: Add custom text before or after the number (e.g., "$" prefix or "%" suffix) for better readability.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="frame" />iFrames</span>
Embed external tools and content directly in your dashboard.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-table.png" alt="Table chart"/>
</Frame>
**Best for:**
- Searching individual items
- Checking exact values
- Auditing or reference
**Example uses:**
- Deals closing this month
- New leads this week
- Overdue invoices
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="table" />Table</span>
See filtered records directly in your dashboard.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-iframe.png" alt="iFrame" />
</Frame>
**Best for:**
- Displaying external reports or dashboards
- Integrating third-party sales tools
- Showing live content from other systems
**Example uses:**
- Metrics from your Support tool
- Metrics from your dialer
- Live content from your Sales sequence tool
#### Editing records
Dashboard table and kanban widgets are read-only by default. To let users edit records from a widget:
1. Edit the dashboard
2. Select the widget
3. Turn on **Allow editing** in the widget settings
For tables, this enables cell editing. For kanban boards, it enables editing cards, moving them between columns, and creating records. Role permissions still apply.
### <span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}><ChartIcon icon="align-box-left-top" />Rich Text</span>
Add formatted text and content directly to your dashboard.
<Frame>
<img src="/images/user-guide/dashboard/dashboard-widget-rich-text.png" alt="Rich text" />
</Frame>
**Best for:**
- Adding context or instructions
- Dashboard descriptions
- Notes and annotations
**Features:**
- Rich text formatting (bold, italic, lists, etc.)
- Image and file uploads
- Markdown-style editing
<Note>
**Coming soon**: Gauge charts are not yet available but are on our roadmap.
</Note>
### Duplicating Widgets
1. Click on the widget
2. Open **Options**
3. Click **Duplicate widget**

View File

@@ -0,0 +1,55 @@
---
title: Dashboards FAQ
description: Frequently asked questions about dashboards in Twenty.
---
<AccordionGroup>
<Accordion title="Can I create private dashboards?">
No, dashboards are currently visible to everyone with access to your Twenty workspace. Private dashboards are not yet available.
</Accordion>
<Accordion title="Why do my metrics look different from my colleague's?">
Dashboards currently display data based on the viewer's timezone. If you're in different regions (e.g., APAC vs. US), you may see slightly different numbers for the same dashboard. We're working on adding a timezone setting per dashboard to ensure consistent data across teams.
</Accordion>
<Accordion title="Can I export my dashboard?">
Exporting dashboards is not available at the moment. This feature is on our roadmap.
</Accordion>
<Accordion title="Can I share dashboards with external users?">
No, sharing dashboards with users outside your Twenty workspace (non-Twenty users) is not currently supported.
</Accordion>
<Accordion title="How do I add a dashboard to my favorites?">
Open the dashboard you want to favorite, then click the star icon. Favorites are personal—they won't affect other users.
</Accordion>
<Accordion title="What's the difference between tabs and widgets?">
- **Tabs** organize your dashboard into sections (like pages within the dashboard)
- **Widgets** are the individual visualizations (charts, numbers, iFrames) within each tab
Structure: Dashboard → Tabs → Widgets
</Accordion>
<Accordion title="Can I filter an entire dashboard at once?">
Dashboard-level filters are not available yet, but this feature is on our roadmap. Currently, you need to apply filters to each widget individually.
</Accordion>
<Accordion title="Are gauge charts available?">
Not yet. Gauge charts are on our roadmap and will be added in a future release.
</Accordion>
<Accordion title="How do I duplicate a dashboard?">
1. Make sure you're in view mode (not editing)
2. Open the command bar with **Cmd + K** (or **Ctrl + K** on Windows)
3. Select **Duplicate dashboard**
</Accordion>
<Accordion title="How often does dashboard data refresh?">
Widgets update automatically as your CRM data changes:
- Real-time updates for most metrics
- Use the refresh button for a manual update if needed
- Historical data is preserved for trend analysis
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,67 @@
---
title: Widget FAQ
description: Common questions and error messages explained.
---
<AccordionGroup>
<Accordion title="How do I show percentages instead of counts?">
Three options:
- **Percent empty/not empty**: Under Data on display, select Percent empty or Percent not empty
- **Ratio**: For Select or Checkbox fields, enable Ratio to show a specific option as a percentage of all records
- **Suffix**: For aggregate charts, add `%` as a Suffix in Style settings
</Accordion>
<Accordion title="What's the difference between grouped and stacked bars?">
When using **Group by**, you can display series two ways:
- **Grouped**: Bars side by side—best for comparing exact values
- **Stacked**: Bars on top of each other—best for showing composition
Toggle **Stacked** in Style settings to switch.
</Accordion>
<Accordion title="Why can't I see Sum or Average options?">
Available operations depend on **field type**:
- **Number fields**: Sum, Average, Min, Max
- **Date fields**: Earliest, Latest (aggregate charts only)
- **Checkbox fields**: Count true, Count false
If you don't see an option, check that you've selected a compatible field type.
</Accordion>
<Accordion title="Why are some settings grayed out or missing?">
Many settings only appear when prerequisites are met:
- **Date granularity**: Select a date field first
- **Group by, Legend, Stacked**: Set Source first
- **Legend, Stacked toggles**: Set Group by first
If a setting is missing, configure its prerequisite first.
</Accordion>
<Accordion title="What does 'No data' mean?">
The chart found no records matching your configuration.
**To fix:** Remove or adjust filters, verify you selected the correct Source object, or check that records exist for your date range.
</Accordion>
<Accordion title="What does 'Invalid configuration' mean?">
A required setting is missing or incompatible.
**To fix:** Ensure Source is set, Data on display is configured, and any required grouping fields are selected.
</Accordion>
<Accordion title="What does 'Undisplayed data' mean?">
Your data exceeds display limits (100 bars, 100 data points, or 100 slices).
**To fix:** Add filters to narrow your data, or change date granularity from Day to Week or Month.
</Accordion>
<Accordion title="Why is one axis showing no data?">
The selected field has no values for the records in your filter, or the field type doesn't match the expected data.
**To fix:** Try a different field, or check that records have values for the selected field.
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,68 @@
---
title: Dashboards
description: Learn the basics of reporting and dashboards in Twenty.
---
## Understanding Dashboards
Dashboards in Twenty provide a visual way to track your key performance metrics and gain insights from your CRM data.
<img src="/images/user-guide/dashboard/dashboards_v2.png" alt="Dashboards" />
## Key Concepts
### Dashboards
A dashboard is a collection of tabs that display your CRM data at a glance. You can create multiple dashboards for different purposes:
- Sales performance
- Team activity
- Pipeline health
- Custom metrics
### Tabs
Tabs allow you to organize your dashboard into sections. Each tab contains one or more widgets.
### Widgets
Widgets are individual visualizations that display specific data. Types include:
- Bar charts
- Pie charts
- Line charts
- Aggregate charts
- iFrames
- Rich text
<Note>
**Current limitations**:
- Exporting dashboards and sharing with external users (non-Twenty users) are not available at the moment.
- Gauge charts are not yet available.
</Note>
## Getting Started
### Creating Your First Dashboard
1. Navigate to the **Dashboards** section
2. Click **+ New Dashboard**
3. Give your dashboard a name
4. Add tabs to organize your content
5. Add widgets to display your data
6. Save
### Adding Widgets
1. Open a tab on your dashboard
2. Click **+ Add Widget**
3. Select the widget type
4. Choose the data source (object)
5. Configure the widget settings
6. Save and view your widget
## Best Practices
- **Start simple**: Begin with a few key metrics and add more over time
- **Focus on actionable data**: Display metrics that drive decisions
- **Regular review**: Check your dashboards regularly to spot trends
- **Share with team**: Make dashboards visible to relevant team members
## Next Steps
- [Widgets and visualizations](/user-guide/dashboards/capabilities/widgets)
- [Chart settings reference](/user-guide/dashboards/capabilities/chart-settings)
- [Dashboards FAQ](/user-guide/dashboards/how-tos/dashboards-faq)

View File

@@ -0,0 +1,70 @@
---
title: Error Handling & Validation
description: Review and fix import errors directly in the UI before confirming.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Pre-Import Validation
After uploading your file and mapping fields, Twenty validates your data **before** importing. This allows you to catch and fix errors without affecting your existing data.
## How It Works
1. **Upload** your CSV file
2. **Map** your columns to Twenty fields
3. **Review** the potential errors highlighted in yellow
4. **Fix errors** directly in the UI
5. **Confirm** the import
<VimeoEmbed videoId="1145273857" title="Video demonstration" />
## Error Display
Rows with issues are highlighted in **yellow**. You can:
- **Edit the cell directly** to fix the error
- **Remove the row** to skip it entirely
This inline editing saves time — no need to go back to your spreadsheet, fix errors, and re-upload.
## Common Error Types
### Duplicate Values
**Cause**: A unique field (email, domain) already exists in Twenty or appears twice in your file.
**Fix**:
- Edit the duplicate value in the import UI
- Remove one of the duplicate rows
See [Uniqueness Constraints](/user-guide/data-migration/capabilities/uniqueness-constraints) for more details on how uniqueness is enforced.
### Invalid Format
**Cause**: Data doesn't match the expected format (e.g., invalid email, wrong date format).
**Fix**: Edit the cell to use the correct format.
See [Field Mapping](/user-guide/data-migration/capabilities/field-mapping) for the expected format of each field type.
### Missing Required Fields
**Cause**: A required field is empty.
**Fix**: Enter a value in the required field or remove the row.
### Relation Not Found
**Cause**: The referenced record doesn't exist (e.g., a Company domain that wasn't imported).
**Fix**:
- Import the parent records first
- Or correct the reference value
See [Import Relations](/user-guide/data-migration/capabilities/import-relations) for the correct import order and how to link records.
## Tips for Fewer Errors
1. **Download the template** to see the expected format prior to importing your file
2. **Clean your data** in the spreadsheet first
3. **Import files in correct order** to import relations (Companies → People → Opportunities)
4. **Test with small batches** before full import
5. **Check for duplicates** before uploading
6. **Limit each file to 10,000 records**

View File

@@ -0,0 +1,164 @@
---
title: Field Mapping
description: How field mapping works during data import.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## How Field Mapping Works
When you upload a file, Twenty analyzes your columns and attempts to match them to existing fields.
### Automatic Mapping
Twenty tries to match columns based on:
- Column header names (exact or similar matches)
- Data type detection (dates, numbers, emails)
- Common field patterns
<Note>**Quick tip:** Export a few rows from the object you want to import. The exported file will have the exact column names Twenty expects, making automatic mapping seamless during import.</Note>
### Manual Mapping Options
For each column, you can:
- **Map to a field**: Select the matching Twenty field from a dropdown
- **Do not map**: Skip the column entirely (data won't be imported)
<Note>**Fields must exist before import.** The import creates records, not fields. Create custom fields under **Settings → Data Model** before importing.</Note>
## Field Type Compatibility
All field types available in the Data Model are supported for import.
You can also import `id` values to either assign a specific ID to new records or update existing ones.
<img src="/images/user-guide/fields/all-field-types.png" style={{width:'100%'}}/>
## Data Format Requirements
<Note>**Some fields have special syntax.** We recommend downloading the sample file before preparing your import to see the expected syntax for each field type.</Note>
### Address Fields
Address is a nested field with multiple columns. Some can be left empty.
- **Address / Address 1**: Street address line 1
- **Address / Address 2**: Street address line 2
- **Address / City**: City name
- **Address / State**: State or province
- **Address / Country**: Country name
- **Address / Post Code**: Postal/ZIP code
### Array Fields
Use the following format:
```
["value1","value2"]
```
### Boolean Fields
Use `TRUE` or `FALSE` (uppercase) - not `true` or `false`
### Currency Fields
Currency is a nested field with two columns that **both must be filled**:
- **Amount / Amount**: The numeric value (e.g., `1234.56`)
- **Amount / Currency**: The currency code (e.g., `USD`, `EUR`)
### Date Fields
Supported formats:
- `YYYY-MM-DD` (recommended)
- `MM/DD/YYYY`
- `DD/MM/YYYY`
- ISO 8601 format
### Domain Fields
- It is recommended to use the format `https://domain.com` to avoid creating duplicates, as this is the format used for Companies created by the mailbox and calendar synchronizations
- A `Domain Label` and `Domain URL` can be filled: best practice is to fill `domain.com` in the label and `https://domain.com` in the url
- Domains must be unique within the Companies object
- **Domains must be unique within the file to import**
### Email Fields
- Must be valid email format
- Emails must be unique within the People object
- **Emails must be unique within the file to import**
- For additional emails: use **Emails / Primary Email** for the main email, and **Emails / Additional Emails** with this format:
```
["jane@twenty.com","jane.doe@twenty.com"]
```
### ID Fields
Specifying an `id` during import is optional. Twenty auto-generates one if not provided.
Use cases for mapping an `id` column:
- **Set a specific ID**: Choose the UUID for newly created records
- **Update existing records**: Match against existing records to update them instead of creating duplicates. In that case, it is recommended to not map the other unique fields: mapping only one unique field ensures a smoother import.
<Note>If you provide an `id`, it must be in UUID format (e.g., `c776ee49-f608-4a77-8cc8-6fe96ae1e43f`).</Note>
### JSON Fields
Use valid JSON format:
```
{"key":"value","key2":"value2"}
```
### Links Fields
Similar to Domain fields:
- Fill both the label and URL columns: **Links / Link URL** and **Links / Link Label**
- Use full URL format: `https://example.com`
- For secondary links, use **Links / Secondary Links** column with this format:
```
[{"url":"https://twenty.com","label":"Twenty"}]
```
### Multi-Select Fields
Use the **API names** (not the display labels) in the following format:
```
["VALUE1","VALUE2"]
```
See [here](#finding-api-names-for-select-fields) where to find the API names.
<Note>New select options will not be created automatically by the import. They must be added under **Settings → Data Model** before importing.</Note>
<Warning>
**Import overwrites; it does not add.**
If a record already has `VALUE2` and `VALUE3` selected, and you import `["VALUE1"]`, the record will only have `VALUE1` after import. The previous selections are replaced, not merged.
</Warning>
### Number Fields
- Numbers only
- Decimals use period: `1234.56`
- No thousands separators
### Phone Fields
Phone is a nested field with multiple columns that **must be filled**
- **Phones / Primary Phone Number**: The phone number (e.g., `4159095555`)
- **Phones / Primary Phone Country Code**: Country code (e.g., `US`)
- **Phones / Primary Phone Calling Code**: Dialing code (e.g., `+1`)
### Rating Fields
Use the API name format: `RATING_1`, `RATING_2`, `RATING_3`, `RATING_4`, `RATING_5`
### Relation Fields
Please see our dedicated article: [Import Relations Between Objects](/user-guide/data-migration/capabilities/import-relations)
### Select Fields
Use the **API name** of the option (not the display label):
```
VALUE1
```
See [here](#finding-api-names-for-select-fields) where to find the API names.
<Note>New select options will not be created automatically by the import. They must be added under **Settings → Data Model** before importing.</Note>
### Text Fields
- No special formatting required
- Leading/trailing spaces are trimmed
## Finding API Names
For Select, Multi-Select, and Array fields with predefined options, you must use the **API names**, not the display labels.
### How to Find API Names
1. Go to **Settings → Data Model**
2. Select the object and field
3. Enable **Advanced mode** (toggle at the bottom right of the settings page)
4. View the API name for each option
<VimeoEmbed videoId="1144910809" title="Video demonstration" />

View File

@@ -0,0 +1,47 @@
---
title: Supported File Formats
description: File formats supported for data import in Twenty.
---
## Supported Formats
Twenty supports three file formats for import:
| Format | Extension | Notes |
|--------|-----------|-------|
| **CSV** | .csv | Recommended, most compatible |
| **Excel** | .xlsx | Modern Excel format |
| **Excel (Legacy)** | .xls | Older Excel format |
## File Requirements
| Requirement | Value |
|-------------|-------|
| **Encoding** | UTF-8 recommended |
| **Record limit** | 10,000 records per file |
| **Structure** | First row must contain column headers |
| **Content** | One object type per file |
## CSV Best Practices
- **Delimiter**: Use comma (`,`) or semicolon (`;`)
- **Text qualifier**: Use double quotes (`"`) for text containing commas
- **Line endings**: Windows (CRLF) or Unix (LF) both supported
- **Empty values**: Leave cells empty, don't use "NULL" or "N/A"
## Excel Best Practices
When exporting from Excel:
- Remove formulas (export values only)
- Delete empty rows at the end
- Ensure no merged cells
- Use the first sheet only
## Large Datasets
For datasets larger than 10,000 records:
- Split into multiple files
- Or use the [API import](/user-guide/data-migration/how-tos/import-data-via-api) for unlimited records
<Note>For very large migrations (100,000+ records), the API is significantly faster and more reliable than CSV imports.</Note>

View File

@@ -0,0 +1,141 @@
---
title: Import Relations Between Objects
description: Import relationships between records via CSV.
---
## Overview
Twenty supports importing relationships between objects during CSV import. This allows you to link records (e.g., attach People to Companies) as part of your data migration.
<Note>**Currently supported for import**: One-to-many relations pointing to a single object type on each side (e.g., People → Companies). Relations pointing to multiple object types are not yet supported in import/export.</Note>
## How Relations Work in Twenty
### One to Many / Many to One
Twenty supports standard relations where one record links to many others:
- **One Company → Many People**: A company can have multiple employees, but each person belongs to one company
- **One Company → Many Opportunities**: A company can have multiple deals, but each opportunity belongs to one company
### Relations That Can Point to Multiple Object Types
Some relations can connect to different types of objects. This works in two ways:
**Pattern 1: Many records linking to one record each from different object types**
Several Notes or Tasks can each be attached to multiple object types at once:
- **Notes** can be linked to one Person, one Company, and one Opportunity simultaneously
- **Tasks** can be linked to one Person, one Company, and one Opportunity simultaneously
Here, the Notes/Tasks are on the "many" side. Each links to one record per object type.
<img src="/images/user-guide/fields/many-to-one-morph.png" style={{width:'100%'}}/>
**Pattern 2: One record receiving links from many records of different object types**
A Project can receive links from multiple records across different object types:
- **A Project** can have many People linked to it, many Companies linked to it, and many Notes attached to it
Here, the Project is on the "one" side. Multiple records from different objects can all link to the same Project.
<img src="/images/user-guide/fields/one-to-many-morph.png" style={{width:'100%'}}/>
<Warning>
**Import/Export limitation**: Relations that point to multiple object types (like Notes → People/Companies/Opportunities) are **not yet supported** in CSV import or export.
- **Import**: Only one-to-many relations pointing to a single object type on each side can be imported
- **Export**: Columns for relations pointing to multiple object types are currently left empty
This is on our roadmap.
</Warning>
### What's Not Supported Today
**Many to Many relations** are not yet available. For example, you cannot currently create a relation where:
- Many People are linked to many Projects
<Note>Many to Many relations are planned for H2 2026.</Note>
## Linking Records During Import
<Note>**Reminder**: Only one-to-many relations pointing to a single object type can be imported (e.g., People → Companies). Relations pointing to multiple object types (e.g., Notes → People/Companies/Opportunities) are not yet supported.</Note>
### Step 1: Identify the "One" and "Many" Sides
First, determine which object is on the "one" side and which is on the "many" side of the relationship.
**Example**:
- **Company** is the "one" side (one company has many employees)
- **People** is the "many" side (each person belongs to one company)
### Step 2: Ensure the "One" Side Records Exist
Before importing the "many" side, the "one" side records must already exist in Twenty.
- Import or create the "one" side records first (e.g., Companies)
- Validate their unique identifier. This can be:
- The `id` (Twenty's UUID)
- A field set as unique (e.g., `domain` for Companies, or an external ID from your previous system)
<Warning>The import will fail if a reference is made to a record that does not exist.</Warning>
### Step 3: Prepare Your CSV File
Add a column in your "many" side CSV file that references the "one" side record.
**Example**: For a People CSV file linking to Companies:
```
firstName,lastName,email,companyDomain
John,Smith,john@acme.com,https://acme.com
Jane,Doe,jane@widgets.co,https://widgets.co
```
**Important**:
- The value must **exactly match** the unique field on the Company record
- For domains, use the **Domain URL** (e.g., `https://acme.com`), not the Domain Label
- Map only **one** unique identifier per relation: this leads to a smoother import
### Step 4: Ensure the Relation Field Exists
Before uploading your file, make sure the relation field exists between your objects.
If it doesn't exist:
1. Go to **Settings → Data Model**
2. Select your object (e.g., People)
3. Create a relation field pointing to the target object (e.g., Company)
### Step 5: Upload and Map the Relation
1. Upload your CSV file via the import UI
2. In the field mapping step, find your relation column (e.g., `companyDomain`)
3. Map it to the relation field (e.g., Company)
4. Twenty will automatically link each record to the matching parent
### Available Unique Fields for Relations
| Object | Unique Fields Available |
|--------|------------------------|
| **Companies** | `id`, `domain`, any custom unique field |
| **People** | `id`, `email`, any custom unique field |
| **Workspace Members** | `id`, `email` (not name) |
| **Other standard and custom objects** | `id`, any field marked as unique |
<Note>**Linking to Workspace Members**: When the relation points to Workspace Members (your team logging into Twenty), reference them by their **email address**, not their name.</Note>
<Note>We recommend using `domain` for Companies and `email` for People, as these are human-readable and easy to maintain in spreadsheets.</Note>
<Note>**Reminder**: Soft-deleted records (visible under Command Menu → See deleted records) count toward uniqueness criteria. If you import a record with the same unique value as a deleted record, the deleted record will be restored. See [Uniqueness Constraints](/user-guide/data-migration/capabilities/uniqueness-constraints) for more details.</Note>
## Import Order Rule
<Warning>
**Always import the "one" side first!**
1. **Companies** first (no dependencies)
2. **People** second (linked to Companies)
3. **Opportunities** third (linked to Companies/People)
4. **Custom objects** following their dependencies
The parent record must exist before you can reference it.
</Warning>

View File

@@ -0,0 +1,68 @@
---
title: Uniqueness Constraints
description: How Twenty enforces data uniqueness during import.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Overview
Twenty enforces uniqueness on certain fields to prevent duplicate records and ensure data integrity. Understanding these constraints is essential for successful imports.
## Default Unique Fields
| Object | Unique Fields |
|--------|---------------|
| **People** | `id`, `email` |
| **Companies** | `id`, `domain` |
| **Custom objects** | `id` only (by default) |
<Note>The `id` field is Twenty's internal identifier, auto-generated for each record. It uses UUID format (e.g., `c776ee49-f608-4a77-8cc8-6fe96ae1e43f`).</Note>
## Custom Unique Fields
You can define additional unique fields under **Settings → Data Model**:
1. Go to **Settings → Data Model**
2. Select the object
3. Click on a field
4. Enable **Unique** in field settings
### Use Cases for Custom Unique Fields
- **External IDs**: Store IDs from other systems (Salesforce ID, HubSpot ID)
- **Business identifiers**: Employee numbers, customer codes
- **Alternative contact info**: LinkedIn profile, phone number
<Note>The field name `id` is reserved for Twenty's internal ID. Use a different name like `externalId` or `legacyId` for external identifiers.</Note>
## Import Behavior
### Creating New Records
If a unique field value doesn't exist, a new record is created.
### Updating Existing Records
If a unique field value matches an existing record, that record is **updated** with the new data.
<Warning>To **update existing records**, it is recommended to **only match one unique field**.</Warning>
### Soft-Deleted Records
<Warning>
**Deleted records count toward uniqueness.**
Soft-deleted records (visible under Command Menu → See deleted records) are included in uniqueness checks. If you import a record with the same unique value as a deleted record, the deleted record will be **restored** with the new data.
</Warning>
## Duplicate Detection During Import
During the validation phase:
- Duplicates within your file are highlighted in yellow
- You can edit or remove duplicate rows from the UI before starting the import
<VimeoEmbed videoId="1145246326" title="Video demonstration" />
## Best Practices
1. **Remove duplicates** from your file before importing
2. **Check for existing records** in Twenty before importing
3. **Use external IDs** when migrating from other systems
4. **Include unique fields** if you want to update existing records

View File

@@ -0,0 +1,32 @@
---
title: Export FAQ
description: Frequently asked questions about exporting data.
---
<AccordionGroup>
<Accordion title="Can we export all workspace data before cancellation, including custom objects, custom fields, relationships, notes, tasks, opportunities, attachments, workflows, permissions, and audit history?">
Workspace data can be exported before cancellation with some exceptions: dashboards, workflows and permissions must be transferred manually; audit logs cannot be transferred.
</Accordion>
<Accordion title="Which elements cannot currently be exported or migrated?">
Most elements can be exported or migrated with some exceptions:
- workflows, dashboards and all settings (API keys, webhooks, audit logs, user settings, etc.) must be migrated manually
- app-created objects and fields can be migrated by installing said app in a different workspace. They shouldn't be migrated manually
- some records, like workflow versions and workflow runs, are not transferable at all and are expected to be lost
- some objects like message and calendar related objects shouldn't be exported as they're created when an account is connected and synced periodically. They'll be synchronized again once you connect your account (as long as you have access to said account, if it's an account of a team member who left your company, then those messages must be exported, otherwise they'll be lost)
</Accordion>
<Accordion title="Is there an official cloud to self-hosted migration procedure or an assisted migration service?">
As of now, there is no official cloud-to-self-hosted migration procedure. The general idea is to:
- first, install apps to introduce app-owned objects and fields
- replicate custom objects and fields added by users
- use a script with API keys or AI tools to migrate all data from one workspace to another
- all non-transferrable objects must be migrated manually
Please be aware of a few things:
- you can send up to 50 requests per minute on the Pro plan or 100 requests per minute on the Organization plan before hitting a request/min limit
- each API request can have up to 200 records
- some data in fields like Created by, Timeline activities and Updated by will be lost during import and overwritten by the system
</Accordion>
<Accordion title="Are exported files provided in open and documented formats?">
Exported files in the UI are in Excel format, and all API requests can be saved in JSON format.
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,186 @@
---
title: Export Your Data
description: Complete step-by-step guide to exporting data from Twenty.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Overview
Export your workspace data to CSV for backups, reporting, or migration.
**Use cases:**
- **Regular backups** — keep copies of your data
- **External reporting** — analyze data in Excel, Google Sheets, or BI tools
- **Migration** — move data to another system
- **Bulk updates** — export, edit, and re-import to update records
## What You Need to Know
### Export Limits
- **Maximum 20,000 records** per export
- Only **visible columns** are exported
- Only **filtered records** are exported (based on your current view)
<Note>For larger exports (20,000+ records), use filters to export in batches or use the [API](/developers/extend/api).</Note>
### Permissions
You need the **"Export CSV"** permission to export data. Contact your workspace admin if you don't have this option.
## Step 1: Navigate to the Object
Go to the object you want to export:
- **People** — for contacts
- **Companies** — for organizations
- **Opportunities** — for deals
- **Custom objects** — any object you've created
## Step 2: Configure Your View
**Important:** The export includes only what's visible in your current view.
### Add/Remove Columns
1. Click **Options → Fields** (or the **+** at the end of columns)
2. Check the fields you want to export
3. Uncheck fields you don't need
### Filter Records (Optional)
If you only need a subset of data:
1. Click **Filter**
2. Add filter conditions (e.g., "Created date > January 1, 2024")
3. Only matching records will be exported
### Sort Records (Optional)
1. Click a column header to sort
2. The export will follow your sort order
<Note>**Create a dedicated export view.** Save a view specifically configured for exports so you don't need to reconfigure each time.</Note>
## Step 3: Export the Data
1. Click the **⋮** icon on the top right of the table
2. Select **Export view**
3. Choose where to save the CSV file
4. Wait for the download to complete
## What Gets Exported
| Included | Not Included |
|----------|--------------|
| All visible columns | Hidden columns |
| Records matching current filters | Filtered-out records |
| Custom field values | Fields not in the view |
| Record IDs | File attachments |
| Relation IDs | Images |
### Relation Fields
Relation IDs are only exported on the **"many" side** of a relationship:
- **People export** includes a `companyId` column (People → Company relation)
- **Companies export** does NOT include `peopleIds` (Companies is the "one" side)
This means you can use the People export to re-import and maintain the Company link, but you'll need to re-import People after Companies to recreate the relationships.
## Exporting for Specific Purposes
### For Backups
1. Create a view with **all fields** visible
2. Remove all filters to include all records
3. Export each object type separately
4. Store exports in a secure location
5. Set a recurring reminder (weekly/monthly)
### For External Reporting
1. Include only the fields you need for analysis
2. Apply filters to focus on relevant data
3. Consider sorting by the field you'll analyze
### For Bulk Updates
1. Export the records you want to update
2. Include the unique identifier (`email`, `domain`, or `id`)
3. Edit the exported file
4. Re-import to update records
See: [How to Update Existing Records](/user-guide/data-migration/how-tos/update-existing-records-via-import)
### For Migration
If you're exporting to migrate to another system:
1. **Export each object separately** — People, Companies, Opportunities, etc.
2. **Include ID fields** — these help maintain relationships
3. **Document field mappings** — note how Twenty fields map to your target system
## Handling Large Datasets (20,000+ Records)
The export limit is 20,000 records. For larger datasets:
### Option 1: Export in Batches
1. Add a filter (e.g., "Created date" ranges)
2. Export the first batch
3. Change the filter
4. Export the next batch
5. Combine files in your spreadsheet
**Example filters for batching:**
- By date range (January, February, March...)
- By owner (Team member A, Team member B...)
- By status (Active, Inactive...)
### Option 2: Use the API
The API has no record limit:
1. Get your API key from **Settings → Developers**
2. Use the GraphQL API to query records
3. Process results in your application
See: [API Documentation](/developers/extend/api)
## Tips and Best Practices
### Create Export Views
Save views configured specifically for exports:
1. Configure columns and filters
2. Click **View options** → **Save as new view**
3. Name it "Export - [Purpose]"
### Secure Your Exports
Exported files may contain sensitive data:
- Store in secure locations
- Delete old exports when no longer needed
- Be careful sharing export files
### Check Before Exporting
<Check>Correct columns are visible</Check>
<Check>Filters are set correctly (or removed for full export)</Check>
<Check>You have Export permission</Check>
## FAQ
<AccordionGroup>
<Accordion title="Why are some columns missing from my export?">
Only visible columns are exported. Add the columns you need via **Options → Fields** before exporting.
</Accordion>
<Accordion title="Why doesn't my export have all records?">
Check your filters. The export only includes records matching your current view filters. Remove filters to export all records.
</Accordion>
<Accordion title="Can I export more than 20,000 records?">
Not in a single export. Use filters to export in batches, or use the API for larger datasets.
</Accordion>
<Accordion title="What format is the export file?">
CSV (Comma Separated Values). Opens in Excel, Google Sheets, or any spreadsheet application.
</Accordion>
<Accordion title="Are relation IDs included?">
Yes, but only on the "many" side of relationships. For example, a People export includes `companyId`, but a Companies export does not include people IDs.
</Accordion>
<Accordion title="Can I automate exports?">
Not directly through the UI. Use the API to build automated export workflows.
</Accordion>
</AccordionGroup>
## Next Steps
- [How to Update Existing Records](/user-guide/data-migration/how-tos/update-existing-records-via-import) — edit and re-import your export
- [How to Import Data via API](/user-guide/data-migration/how-tos/import-data-via-api) — for large datasets
- [API Documentation](/developers/extend/api) — build custom export workflows

View File

@@ -0,0 +1,389 @@
---
title: Fix Import Errors
description: Complete troubleshooting guide for resolving CSV import errors.
---
## Overview
Import not working? This guide helps you identify and fix common import errors step by step.
## How Import Validation Works
After uploading your file and mapping columns, Twenty validates your data:
1. **Validation runs** — Twenty checks each row for errors
2. **Errors are highlighted** — problematic rows appear in **yellow**
3. **You can fix in-place** — edit cells directly in the import UI
4. **Or remove rows** — skip problematic records entirely
<Note>**Fix errors in the UI.** You don't need to go back to your spreadsheet. Edit cells directly during import to save time.</Note>
## Step-by-Step Troubleshooting
### Step 1: Identify the Error Type
Click on a highlighted row to see the specific error message. Common error types:
| Error Message | What It Means |
|---------------|---------------|
| Duplicate values highlighted in yellow | Value already exists in Twenty or appears twice in your file |
| `{field} is not a valid {type}` (hover on yellow cell) | Data doesn't match expected format |
| Required field highlighted | A required field is empty |
| `Can't connect to {object}. No unique record found...` (import fails) | Referenced record doesn't exist |
| `Too many records. Up to 10000 allowed` (upload blocked) | File has more than 10,000 records |
### Step 2: Fix the Error
Follow the specific instructions below for each error type.
---
## Error: Duplicate Value
### What You'll See
Rows with duplicate values are **highlighted in yellow** in the import UI before the import starts.
### What It Means
A unique field (email, domain) either:
- Already exists in Twenty
- Appears twice in your file
### How to Fix
**Option 1: Edit the duplicate value**
1. Click the cell with the error
2. Change to a unique value
3. Continue with import
**Option 2: Remove the duplicate row**
1. Click the X next to the row
2. The row will be skipped during import
**Option 3: Let Twenty update the existing record**
1. Ensure your file includes a unique identifier (`email`, `domain`, or `id`)
2. Map the unique identifier field
3. Twenty will update the existing record instead of creating a duplicate
<Note>
**You can update unique fields too.**
- If you keep the `id` but change the `email` → the email will be updated
- If you keep the `email` but change the `id` → the id will be updated
As long as one unique identifier matches, Twenty updates the record.
</Note>
### How to Prevent This Error
Before importing:
1. Sort your spreadsheet by the unique field
2. Remove duplicate rows
3. Check if records already exist in Twenty
<Warning>
**Soft-deleted records count toward uniqueness.**
Check Command Menu → See deleted records. Records there still enforce uniqueness. Permanently delete them or restore and update.
</Warning>
For more details: [Uniqueness Constraints](/user-guide/data-migration/capabilities/uniqueness-constraints)
---
## Error: Invalid Format
### What You'll See
The cell value is highlighted in yellow. Hover over it to see the error message:
```
{field name} is not a valid {field type}
```
### What It Means
The data doesn't match the expected format for that field type.
### How to Fix — By Field Type
#### Email
**Problem:** Invalid email format
**Solution:** Use format `name@domain.com`
```
❌ john.smith@
❌ john smith@acme.com
✓ john.smith@acme.com
```
#### Domain
**Problem:** Inconsistent format may cause duplicates
**Solution:** Use `https://domain.com` format (recommended)
```
⚠️ acme.com (valid, but not recommended)
⚠️ www.acme.com (valid, but not recommended)
✅ https://acme.com (recommended)
```
<Note>All formats are valid, but `https://domain.com` is recommended because it matches the format used by email/calendar sync. Using other formats may create duplicate companies.</Note>
#### Date
**Problem:** Unrecognized date format
**Solution:** Use `YYYY-MM-DD` format consistently throughout file
```
✓ 2024-03-15 (YYYY-MM-DD)
❌ 03/15/2024 (MM/DD/YYYY)
❌ 15/03/2024 (DD/MM/YYYY)
```
#### Phone
**Problem:** Missing required columns
**Solution:** Include all phone columns
| Column | Example |
|--------|---------|
| **Phones / Primary Phone Number** | `4159095555` |
| **Phones / Primary Phone Country Code** | `US` |
| **Phones / Primary Phone Calling Code** | `+1` |
#### Boolean
**Problem:** Wrong boolean value
**Solution:** Use uppercase `TRUE` or `FALSE`
```
❌ true
❌ yes
❌ 1
✓ TRUE
✓ FALSE
```
#### Select / Multi-Select
**Problem:** Value doesn't match existing options
**Solution:** Use **API names**, not display labels
How to find API names:
1. Go to **Settings → Data Model**
2. Select the object and field
3. Enable **Advanced mode** (toggle at bottom right)
4. Use the API name (e.g., `OPTION_1`, not "Option 1")
```
❌ High Priority
✓ HIGH_PRIORITY
```
#### Currency
**Problem:** Missing amount or currency code
**Solution:** Fill both columns
| Column | Example |
|--------|---------|
| **Amount / Amount** | `1234.56` |
| **Amount / Currency** | `USD` |
#### Number
**Problem:** Non-numeric characters
**Solution:** Numbers only, period for decimals
```
❌ $1,234.56
❌ 1,234.56
✓ 1234.56
```
For complete format reference: [Field Mapping](/user-guide/data-migration/capabilities/field-mapping)
---
## Error: Required Field Missing
### What You'll See
The row is highlighted in yellow with the required field cell marked.
### What It Means
A required field is empty for this row.
### How to Fix
**Option 1: Enter a value**
1. Click the empty cell
2. Enter a value
3. Continue with import
**Option 2: Remove the row**
1. If you don't have the data, click X to skip the row
### How to Prevent This Error
Before importing, identify required fields:
1. Go to **Settings → Data Model**
2. Select your object
3. Check which fields are marked as required
---
## Error: Relation Not Found
### What You'll See
This error appears **after the import starts** — the import fails with a message like:
```
Can't connect to company. No unique record found with condition: id = 7776ee49-f608-4a77-8cc8-6fe96ae1e43f
```
This means there is no Company in Twenty with that specific identifier.
<Note>Unlike other errors, this one is not caught during the data review step. The import will start and then fail when it encounters the missing relation.</Note>
### What It Means
You're trying to link to a record that doesn't exist in Twenty.
### How to Fix
**Option 1: Import parent records first**
1. Cancel the current import
2. Import the parent records (e.g., Companies)
3. Then import the child records (e.g., People)
**Option 2: Fix the reference value**
1. Check the reference value in your file
2. Ensure it exactly matches an existing record
3. Verify format: domains should be `https://domain.com`
**Option 3: Remove the relation**
1. Clear the cell to import without the relation
2. Add the relation manually later
### How to Prevent This Error
1. **Import in the correct order:**
- Companies first
- People second (with company references)
- Opportunities third
2. **Verify reference values:**
- Export parent records to get exact identifiers
- Use domain format `https://domain.com`
- Check for typos and case sensitivity
<Warning>
**Import will fail if a reference is made to a non-existent record.**
Always import parent objects before child objects.
</Warning>
For more details: [Import Relations](/user-guide/data-migration/capabilities/import-relations)
---
## Error: File Too Large
### What You'll See
This error appears **when uploading your file** — the upload is blocked entirely:
```
Too many records. Up to 10000 allowed
```
You won't be able to proceed to the data review step until you reduce the file size.
### What It Means
Your file has more than 10,000 records.
### How to Fix
**Option 1: Split into multiple files**
1. Divide your data into files of 10,000 records or fewer
2. Import each file separately
3. Maintain import order (Companies before People)
**Option 2: Use API import**
For very large datasets, use the API which has no record limit.
See: [How to Import Data via API](/user-guide/data-migration/how-tos/import-data-via-api)
---
## Error: Field Not Recognized
### What It Means
A column in your file can't be mapped because the field doesn't exist in Twenty.
### How to Fix
1. Go to **Settings → Data Model**
2. Select the object you're importing
3. Click **+ Add field**
4. Create the custom field with the appropriate type
5. Re-upload your file
<Note>The CSV import creates records, not fields. All fields must exist before importing.</Note>
---
## Error: User Relation Empty
### What It Means
You're trying to assign a record to a user (Owner, Assignee) but the relation isn't being mapped.
### Common Causes
1. **User hasn't accepted their invitation** — the user doesn't exist in Twenty yet
2. **Using user ID from old system** — Twenty can't match IDs from another system
3. **Wrong email format** — the email doesn't match the user's Twenty account
### How to Fix
1. Ensure all users have **accepted their invitation** to your Twenty workspace
2. Use the user's **email address** (not their name or old system ID)
3. Use the same email they used to join Twenty
<Warning>
**Users must accept invitations before importing.**
If a user hasn't accepted their invitation, records referencing them will have empty user relations.
</Warning>
---
## Pre-Import Checklist
Avoid errors by checking these before importing:
### File Requirements
<Check>File is CSV, XLSX, or XLS format</Check>
<Check>File has fewer than 10,000 records</Check>
<Check>File uses UTF-8 encoding</Check>
### Data Quality
<Check>No duplicate emails (for People)</Check>
<Check>No duplicate domains (for Companies)</Check>
<Check>All dates use consistent format</Check>
<Check>All domains use `https://domain.com` format</Check>
### Field Formats
<Check>Boolean fields use `TRUE` or `FALSE` (uppercase)</Check>
<Check>Select fields use API names, not display labels</Check>
<Check>Phone fields have all required columns</Check>
<Check>Currency fields have both Amount and Currency Code</Check>
### Relations
<Check>Parent records imported before child records</Check>
<Check>Relation columns reference existing records</Check>
<Check>Domain format matches Twenty's format exactly</Check>
### Data Model
<Check>All custom fields exist in Settings → Data Model</Check>
<Check>Select options exist before importing</Check>
---
## Still Having Issues?
If you've tried the above solutions:
1. **Download the sample file** — see the exact format Twenty expects
2. **Export existing records** — compare your file to working data
3. **Test with a small batch** — try 5-10 rows first
4. **Check the reference articles:**
- [Field Mapping](/user-guide/data-migration/capabilities/field-mapping)
- [Uniqueness Constraints](/user-guide/data-migration/capabilities/uniqueness-constraints)
- [Import Relations](/user-guide/data-migration/capabilities/import-relations)
- [Error Handling](/user-guide/data-migration/capabilities/error-handling)

View File

@@ -0,0 +1,192 @@
---
title: Import Companies via CSV
description: Complete step-by-step guide to importing companies into Twenty.
---
## Overview
This guide walks you through importing your companies into Twenty. **Companies should be imported first** because People and Opportunities link to Companies.
## Before You Start
### Prerequisites Checklist
<Check>
Your file is CSV, XLSX, or XLS format
</Check>
<Check>
File has fewer than 10,000 records
</Check>
<Check>
No duplicate domains in your file
</Check>
<Check>
All custom fields exist in **Settings → Data Model**
</Check>
<Note>
Need to import more than 10,000 companies? Split into multiple files or use the [API import](/user-guide/data-migration/how-tos/import-data-via-api).
</Note>
## Step 1: Prepare Your Company Data
### Required and Recommended Fields
| Field | Required? | Format | Notes |
|-------|-----------|--------|-------|
| **Name** | Recommended | Text | Company display name |
| **Domain** | Recommended | `https://domain.com` | Unique identifier |
| **Address** | Optional | Multiple columns | See below |
| **Employees** | Optional | Number | Employee count |
| **Custom fields** | Optional | Varies | Must exist in Data Model |
### Domain Format
<Warning>
**Use the format `https://domain.com` for domains.**
This matches the format used when Companies are auto-created from email/calendar sync, preventing duplicates later.
</Warning>
**Domain columns:**
- **Domain / Domain Label**: `acme.com`
- **Domain / Domain URL**: `https://acme.com`
### Address Format
Address is a nested field with multiple columns:
```
Address / Address 1,Address / City,Address / State,Address / Country,Address / Post Code
123 Main Street,San Francisco,CA,USA,94105
```
### Sample CSV Structure
```csv
name,Domain / Domain URL,Domain / Domain Label,Address / City,Address / Country,employees
Acme Corp,https://acme.com,acme.com,San Francisco,USA,250
Widget Co,https://widgets.co,widgets.co,New York,USA,50
```
<Note>
**Pro tip:** Click **Download sample file** during import to see the exact column names Twenty expects.
</Note>
## Step 2: Access the Import Feature
**Option 1: From the Companies View**
1. Navigate to **Companies** in the left sidebar
2. Click the **⋮** icon on the top right
3. Select **Import records**
**Option 2: Using Command Menu**
1. Press `Cmd + K` (Mac) or `Ctrl + K` (Windows)
2. Type "import"
3. Select **Import records**
4. Choose **Companies**
## Step 3: Upload Your File
1. Click **Select file**
2. Choose your CSV, XLSX, or XLS file
3. Wait for Twenty to analyze your file
## Step 4: Map Your Columns
Twenty automatically tries to match your columns to fields. Review and adjust:
1. **Check automatic mappings** — verify they're correct
2. **Fix incorrect mappings** — click the dropdown to select the right field
3. **Skip columns** — select **Do not map** for columns you don't want to import
### Important Mapping Rules
- **Domain**: Map to **Domain / Domain URL** (not Domain Label)
- **Address**: Map each part to its specific column (City, State, etc.)
- **Select fields**: Values must match existing options (or you'll map them in the next step)
<img src="/images/user-guide/import-export-data/match-columns.png" style={{width:'100%'}}/>
## Step 5: Map Select Field Values
If you have Select or Multi-Select fields:
1. Twenty shows your values alongside existing options
2. Match each value in your file to a Twenty option
3. Or create new options if needed
<Note>
Select options use **API names**, not display labels. Check **Settings → Data Model** → Enable **Advanced mode** to see API names.
</Note>
## Step 6: Review and Fix Errors
Before completing the import, Twenty validates your data:
1. Click **Next Steps**
2. Rows with errors are highlighted in **yellow**
3. **Fix errors directly** — click a cell and edit the value
4. **Remove problematic rows** — click the X to skip that row
### Common Company Import Errors
| Error | Cause | Solution |
|-------|-------|----------|
| **Duplicate domain** | Domain already exists in Twenty | Remove from file or update existing record |
| **Invalid domain format** | Wrong format | Use `https://domain.com` |
| **Missing required field** | Required field is empty | Fill in the value or remove the row |
## Step 7: Complete the Import
1. Review the import summary
2. Click **Confirm** to import
3. Wait for the import to complete
4. Verify by checking a few records
## After Importing Companies
Now you can import records that link to Companies:
1. **[Import People](/user-guide/data-migration/how-tos/import-contacts-via-csv)** — link them to Companies using the domain
2. **Import Opportunities** — link them to Companies
3. **Verify the import** — spot-check a few records to ensure data is correct
## Updating Existing Companies
To update companies instead of creating new ones:
1. Include the `domain` or `id` column in your file
2. Twenty matches records by this unique identifier
3. Existing companies are updated; new ones are created
See [How to Update Existing Records](/user-guide/data-migration/how-tos/update-existing-records-via-import) for details.
## FAQ
<AccordionGroup>
<Accordion title="Why can't two Companies have the same domain?">
Domain is a unique identifier in Twenty. This prevents duplicate companies and ensures email sync correctly links emails to the right company.
</Accordion>
<Accordion title="What if I have companies without a domain?">
You can leave the domain empty. However, we recommend adding domains when possible for better data quality and automatic email linking.
</Accordion>
<Accordion title="Can I import companies without any People linked?">
Yes! You can import companies first, then import People later and link them using the company domain.
</Accordion>
<Accordion title="What happens if I import a domain that already exists?">
If you include a unique identifier (domain or id) that matches an existing company, Twenty updates that company instead of creating a duplicate.
</Accordion>
<Accordion title="How do I fix 'duplicate domain' errors?">
Either remove the duplicate from your file, or include the company's `id` to update the existing record instead.
</Accordion>
</AccordionGroup>
## Troubleshooting
Having issues? Check:
- [How to Fix Import Errors](/user-guide/data-migration/how-tos/fix-import-errors)
- [Field Mapping Reference](/user-guide/data-migration/capabilities/field-mapping)
- [Uniqueness Constraints](/user-guide/data-migration/capabilities/uniqueness-constraints)

View File

@@ -0,0 +1,232 @@
---
title: Import Contacts via CSV
description: Complete step-by-step guide to importing people/contacts into Twenty.
---
## Overview
This guide walks you through importing your contacts (People) into Twenty.
## Before You Start
### Prerequisites Checklist
<Check>
Your file is CSV, XLSX, or XLS format
</Check>
<Check>
File has fewer than 10,000 records
</Check>
<Check>
No duplicate email addresses in your file
</Check>
<Check>
**Companies imported first** (if linking People to Companies)
</Check>
<Check>
All custom fields exist in **Settings → Data Model**
</Check>
<Warning>
**Import Companies Before People**
If you want to link People to Companies, import Companies first. The Company must exist before you can reference it.
</Warning>
## Step 1: Prepare Your Contact Data
### Required and Recommended Fields
| Field | Required? | Format | Notes |
|-------|-----------|--------|-------|
| **Email** | Recommended | `name@domain.com` | Must be unique |
| **First Name** | Recommended | Text | |
| **Last Name** | Recommended | Text | |
| **Company** | Optional | Domain or ID | Links to existing Company |
| **Phone** | Optional | Multiple columns | See below |
| **Job Title** | Optional | Text | |
| **Custom fields** | Optional | Varies | Must exist in Data Model |
### Email Format
- Must be valid email format: `name@domain.com`
- **Must be unique** — no duplicates in your file or in Twenty
- For additional emails, use the **Emails / Additional Emails** column:
```
["jane@twenty.com","jane.doe@twenty.com"]
```
### Phone Format
Phone is a **nested field** requiring multiple columns:
| Column | Example |
|--------|---------|
| **Phones / Primary Phone Number** | `4159095555` |
| **Phones / Primary Phone Country Code** | `US` |
| **Phones / Primary Phone Calling Code** | `+1` |
### Linking to Companies
Add a column with the Company's unique identifier:
| Column Name | Format | Example |
|-------------|--------|---------|
| `companyDomain` | URL format | `https://acme.com` |
| `companyId` | UUID | `c776ee49-f608-4a77-8cc8-6fe96ae1e43f` |
<Note>
**Use Domain URL format** (`https://acme.com`), not the label. This matches how Companies are stored in Twenty.
</Note>
### Sample CSV Structure
```csv
firstName,lastName,email,jobTitle,companyDomain,Phones / Primary Phone Number,Phones / Primary Phone Country Code
John,Smith,john@acme.com,CEO,https://acme.com,4159095555,US
Jane,Doe,jane@widgets.co,CTO,https://widgets.co,2125551234,US
```
<Note>
**Pro tip:** Click **Download sample file** during import or export a few existing People to see the exact column names Twenty expects.
</Note>
## Step 2: Access the Import Feature
**Option 1: From the People View**
1. Navigate to **People** in the left sidebar
2. Click the **⋮** icon on the top right
3. Select **Import records**
**Option 2: Using Command Menu**
1. Press `Cmd + K` (Mac) or `Ctrl + K` (Windows)
2. Type "import"
3. Select **Import records**
4. Choose **People**
## Step 3: Upload Your File
1. Click **Select file**
2. Choose your CSV, XLSX, or XLS file
3. Wait for Twenty to analyze your file
## Step 4: Map Your Columns
Twenty automatically tries to match your columns to fields. Review and adjust:
1. **Check automatic mappings** — verify they're correct
2. **Fix incorrect mappings** — click the dropdown to select the right field
3. **Skip columns** — select **Do not map** for columns you don't want to import
### Important Mapping Rules
| Column Type | Map To | Notes |
|-------------|--------|-------|
| Company reference | **Company** relation field | Use domain OR id, not both |
| Email | **Email** | Primary email address |
| Additional emails | **Emails / Additional Emails** | Array format |
| Phone | Separate columns | Number, Country Code, Calling Code |
<img src="/images/user-guide/import-export-data/match-columns.png" style={{width:'100%'}}/>
### Mapping the Company Relation
When mapping the company column:
1. Find your company reference column (e.g., `companyDomain`)
2. Map it to the **Company** relation field
3. Twenty will link each Person to the matching Company
<Warning>
**Map only ONE unique identifier for relations.**
Don't map both `companyId` AND `companyDomain`. Choose one—preferably domain since it's human-readable.
</Warning>
## Step 5: Map Select Field Values
If you have Select or Multi-Select fields (like Lead Source):
1. Twenty shows your values alongside existing options
2. Match each value in your file to a Twenty option
3. Or create new options if needed
<Note>
Select options use **API names**, not display labels. Check **Settings → Data Model** → Enable **Advanced mode** to see API names.
</Note>
## Step 6: Review and Fix Errors
Before completing the import, Twenty validates your data:
1. Click **Next Steps**
2. Rows with errors are highlighted in **yellow**
3. **Fix errors directly** — click a cell and edit the value
4. **Remove problematic rows** — click the X to skip that row
### Common Contact Import Errors
| Error | Cause | Solution |
|-------|-------|----------|
| **Duplicate email** | Email already exists in Twenty or file | Remove duplicate or update existing record |
| **Invalid email format** | Email format incorrect | Fix to `name@domain.com` |
| **Relation not found** | Company doesn't exist | Import Companies first or fix the reference |
| **Missing required field** | Required field is empty | Fill in the value or remove the row |
## Step 7: Complete the Import
1. Review the import summary
2. Click **Confirm** to import
3. Wait for the import to complete
4. Verify by checking a few records and their Company links
## After Importing Contacts
Your contacts are now in Twenty! Next steps:
1. **Verify Company links** — open a few People records to confirm they're linked to the right Company
2. **Import Opportunities** — if needed, link them to People and Companies
3. **Set up email sync** — connect your mailbox to see email history on contact records
## Updating Existing Contacts
To update contacts instead of creating new ones:
1. Include the `email` or `id` column in your file
2. Twenty matches records by this unique identifier
3. Existing contacts are updated; new ones are created
See [How to Update Existing Records](/user-guide/data-migration/how-tos/update-existing-records-via-import) for details.
## FAQ
<AccordionGroup>
<Accordion title="Why can't two People have the same email?">
Email is a unique identifier in Twenty. This prevents duplicate contacts and ensures email sync correctly links emails to the right person.
</Accordion>
<Accordion title="What if I have people without an email?">
You can leave the email empty. However, we recommend adding emails when possible for better data quality and email sync functionality.
</Accordion>
<Accordion title="How do I link People to Companies during import?">
Add a column with the Company's domain (e.g., `https://acme.com`) or ID. During mapping, connect this column to the Company relation field.
</Accordion>
<Accordion title="What if the Company doesn't exist yet?">
Import Companies first, then import People. The Company must exist before you can reference it.
</Accordion>
<Accordion title="Can I import the ID from my previous CRM?">
Yes! Create a custom field marked as "unique" in your data model to store the external ID. Note: the field name `id` is reserved for Twenty's internal ID.
</Accordion>
<Accordion title="How do I fix 'relation not found' errors?">
The Company you're referencing doesn't exist. Either import the Company first, or check that the domain/ID exactly matches an existing Company.
</Accordion>
</AccordionGroup>
## Troubleshooting
Having issues? Check:
- [How to Fix Import Errors](/user-guide/data-migration/how-tos/fix-import-errors)
- [How to Import Relations](/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv)
- [Field Mapping Reference](/user-guide/data-migration/capabilities/field-mapping)

View File

@@ -0,0 +1,168 @@
---
title: Import Data via API
description: When and how to use Twenty's APIs for large-scale data imports.
---
## Overview
Twenty provides both **GraphQL** and **REST APIs** for programmatic data import. Use the API when CSV import isn't practical for your data volume or when you need automated, recurring imports.
## When to Use API Import
| Scenario | Recommended Method |
|----------|-------------------|
| Under 10,000 records | CSV Import |
| 10,000 - 50,000 records | CSV Import (split into files) |
| **50,000+ records** | **API Import** |
| One-time migration | Either (based on volume) |
| **Recurring imports** | **API Import** |
| **Real-time sync** | **API Import** |
| **Integration with other systems** | **API Import** |
<Note>For datasets in the hundreds of thousands, the API is significantly faster and more reliable than multiple CSV imports.</Note>
## API Rate Limits
Twenty enforces rate limits to ensure system stability:
| Limit | Value |
|-------|-------|
| **Requests per minute** | 100 |
| **Records per batch call** | 60 |
| **Maximum throughput** | ~6,000 records/minute |
<Warning>
**Plan your import around these limits.**
For 100,000 records at maximum throughput, expect approximately 17 minutes of import time. Add buffer time for error handling and retries.
</Warning>
## Getting Started
### Step 1: Get Your API Key
1. Go to **Settings → Developers**
2. Click **+ Create API key**
3. Give your key a descriptive name
4. Copy the API key immediately (it won't be shown again)
5. Store it securely
<Warning>
**Keep your API key secret.**
Anyone with your API key can access and modify your workspace data. Never commit it to code repositories or share it publicly.
</Warning>
### Step 2: Choose Your API
Twenty supports two API types:
| API | Best For | Documentation |
|-----|----------|---------------|
| **GraphQL** | Flexible queries, fetching related data, complex operations | [API Docs](/developers/extend/api) |
| **REST** | Simple CRUD operations, familiar REST patterns | [API Docs](/developers/extend/api) |
Both APIs support:
- Creating, reading, updating, and deleting records
- **Batch operations** — create or update up to 60 records per call
**For imports, use batch operations** to maximize throughput within rate limits.
### Step 3: Plan Your Import Order
Just like CSV imports, **order matters** for relations:
1. **Companies** first (no dependencies)
2. **People** second (can link to Companies)
3. **Opportunities** third (can link to Companies and People)
4. **Tasks/Notes** (can link to any of the above)
5. **Custom objects** (following their dependencies)
## Best Practices
### Batch Your Requests
- Don't send records one at a time
- Group up to **60 records per API call**
- This maximizes throughput within rate limits
### Handle Rate Limits
- Implement delays between requests (600ms minimum for sustained imports)
- Use exponential backoff when you hit limits
- Monitor for 429 (Too Many Requests) responses
### Validate Data First
- Clean and validate your data before importing
- Check required fields are populated
- Verify formats match Twenty's requirements (see [Field Mapping](/user-guide/data-migration/capabilities/field-mapping))
### Log Everything
- Log every record imported (including IDs)
- Log errors with full context
- This helps debug issues and verify completion
### Test First
- Test with a small batch (10-20 records)
- Verify data appears correctly in Twenty
- Then run the full import
### Upsert to Avoid Duplicates
The GraphQL API supports **batch upsert** — update if the record exists, create if not. This prevents duplicates when re-running imports.
## Finding Object and Field Names
To see available objects and fields:
1. Go to **Settings → API and Webhooks**
2. Browse the **Metadata API**
3. View all standard and custom objects with their fields
The documentation shows all standard and custom objects, their fields, and the expected data types.
## Professional Services
For complex API migrations, our partners can help:
| Service | What's Included |
|---------|-----------------|
| **Data Model Design** | design your optimal data structure |
| **Migration Scripts** | write and run the import scripts |
| **Data Transformation** | handle complex mapping and cleanup |
| **Validation & QA** | verify the migration is complete |
**Best for:**
- Migrations of 100,000+ records
- Complex data transformations
- Tight timelines
- Teams without developer resources
Contact us at [contact@twenty.com](mailto:contact@twenty.com) or explore our [Implementation Services](/user-guide/getting-started/capabilities/implementation-services).
## FAQ
<AccordionGroup>
<Accordion title="What's the difference between GraphQL and REST?">
GraphQL lets you request exactly the data you need in a single query and is better for complex operations. REST uses standard HTTP methods (GET, POST, PUT, DELETE) and may be more familiar if you've worked with traditional APIs.
</Accordion>
<Accordion title="Can I update existing records via API?">
Yes! Use update mutations (GraphQL) or PUT/PATCH requests (REST) with the record's `id`.
</Accordion>
<Accordion title="How do I handle duplicates?">
Query for existing records first using unique identifiers (email, domain). Update if exists, create if not.
</Accordion>
<Accordion title="Can I delete records via API?">
Yes, use delete mutations (GraphQL) or DELETE requests (REST).
</Accordion>
<Accordion title="Is there a Python or Node.js SDK?">
Not currently, but both APIs work with any HTTP client in any language.
</Accordion>
</AccordionGroup>
## API Documentation
For full implementation details, code examples, and schema reference:
- [API Documentation](/developers/extend/api)

View File

@@ -0,0 +1,218 @@
---
title: Import Relations Between Objects via CSV
description: Complete step-by-step guide to linking records during CSV import.
---
## Overview
This guide walks you through importing relations between objects—for example, linking People to Companies, or Opportunities to People.
<Note>**What can be imported:** Only one-to-many relations pointing to a single object type. Relations pointing to multiple object types (like Notes linking to People AND Companies) are not yet supported for import.</Note>
## Understanding Relations
### What is a "One-to-Many" Relation?
In a one-to-many relation:
- **One** Company has **many** People (employees)
- **One** Company has **many** Opportunities
- **One** Person has **many** Tasks
The "one" side is the **parent**. The "many" side is the **child**.
### Common Relations in Twenty
| Relation | "One" Side (Parent) | "Many" Side (Child) |
|----------|---------------------|---------------------|
| Companies → People | Company | People |
| Companies → Opportunities | Company | Opportunities |
| People → Tasks | Person | Tasks |
| People → Notes | Person | Notes |
## Step 1: Identify the "One" and "Many" Sides
Before importing, determine which object is the parent and which is the child.
**Ask yourself:** "Does ONE [Object A] have MANY [Object B]?"
- One Company → Many People ✓ (Company is parent)
- One Person → Many Companies ✗ (This is wrong—a person belongs to one company)
## Step 2: Import the Parent Records First
The parent ("one" side) must exist in Twenty before you can reference it.
**Import order:**
1. **Companies** first (no dependencies)
2. **People** second (link to Companies)
3. **Opportunities** third (link to Companies and/or People)
4. **Tasks/Notes** (link to any of the above)
<Warning>
**If the parent record doesn't exist, the import will fail.**
Always verify that Companies are imported before importing People with company references.
</Warning>
## Step 3: Note the Parent's Unique Identifier
You need to reference the parent record using a **unique identifier**. Available options:
| Parent Object | Available Unique Identifiers |
|---------------|------------------------------|
| **Companies** | `id` (UUID), `domain` (recommended), or any custom unique field |
| **People** | `id` (UUID), `email`, or any custom unique field |
| **Workspace Members** | `id` (UUID), `email` (not name) |
| **Custom Objects** | `id` (UUID), or any field marked as unique |
<Note>**Recommended:** Use `domain` for Companies and `email` for People. These are human-readable and easy to verify in your spreadsheet.</Note>
### Finding the Identifier
If you need the `id`:
1. Export the parent records from Twenty
2. The export includes the `id` column
3. Use these IDs in your child records file
## Step 4: Verify the Relation Field Exists
Before importing, ensure the relation field exists between your objects.
**To check or create:**
1. Go to **Settings → Data Model**
2. Select your child object (e.g., People)
3. Look for a relation field pointing to the parent (e.g., Company)
4. If it doesn't exist, create it:
- Click **+ Add field**
- Select **Relation** type
- Choose the parent object
## Step 5: Prepare Your CSV File
Add a column to your child CSV that references the parent using its unique identifier.
### Example: People Linking to Companies
**Your People CSV:**
```csv
firstName,lastName,email,jobTitle,companyDomain
John,Smith,john@acme.com,CEO,https://acme.com
Jane,Doe,jane@widgets.co,CTO,https://widgets.co
Bob,Johnson,bob@techstart.io,Developer,https://techstart.io
```
The `companyDomain` column references the Company's domain.
### Format Requirements
| Identifier | Format | Example |
|------------|--------|---------|
| Domain | URL format | `https://acme.com` |
| Email | Standard email | `john@acme.com` |
| ID | UUID | `c776ee49-f608-4a77-8cc8-6fe96ae1e43f` |
<Warning>
**Domain format matters!**
Use `https://domain.com` (not just `domain.com`). This matches how Twenty stores Company domains and prevents matching errors.
</Warning>
### Important Rules
1. **Exact match required** — the value must exactly match the parent record
2. **Map only ONE unique identifier** — don't include both `companyId` AND `companyDomain`
3. **Case sensitive** — `Acme.com` ≠ `acme.com`
## Step 6: Upload and Map the Relation
1. Navigate to the child object (e.g., People)
2. Click **⋮** → **Import records**
3. Upload your CSV file
4. In the field mapping step:
- Find your relation column (e.g., `companyDomain`)
- Map it to the **Company** relation field
5. Complete the remaining mapping
6. Review errors and confirm
Twenty will automatically link each child record to the matching parent.
## Step 7: Verify the Import
After importing:
1. Open a few child records (e.g., People)
2. Verify the relation field shows the correct parent (e.g., Company)
3. Open a parent record and check the related records section
## Common Mistakes to Avoid
| Mistake | Problem | Solution |
|---------|---------|----------|
| **Wrong import order** | Importing People before Companies | Always import parents first, then children |
| **Wrong domain format** | Using `acme.com` instead of `https://acme.com` | Use full URL format with `https://` |
| **Multiple unique fields** | Mapping both `companyId` AND `companyDomain` | Map only ONE unique identifier |
| **Missing relation field** | The relation field doesn't exist in the data model | Create it in **Settings → Data Model** before importing |
| **Non-existent records** | The parent record doesn't exist in Twenty | Import parent records first, or check for typos |
| **Case mismatch** | `Acme.com` in file but `acme.com` in Twenty | Ensure exact case matching |
## Linking to Workspace Members
When linking to Workspace Members (your team):
- Use their **email address**, not their name
- Example: `owner@yourcompany.com`, not "John Smith"
```csv
taskName,assignedTo
Follow up with client,john@yourcompany.com
Review proposal,jane@yourcompany.com
```
## FAQ
<AccordionGroup>
<Accordion title="What if my parent record doesn't have a domain or email?">
You have two options:
1. Use the Twenty `id` (export parent records to get their IDs)
2. Create a custom unique field in your data model to store an external ID from your previous system
</Accordion>
<Accordion title="Can I update relations on existing records?">
Yes! Include the child record's unique identifier (e.g., `email` for People) and the new relation value. The import will update the relation.
</Accordion>
<Accordion title="Can I import Many-to-Many relationships?">
Many-to-Many relations are not yet supported for import. This is planned for H1 2026.
</Accordion>
<Accordion title="Can I link to multiple object types (like Notes to People AND Companies)?">
Relations pointing to multiple object types are not yet supported for import/export. This is on our roadmap.
</Accordion>
<Accordion title="What happens if a parent record doesn't exist?">
The import will show an error for that row. You can either:
- Import the parent record first, then re-import
- Fix the reference value
- Remove the row from import
</Accordion>
<Accordion title="Why is my relation not linking correctly?">
Common causes:
- Wrong format (use `https://domain.com` for domains)
- Case mismatch (check exact spelling)
- Parent doesn't exist (import parents first)
- Mapping multiple identifiers (use only one)
</Accordion>
</AccordionGroup>
<Warning>
**Remember: Soft-deleted records count toward uniqueness.**
If you're getting "not found" errors but the record seems to exist, check Command Menu → See deleted records. The parent may have been soft-deleted.
</Warning>
## Troubleshooting
Having issues? Check:
- [How to Fix Import Errors](/user-guide/data-migration/how-tos/fix-import-errors)
- [Import Relations Capabilities](/user-guide/data-migration/capabilities/import-relations)
- [Uniqueness Constraints](/user-guide/data-migration/capabilities/uniqueness-constraints)

View File

@@ -0,0 +1,274 @@
---
title: Migrating from Other CRMs
description: Step-by-step guide to migrate your data from any CRM to Twenty.
---
## Overview
This guide walks you through migrating your data from any CRM to Twenty. The process involves auditing your data, preparing your Twenty workspace, exporting from your current system, and importing into Twenty.
<Note>Views, workflows, and permissions must be recreated manually after migration. Plan time for this configuration work.</Note>
## Step 1: Audit Your Current Data
Migration is an opportunity for a fresh start. Don't bring over clutter.
**What to keep:**
- Active contacts and companies
- Open opportunities and deals
- Important notes and activities
- Custom fields you actually use
**What to leave behind:**
- Outdated contacts (no activity in 2+ years)
- Duplicate records
- Test data
- Unused custom fields
## Step 2: Map Your Data Model
Create a mapping document between your current CRM and Twenty:
| Your CRM | Twenty |
|----------|--------|
| Account / Organization | **Company** |
| Contact / Person | **People** |
| Deal / Opportunity | **Opportunity** |
| Activity | **Task** or **Note** |
| Custom Object | **Custom Object** |
**For each field, document:**
- The source field name
- The target Twenty field
- Any format transformations needed (dates, phone numbers, etc.)
<Note>Keep this mapping document handy during import—you'll reference it when mapping columns.</Note>
## Step 3: Set Up Your Twenty Workspace
Before importing data, prepare your Twenty workspace:
### Create Custom Objects and Fields
1. Go to **Settings → Data Model**
2. Create any custom objects you need
3. Add custom fields to standard and custom objects
4. Configure field settings (unique, required, select options, etc.)
<Warning>
**Fields must exist before import.**
The CSV import creates records, not fields. Create all custom fields in Settings → Data Model before importing.
</Warning>
### Invite Your Team
<Warning>
**Invite users BEFORE importing data.**
If your data includes user references (Account Owner, Assignee, etc.), those users must exist in Twenty before import. Otherwise, those relations cannot be mapped.
</Warning>
1. Go to **Settings → Members**
2. Invite all team members
3. **Wait for everyone to accept** their invitation
4. Verify all users appear in your Members list
## Step 4: Export from Your Current CRM
Export your data from your current CRM:
1. Look for an **Export** function (usually under Settings, Data Management, or Admin)
2. Export to **CSV format** when possible
3. Export each object type separately (Companies, Contacts, Deals, etc.)
4. Include all fields you want to migrate
**Export these objects (in this order for reference):**
1. Companies / Accounts / Organizations
2. Contacts / People
3. Deals / Opportunities
4. Notes and Activities
5. Custom objects
## Step 5: Clean and Format Your Data
Open each exported CSV in a spreadsheet application and prepare it for Twenty.
### Remove Duplicates
1. Sort by the unique field (email for People, domain for Companies)
2. Remove or merge duplicate rows
3. Verify no duplicates exist in Twenty already
### Format Fields Correctly
| Field Type | Required Format |
|------------|-----------------|
| **Domain** | `https://domain.com` |
| **Email** | `name@domain.com` (must be unique) |
| **Date** | `YYYY-MM-DD` |
| **Phone** | Three columns: Number, Country Code, Calling Code |
| **Boolean** | `TRUE` or `FALSE` (uppercase) |
| **Select fields** | Use API names, not display labels |
<Warning>
**Domain format is critical.**
Use `https://domain.com` (not `domain.com` or `www.domain.com`). This matches Twenty's format and prevents duplicates when you connect email/calendar sync.
</Warning>
See [How to Prepare Your CSV Files](/user-guide/data-migration/how-tos/prepare-your-csv-files) for complete formatting requirements for all field types.
### Add Relation Columns
To link records (e.g., People to Companies), add a column with the parent's unique identifier.
**Example: People CSV with Company link**
```csv
firstName,lastName,email,companyDomain
John,Smith,john@acme.com,https://acme.com
Jane,Doe,jane@widgets.co,https://widgets.co
```
See [How to Import Relations](/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv) for detailed instructions on linking records.
### Update User References
If your data includes user assignments (Owner, Assignee):
1. Add a column with the **user's email** (not just their ID from the old system)
2. Use the same email addresses that users used to join your Twenty workspace
See [How to Prepare Your CSV Files](/user-guide/data-migration/how-tos/prepare-your-csv-files) for complete formatting guide.
## Step 6: Import to Twenty
<Warning>
**Import Order Matters!**
Always import in this order:
1. **Companies** first (no dependencies)
2. **People** second (link to Companies)
3. **Opportunities** third (link to Companies/People)
4. **Notes and Tasks** (link to records)
5. **Custom objects** following their dependencies
The parent record must exist before you can reference it.
</Warning>
### Import Each Object
For each CSV file, in order:
1. Navigate to the object in Twenty
2. Click **⋮ → Import records**
3. Upload the CSV file
4. Map columns to fields:
- Map user email columns to the appropriate relation fields
- Map relation columns (like `companyDomain`) to relation fields
5. Review and fix any errors in the UI
6. Confirm the import
7. Verify a few records before proceeding to the next file
**Detailed guides:**
- [How to Import Companies](/user-guide/data-migration/how-tos/import-companies-via-csv)
- [How to Import Contacts](/user-guide/data-migration/how-tos/import-contacts-via-csv)
- [How to Import Relations](/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv)
## Step 7: Large Migrations (50,000+ Records)
For large migrations:
| Volume | Recommended Approach |
|--------|---------------------|
| Under 10,000 records | Single CSV import |
| 10,000 - 50,000 records | Split into multiple CSV files |
| 50,000+ records | Use the API |
**For API imports:**
- Faster and more reliable for large datasets
- Supports batch operations (up to 60 records per call)
- See [How to Import Data via API](/user-guide/data-migration/how-tos/import-data-via-api)
## Step 8: Post-Migration Setup
After importing data, complete your workspace configuration:
### Recreate Views
- Set up saved views with filters, sorts, and column configurations
- Create any kanban or calendar views you need
### Recreate Workflows
- Rebuild your automations in **Settings → Workflows**
- Start with the most critical workflows
- Test each one before relying on it
### Configure Roles and Permissions
- Set up roles in **Settings → Members → Roles**
- Assign users to appropriate roles
### Connect Email and Calendar
- Each user connects their own account in **Settings → Accounts**
- Twenty will start syncing emails to contact records
- See [Email & Calendar](/user-guide/calendar-emails/overview)
### Train Your Team
- Walk through the new interface together
- Document any team-specific processes
## Common Issues and Solutions
| Issue | Cause | Solution |
|-------|-------|----------|
| **Duplicate errors** | Email/domain already exists | Remove duplicates from file, or include unique identifier to update existing records |
| **Relation not found** | Parent record doesn't exist | Import parent objects first (Companies before People) |
| **Missing fields** | Custom field doesn't exist | Create field in Settings → Data Model before importing |
| **Select field errors** | Using display labels | Use API names (enable Advanced mode in Settings to find them) |
| **User relation empty** | User hasn't accepted invite | Ensure all users accept invitations before importing |
See [How to Fix Import Errors](/user-guide/data-migration/how-tos/fix-import-errors) for detailed troubleshooting steps.
## Post-Migration Checklist
### Data Integrity
<Check>All records imported (compare counts with source system)</Check>
<Check>Relations working correctly (People linked to Companies)</Check>
<Check>User assignments mapped correctly (Owner, Assignee)</Check>
<Check>Custom fields populated</Check>
<Check>No unexpected duplicates</Check>
### Configuration
<Check>Views recreated</Check>
<Check>Workflows recreated and tested</Check>
<Check>Roles and permissions configured</Check>
<Check>Email/calendar sync connected</Check>
### Team Readiness
<Check>Team trained on new system</Check>
<Check>Old CRM access plan decided (keep for reference? When to disable?)</Check>
## FAQ
<AccordionGroup>
<Accordion title="Can I migrate workflows automatically?">
Not currently. Workflows must be recreated manually in Twenty.
</Accordion>
<Accordion title="What about file attachments?">
File attachments are not included in CSV exports. You'll need to re-upload them manually, migrate via API, or contact our team for assistance.
</Accordion>
<Accordion title="Can I keep both systems running during migration?">
Yes, we recommend keeping your old CRM running until you've verified the migration is complete. Just be careful not to create new data in both places.
</Accordion>
<Accordion title="How long does migration typically take?">
Depends on data volume and complexity. Small migrations (under 10,000 records) can be done in a few hours. Large migrations may take several days including data cleanup and testing.
</Accordion>
</AccordionGroup>
## Need Help?
<Tip>
Want help with your migration? [Find a certified Twenty partner](https://twenty.com/partners/list?categories=SOLUTIONING&ref=docs-migrate-crm) to move your data, pipelines, and users end-to-end.
</Tip>

View File

@@ -0,0 +1,167 @@
---
title: Migrating from Self-Hosted to Cloud
description: Step-by-step guide to migrate your Twenty self-hosted instance to Twenty Cloud.
---
## Overview
This guide walks you through migrating your data from a Twenty self-hosted instance to Twenty Cloud. The process involves setting up your cloud workspace, exporting your data, and re-importing it.
<Note>Views, workflows, and roles must be recreated manually after migration. Plan time for this configuration work.</Note>
## Step 1: Create Your Cloud Workspace
1. Go to [app.twenty.com](https://app.twenty.com) and create a new workspace
2. Complete the initial setup wizard
3. Note your new workspace URL
## Step 2: Recreate Your Data Model
Before importing data, recreate your custom objects and fields:
1. Go to **Settings → Data Model** in your cloud instance
2. Create custom objects that match your self-hosted setup
3. Add custom fields to standard and custom objects
4. Configure field settings (unique, required, etc.)
<Note>Take screenshots of your self-hosted data model for reference, or keep both instances open side by side.</Note>
## Step 3: Invite All Users
<Warning>
**Critical: Invite users BEFORE importing data.**
Users must accept their invitations before you import any records that reference them (like Account Owner fields). If users don't exist yet, those relations cannot be mapped.
</Warning>
1. Go to **Settings → Members** in your cloud instance
2. Invite all team members who had accounts on self-hosted
3. **Wait for everyone to accept** their invitation
4. Verify all users appear in your Members list
## Step 4: Export Data from Self-Hosted
Export each object from your self-hosted instance:
1. Navigate to each object (Companies, People, Opportunities, etc.)
2. Configure the view to show **all columns** you want to migrate
3. Click **⋮ → Export view**
4. Save each CSV file with a clear name (e.g., `companies-export.csv`)
**Export in this order** (for reference when importing):
1. Companies
2. People
3. Opportunities
4. Custom objects (following their dependencies)
5. Tasks, Notes
## Step 5: Update Workspace Member References
The exported CSVs contain user IDs from your self-hosted instance. These IDs won't match your cloud instance, so you need to replace them with emails.
**For each CSV file with user references (Owner, Assignee, etc.):**
1. Open the CSV in a spreadsheet application
2. Add a new column next to each user ID column (e.g., `accountOwnerEmail` next to `accountOwnerId`)
3. Fill in the **email address** of each user
4. You can delete the old ID column or leave it (it will be skipped during import)
**Example:**
Before:
```csv
name,domain,accountOwnerId
Acme Corp,https://acme.com,old-uuid-123
```
After:
```csv
name,domain,accountOwnerEmail
Acme Corp,https://acme.com,john@yourcompany.com
```
<Note>Use the same email addresses that users used to accept their cloud workspace invitation.</Note>
## Step 6: Plan Your Import Order
Import files in the correct order to maintain relationships:
1. **Companies** first (no dependencies)
2. **People** second (link to Companies)
3. **Opportunities** third (link to Companies and People)
4. **Custom objects** (following their dependencies)
5. **Tasks and Notes** last (link to other records)
See [How to Import Relations](/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv) for details on maintaining relationships.
## Step 7: Import to Cloud
For each CSV file, in order:
1. Navigate to the object in your cloud instance
2. Click **⋮ → Import records**
3. Upload the CSV file
4. Map columns to fields:
- Map user email columns to the appropriate relation fields
- Map other columns as usual
5. Review and fix any errors
6. Confirm the import
7. Verify a few records before proceeding to the next file
## Step 8: Recreate Configuration
After importing data, manually recreate:
### Views
- Recreate saved views with filters, sorts, and column configurations
- Set up any kanban or calendar views
### Workflows
- Recreate automations in **Settings → Workflows**
- Test each workflow before relying on it
### Roles and Permissions
- Configure roles in **Settings → Members → Roles**
- Assign users to appropriate roles
### Integrations
- Reconnect email and calendar sync for each user
- Reconfigure any API integrations with new API keys
## Post-Migration Checklist
<Check>All data imported successfully</Check>
<Check>Relations between objects working correctly</Check>
<Check>User assignments (Owner, Assignee) mapped correctly</Check>
<Check>Views recreated</Check>
<Check>Workflows recreated and tested</Check>
<Check>Roles and permissions configured</Check>
<Check>Email/calendar sync reconnected</Check>
<Check>API integrations updated with new keys</Check>
## FAQ
<AccordionGroup>
<Accordion title="Can I migrate workflows automatically?">
Not currently. Workflows must be recreated manually in your cloud instance.
</Accordion>
<Accordion title="What about file attachments and images?">
File attachments are not included in CSV exports. You'll need to re-upload any attachments manually, migrate them via API or contact our team for assistance with large migrations.
</Accordion>
<Accordion title="Can I keep both instances running during migration?">
Yes, we recommend keeping your self-hosted instance running until you've verified the cloud migration is complete. Just be careful not to create new data in both places.
</Accordion>
<Accordion title="What if a user hasn't accepted their invitation yet?">
Records referencing that user will fail to import or the relation will be empty. Ensure all users accept invitations before importing data.
</Accordion>
</AccordionGroup>
## Need Help?
<Tip>
Migrating a large or complex workspace? [Get a certified Twenty partner](https://twenty.com/partners/list?categories=HOSTING&ref=docs-migrate-cloud) to handle the move end-to-end. *(Or loop in our team: [contact@twenty.com](mailto:contact@twenty.com).)*
</Tip>

View File

@@ -0,0 +1,237 @@
---
title: Prepare Your CSV Files
description: Complete step-by-step guide to format your data for import into Twenty.
---
## Overview
This guide walks you through preparing your CSV file for a successful import. Follow these steps in order to avoid errors.
## Step 1: Check File Requirements
Before you start, ensure your file meets these requirements:
| Requirement | Details |
|-------------|---------|
| **Format** | CSV, XLSX, or XLS |
| **Size limit** | 10,000 records per file |
| **Encoding** | UTF-8 recommended |
| **Structure** | One object type per file |
<Note>For datasets larger than 10,000 records, split into multiple files or use the [API import](/user-guide/data-migration/how-tos/import-data-via-api).</Note>
## Step 2: Download the Sample File
**This is the most important step.** The sample file shows you the exact column names and format Twenty expects.
1. Go to the object view (People, Companies, etc.)
2. Click **⋮** → **Import records**
3. Click **Download sample file**
4. Use this file as your template
<Note>**Pro tip:** Export a few existing records instead. This gives you real examples of how data should be formatted, and the column names will map automatically during import.</Note>
## Step 3: Remove Duplicate Values
Twenty enforces uniqueness on certain fields. Duplicates will cause import errors.
| Object | Unique Fields |
|--------|---------------|
| **People** | `id`, `email` |
| **Companies** | `id`, `domain` |
| **Custom objects** | `id`, plus any field you marked as unique |
**Before importing:**
1. Sort your spreadsheet by the unique field (email or domain)
2. Remove or merge duplicate rows
3. Check for duplicates that already exist in Twenty
<Warning>**Soft-deleted records count toward uniqueness.** Records in Command Menu → See deleted records will cause duplicate errors. Delete them permanently or restore and update them.</Warning>
## Step 4: Format Each Field Type Correctly
Different field types require specific formats. Here's the complete reference:
### Text Fields
- No special formatting required
- Leading/trailing spaces are automatically trimmed
### Email Fields
- Must be valid email format: `name@domain.com`
- Must be unique (no duplicates in file or in Twenty)
- For additional emails, use this format in the **Emails / Additional Emails** column:
```
["jane@twenty.com","jane.doe@twenty.com"]
```
### Domain Fields
- **Recommended format**: `https://domain.com`
- This matches the format used by mailbox/calendar sync (prevents duplicates)
- Fill both columns:
- **Domain / Domain Label**: `domain.com`
- **Domain / Domain URL**: `https://domain.com`
- Must be unique within your file and in Twenty
### Phone Fields
Phone is a **nested field** requiring multiple columns:
| Column | Example |
|--------|---------|
| **Phones / Primary Phone Number** | `4159095555` |
| **Phones / Primary Phone Country Code** | `US` |
| **Phones / Primary Phone Calling Code** | `+1` |
### Address Fields
Address is a **nested field** with multiple columns (some can be left empty):
- **Address / Address 1**: Street address line 1
- **Address / Address 2**: Street address line 2 (optional)
- **Address / City**: City name
- **Address / State**: State or province
- **Address / Country**: Country name
- **Address / Post Code**: Postal/ZIP code
### Date Fields
Use consistent formatting throughout your file:
- `YYYY-MM-DD` (recommended): `2024-03-15`
- ISO 8601: `2024-03-15T10:30:00Z`
### Number Fields
- Numbers only (no text)
- Use period for decimals: `1234.56`
- No thousands separators (not `1,234.56`)
### Currency Fields
Currency is a **nested field** requiring two columns that **both must be filled**:
| Column | Example |
|--------|---------|
| **Amount / Amount** | `1234.56` |
| **Amount / Currency** | `USD` |
### Boolean Fields
Use uppercase: `TRUE` or `FALSE`
<Warning>Lowercase `true` or `false` will not work.</Warning>
### Select Fields
Use the **API name** of the option, not the display label.
**How to find API names:**
1. Go to **Settings → Data Model**
2. Select the object and field
3. Enable **Advanced mode** (toggle at bottom right)
4. Copy the API name (e.g., `OPTION_1`, not "Option 1")
<Note>New select options are not created automatically. Add them in **Settings → Data Model** before importing.</Note>
### Multi-Select Fields
Use API names in array format:
```
["VALUE1","VALUE2"]
```
### Array Fields
Use JSON array format:
```
["value1","value2"]
```
### Rating Fields
Use the format: `RATING_1`, `RATING_2`, `RATING_3`, `RATING_4`, or `RATING_5`
### Links/URL Fields
Fill both columns:
- **Links / Link Label**: `Twenty`
- **Links / Link URL**: `https://twenty.com`
For secondary links, use the **Links / Secondary Links** column:
```
[{"url":"https://twenty.com","label":"Twenty"}]
```
### JSON Fields
Use valid JSON format:
```
{"key":"value","key2":"value2"}
```
### ID Fields
- **Optional**: Twenty auto-generates IDs if not provided
- **Format**: UUID (e.g., `c776ee49-f608-4a77-8cc8-6fe96ae1e43f`)
- **Use case**: Include ID to update existing records instead of creating new ones
## Step 5: Add Relation Columns (If Linking Records)
To link records to other objects (e.g., People to Companies), add a column with the unique identifier of the related record.
**Example**: Linking People to Companies
Add a column to your People CSV:
```
firstName,lastName,email,companyDomain
John,Smith,john@acme.com,https://acme.com
Jane,Doe,jane@widgets.co,https://widgets.co
```
**Important rules for relations:**
- The parent record must already exist in Twenty
- Use the **Domain URL** format (`https://domain.com`), not the label
- Map only ONE unique identifier (don't include both `companyId` AND `companyDomain`)
- For Workspace Members, use their **email** (not name)
<Warning>
**Import Order Matters!**
Import the "one" side before the "many" side:
1. **Companies** first
2. **People** second (with company reference)
3. **Opportunities** third
The parent record must exist before you can reference it.
</Warning>
See [How to Import Relations](/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv) for detailed instructions.
## Step 6: Ensure Fields Exist in Twenty
The import creates **records**, not **fields**. All fields you want to import must already exist in your data model.
**Before importing:**
1. Go to **Settings → Data Model**
2. Select your object
3. Create any custom fields you need
4. Note the exact field names (they must match your column headers)
## Step 7: Final Checklist
Before uploading your file, verify:
<Check>File is CSV, XLSX, or XLS format</Check>
<Check>File has fewer than 10,000 records</Check>
<Check>Encoding is UTF-8</Check>
<Check>No duplicate emails (for People) or domains (for Companies)</Check>
<Check>Dates use consistent format throughout</Check>
<Check>Domains use `https://domain.com` format</Check>
<Check>Boolean fields use `TRUE` or `FALSE` (uppercase)</Check>
<Check>Select fields use API names, not display labels</Check>
<Check>All custom fields exist in Settings → Data Model</Check>
<Check>Parent records imported before child records</Check>
<Check>Relation columns reference existing records</Check>
## Common Mistakes to Avoid
| Mistake | Solution |
|---------|----------|
| Using `true` instead of `TRUE` | Boolean values must be uppercase |
| Using display labels for Select fields | Find and use API names in Settings |
| Importing People before Companies | Always import parent objects first |
| Missing currency code for Currency fields | Fill both Amount and Currency columns |
| Wrong domain format | Use `https://domain.com` consistently |
| Mapping multiple unique fields for relations | Map only ONE (domain OR id, not both) |
## Next Steps
Your file is ready! Now:
- [Import Companies](/user-guide/data-migration/how-tos/import-companies-via-csv) (import these first)
- [Import Contacts](/user-guide/data-migration/how-tos/import-contacts-via-csv)
- [Fix any import errors](/user-guide/data-migration/how-tos/fix-import-errors)

View File

@@ -0,0 +1,195 @@
---
title: Update Existing Records via Import
description: Complete step-by-step guide to bulk updating records using CSV import.
---
## Overview
Need to update many records at once? Instead of editing them one by one, use the CSV import to bulk update existing records.
**Use cases:**
- Update job titles for multiple people
- Change company information in bulk
- Add data to new custom fields
- Correct data errors across many records
## How It Works
When you import a file containing a **unique identifier** that matches an existing record, Twenty updates that record instead of creating a duplicate.
| If unique identifier... | Twenty will... |
|-------------------------|----------------|
| Matches an existing record | **Update** the existing record |
| Doesn't match any record | **Create** a new record |
| Is missing from your file | **Create** a new record (with auto-generated ID) |
<Warning>
**Multi-Select fields are overwritten, not merged.**
If a record has `Option A` and `Option B` selected, and you import `["Option C"]`, the record will only have `Option C` after import. The import replaces all previous selections—it does not add to them.
To keep existing values, include them all in your import: `["Option A","Option B","Option C"]`
</Warning>
## Step 1: Export Your Current Data
First, export the records you want to update:
1. Navigate to the object (People, Companies, etc.)
2. **Add the columns you need** — click **Options → Fields** to show the fields you want to update
3. **Filter if needed** — narrow down to only the records you want to update
4. Click **⋮** → **Export view**
5. Save the CSV file
<Note>**Why export first?** The exported file has the correct format, includes unique identifiers, and maps automatically during import.</Note>
### What Gets Exported
- All visible columns in your current view
- The record's unique identifiers (`id`, `email`, `domain`)
- Current field values you can modify
## Step 2: Edit the CSV File
Open the exported file in your spreadsheet application (Excel, Google Sheets, etc.):
1. **Keep the unique identifier column** — don't delete `id`, `email`, or `domain`
2. **Update the values** in the columns you want to change
3. **Remove columns you don't need to update** (optional, but cleaner)
4. **Don't change unique identifier values** — or Twenty will create new records
### Example: Updating Job Titles
**Exported file:**
```csv
id,email,firstName,lastName,jobTitle
550e8400-e29b-41d4-a716-446655440001,john@acme.com,John,Smith,Sales Rep
550e8400-e29b-41d4-a716-446655440002,jane@acme.com,Jane,Doe,Sales Rep
550e8400-e29b-41d4-a716-446655440003,bob@acme.com,Bob,Johnson,Sales Rep
```
**After your edits:**
```csv
id,email,firstName,lastName,jobTitle
550e8400-e29b-41d4-a716-446655440001,john@acme.com,John,Smith,Account Executive
550e8400-e29b-41d4-a716-446655440002,jane@acme.com,Jane,Doe,Senior Account Executive
550e8400-e29b-41d4-a716-446655440003,bob@acme.com,Bob,Johnson,Account Executive
```
<Warning>
**Don't change the unique identifier values.**
If you change `john@acme.com` to `john.smith@acme.com`, Twenty will create a new record instead of updating the existing one.
</Warning>
## Step 3: Import the Updated File
1. Navigate to the object
2. Click **⋮** → **Import records**
3. Upload your edited CSV file
4. **Ensure the unique identifier is mapped** — verify `email`, `domain`, or `id` is mapped correctly
5. Review the field mappings
6. Check for errors
7. Click **Confirm**
Twenty matches records by the unique identifier and updates them with new values.
## Choosing the Right Unique Identifier
| Object | Recommended | Alternative | Notes |
|--------|-------------|-------------|-------|
| **People** | `email` | `id` | Email is human-readable |
| **Companies** | `domain` | `id` | Domain is human-readable |
| **Custom objects** | Any unique field | `id` | Use your custom unique field |
<Note>**Use only ONE unique identifier.** Don't map both `email` AND `id`. This can cause confusion and errors.</Note>
### Using Custom Unique Fields
If you have a custom field marked as unique (like an external ID from another system):
1. Include that field in your export and import
2. Map it during import
3. Twenty will match on that field
## Step 4: Verify the Updates
After importing:
1. Open a few updated records
2. Verify the changes were applied
3. Check that no duplicate records were created
## What About Fields Not in Your File?
**Fields not included in your import file remain unchanged.**
| Your file includes... | Result |
|-----------------------|--------|
| `email`, `jobTitle` | Only `jobTitle` is updated; other fields stay the same |
| `email`, `jobTitle`, `phone` | `jobTitle` and `phone` are updated |
This means you only need to include the fields you want to change (plus the unique identifier).
## Combining Updates and New Records
You can update existing records AND create new ones in the same import:
```csv
email,firstName,lastName,jobTitle
john@acme.com,John,Smith,Senior Manager ← Updates existing (email matches)
newperson@acme.com,New,Person,Analyst ← Creates new (email doesn't match)
```
## Common Mistakes to Avoid
| Mistake | Problem | Result | Solution |
|---------|---------|--------|----------|
| **Changing unique identifier** | Changed `john@acme.com` to `john.smith@acme.com` | Creates new record instead of updating | Keep unique identifiers unchanged |
| **Multiple unique fields** | Mapping both `email` AND `id` | Potential matching conflicts | Map only ONE unique identifier |
| **No unique identifier** | File only has `firstName`, `lastName`, `jobTitle` | All rows create new records | Always include `email`, `domain`, or `id` |
| **Case mismatch** | File has `John@acme.com` but Twenty has `john@acme.com` | Creates new record | Export from Twenty to get exact values |
## FAQ
<AccordionGroup>
<Accordion title="What if some records don't exist yet?">
Records with unique identifiers that don't match existing records will be created as new records. This lets you update and create in the same import.
</Accordion>
<Accordion title="Can I clear/empty a field value?">
Yes, leave the cell empty in your CSV. The import will clear that field's value on the existing record.
</Accordion>
<Accordion title="What happens to fields I don't include in the import?">
Fields not in your import file remain unchanged on existing records. Only fields you include are updated.
</Accordion>
<Accordion title="Can I update relation fields (like Company)?">
Yes! Include the relation's unique identifier (e.g., `companyDomain`) and map it to the relation field. The relation will be updated.
</Accordion>
<Accordion title="How do I know which records will be updated vs. created?">
During the import review step, Twenty shows you how many records will be updated vs. created based on unique identifier matches.
</Accordion>
<Accordion title="Can I undo a bulk update?">
There's no automatic undo. We recommend exporting your data as a backup before making bulk updates.
</Accordion>
</AccordionGroup>
## Best Practices
1. **Export first** — always start from an export to ensure correct format
2. **Backup before updating** — export your data before making bulk changes
3. **Test with a few records** — try updating 5-10 records first before doing a large batch
4. **Use human-readable identifiers** — `email` and `domain` are easier to verify than `id`
5. **Only include necessary columns** — fewer columns means less chance for errors
## Troubleshooting
Having issues? Check:
- [How to Fix Import Errors](/user-guide/data-migration/how-tos/fix-import-errors)
- [Uniqueness Constraints](/user-guide/data-migration/capabilities/uniqueness-constraints)
- [Field Mapping Reference](/user-guide/data-migration/capabilities/field-mapping)

View File

@@ -0,0 +1,79 @@
---
title: Data Migration
description: Import and export your CRM data via CSV files or API.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Import Methods
Twenty supports two main methods for importing data:
| Method | Best For | Volume Limit |
|--------|----------|--------------|
| **CSV Import** | Standard migrations, regular updates | 10,000 records per file |
| **API Import** | Large-scale migrations, automation | Unlimited |
<Note>For very large datasets (hundreds of thousands of records), use the API. Our [implementation partners](/user-guide/getting-started/capabilities/implementation-services) can help run these scripts if needed.</Note>
## CSV Import Basics
You can import data for any object using CSV, XLSX, or XLS files. Each file should contain **only one type of object** (e.g., only People records).
<Note>**Fields must exist before import.** Uploading a CSV creates records but does not create fields. If you need custom fields, create them first under **Settings → Data Model**.</Note>
### Steps
1. Navigate to the object where you want to import data
2. Click the **⋮** icon on the top right (this is the Command Menu) and click on **Import records**
3. Download the template file to ensure your data is in the expected format
4. Upload your formatted CSV file
5. Map your columns to Twenty fields
6. Review errors (highlighted in yellow) and fix them, directly editing in the UI
7. Confirm the import
### Importing Relations Between Objects
You can import relations between objects using the CSV import function. You need to reference the related object using a unique field from this object: the `id`, the `email` for People and Workspace Members, the `domain` for companies, any other field set as unique in the data model for any other object.
<Note>**Deleted records count toward uniqueness.** Soft-deleted records (visible under Command Menu → See deleted records) are included in uniqueness checks. If you import a record with the same unique value as a deleted record, the deleted record will be restored.</Note>
<Warning>
**Import Order Matters!**
When importing related objects, upload files in this order:
1. **Companies** first (the "one" side of relationships)
2. **People** second (linked to Companies via companyId)
3. **Opportunities** third (linked to Companies/People)
4. **Custom objects** with relations last
Why? The "one" side of a one-to-many relationship must exist before you can reference it. For example, the Company record must exist before you import a Person with that company's ID.
</Warning>
Please refer to [this article](/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv) for a step-by-step guide on how to proceed.
## Export Data
Export your workspace data for backups, reporting, or migration.
### Steps
1. Navigate to the object you want to export
2. Configure the view with the columns you need
3. Click **⋮** → **Export view**
4. Save the CSV file
<Note>**Only visible columns are exported.** The CSV file will only contain the columns displayed in your current view. Add or hide columns before exporting to control what data is included.</Note>
<Note>**Export limits**: Up to 20,000 records per export.</Note>
## Permissions
Data import and export require specific permissions:
- **Import**: Requires "Import CSV" permission
- **Export**: Requires "Export CSV" permission
Contact your workspace admin if you don't have these permissions.
## Next Steps
- [Prepare your CSV files](/user-guide/data-migration/how-tos/prepare-your-csv-files)
- [Import relations between objects](/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv)
- [Import via API for large datasets](/user-guide/data-migration/how-tos/import-data-via-api)

View File

@@ -0,0 +1,118 @@
---
title: Fields
description: Understand the role of fields and how to manage them.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## About Fields
Fields are like columns in a spreadsheet. They store different types of data like text, numbers, or dates. Fields can be standard (built-in) or custom (the ones you create).
### Standard Fields
Standard fields come built-in with Twenty to handle common business needs.
For example, `First Name` and `Last Name` are standard fields in the `People` object. They store text data for individual names.
You cannot delete standard fields, but you can deactivate them if you don't need them.
You can also customize the options of the standard `SELECT` type fields, for example the options for the `Stage` on Opportunities.
<img src="/images/user-guide/fields/standard-fields.png" style={{width:'100%'}}/>
### Custom Fields
Custom fields can be added to any object. You can store text, numbers, dates, dropdown selections, and more. Use custom fields to track information that's specific to your business.
For instance, a custom field for SpaceX could be `Rocket Active Status`, indicating if a rocket is operational.
<img src="/images/user-guide/fields/custom-fields.png" style={{width:'100%'}}/>
## Field Types
Twenty supports various field types:
| Type | Description | Example |
|------|-------------|---------|
| Address | Structured address with street, city, state, country, postal code | Office Address |
| Array | List of text values | Tags |
| Boolean | True/false checkbox | Is Active |
| Currency | Monetary value with currency code | Deal Amount (USD) |
| Date | Date values | Close Date |
| Date & Time | Date with time | Meeting Time |
| Domain | Website domain (used for Companies) | acme.com |
| Email | Email addresses (with primary + additional) | Contact Email |
| JSON | Structured JSON data | Custom metadata |
| Links | URLs with labels (primary + secondary) | Website, LinkedIn |
| Long Text | Multi-line text | Description, Notes |
| Multi-Select | Multiple choices from a predefined list | Tags, Categories |
| Number | Numeric values (integers or decimals) | Quantity, Score |
| Phone | Phone numbers with country code | Work Phone |
| Rating | Star rating (1-5) | Priority, Score |
| Relation | Links to records in other objects | Company → People |
| Select | Single choice from a predefined list | Stage, Status |
| Text | Single line of text | Name, Title |
## Create a Custom Field
To add a custom field to any object, follow these steps:
1. Go to `Settings` in the left sidebar.
2. Go to `Data Model`, then select the object you wish to customize.
3. Proceed by clicking on `+ New Field`.
4. Choose a field name and type that suits your requirements. Consider adding a field description for better understanding.
Your newly created field is now available within the application's fields. To display it on a specific view, click on the options menu, then select `Fields`.
<VimeoEmbed videoId="927628219" title="Video demonstration" />
**Quick way:** Click the **+** button at the top right of any object table, then select `Customize fields`. This takes you directly to the Data Model settings.
<img src="/images/user-guide/fields/quick-new-field.png" style={{width:'100%'}}/>
## Deactivate a Field
You can deactivate a field to hide it from the app without losing your data. Think of it as hiding the field rather than deleting it.
Here's how you can do it:
1. Find the field you want to deactivate in your object settings.
2. Click the three dots `⋮` next to the field to open the menu.
3. Select `Deactivate` from the dropdown.
<img src="/images/user-guide/fields/deactivate-field.png" style={{width:'100%'}}/>
What happens when you deactivate a field?
1. **In the app:** The field disappears and you can't add new values to it.
2. **Existing relationships:** If it's a relation field, existing connections stay, but you can't create new ones.
3. **API access:** You can still access the field and its data through the API.
You can reactivate Standard and Custom Fields or have the option to permanently delete them.
## Make Fields Unique
Make a field unique to ensure distinct records cannot have the same value. For example, email addresses are unique for each person.
If you get an error when setting uniqueness, check for duplicate values in your data (including deleted records).
## Indexes (Advanced)
Database indexes are managed automatically — adding your own is rarely necessary and easy to get wrong. With Advanced mode on, each object has an **Indexes** section under `Settings → Data Model → <object>` for the cases where you know you need one.
## Field Configuration Best Practices
### Naming Conventions and Limitations
- **Singular and plural names must be distinct**: Our GraphQL API needs distinct names for mutations
- **Protected field names**: some names are reserved for system usage (e.g., `Type`, `Application`)
### Currency and Phone Fields
- **Default currency**: can be configured via the data model
- **Default country codes**: can be configured for phone fields via the data model
### Select Fields
- **A default option can be selected** for each Select field
### Record Text Fields
- **Each object has one main display field**: This field appears in the leftmost column and represents the record when linked to other objects. It must be a text field. For example, People uses `Name` as the main field, so when you link a person to a company, you'll see their name in the company's view.

View File

@@ -0,0 +1,86 @@
---
title: Objects
description: Learn about standard and custom objects in Twenty.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Standard Objects
Standard objects are predefined entities in your workspace to help you get started. They're part of a shared data model accessible to all users of Twenty. You can use them as-is, customize them or deactivate them.
<img src="/images/user-guide/objects/standard-objects.png" style={{width:'100%'}}/>
### People
The `People` object stores your contacts. It includes contact details and interaction history, so you can see all your customer interactions in one place.
### Companies
The `Companies` object stores your business accounts. It includes details like industry, size and location. Companies connect to both `People` and `Opportunities` objects.
### Opportunities
The `Opportunities` object stores deal-related data. It tracks the progression of potential sales, from prospecting to closure, recording stages, deal sizes, associated account, and expected close date. You can view your sales pipeline in a kanban layout.
### Notes
The `Notes` object stores free-form notes that can be attached to People, Companies, Opportunities, and other records. Use notes to capture meeting summaries, important details, or any contextual information.
### Tasks
The `Tasks` object stores to-dos and action items. Tasks can be linked to People, Companies, Opportunities, and other records. Track due dates, assignees, and completion status to stay on top of your follow-ups.
## Custom Objects
Custom objects let you store information that's unique to your organization and that standard objects can't handle. For example, if you're SpaceX, you may want to create a custom object for Rockets and Launches.
<img src="/images/user-guide/objects/custom-objects.png" style={{width:'100%'}}/>
### Creating a New Custom Object
To create a new custom object:
1. Go to Settings in the sidebar on the left.
2. Under Workspace, go to Data Model. Here you'll be able to see an overview of all your existing Standard and Custom objects (both active and deactivated).
<VimeoEmbed videoId="926288174" title="Video demonstration" />
3. Click on `+ New object` at the top. Enter the name (both singular and plural), choose an icon, and add a description for your custom object and hit Save (at the top right). Using Listing as an example of custom object, the singular would be "listing" and the plural would be "listings" along with a description like "Listings that hosts created to showcase their property."
4. Your custom object is now created and will appear in your sidebar. You can start adding records to it right away.
## Managing Objects
### Deactivating Objects
If you don't need a standard or custom object:
1. Go to Settings → Data Model
2. Find the object you want to deactivate and click it
3. Go to object's **Settings** tab
4. Click `Deactivate` button
5. The object will be hidden from your workspace but data is preserved
### Reactivating Objects
To bring back a deactivated object:
1. Go to Settings → Data Model
2. Enable `Deactivated` filter
3. Look for deactivated objects (they have `Deactivated` next to their name)
4. Click `⋮` and then `Activate` to reactivate it
5. The object and all its data will be restored
## Best Practices
### When to Create Custom Objects
- **Unique business entities**: Things specific to your industry or process
- **Complex relationships**: When you need to track connections between multiple entities
- **Scalable data**: When you might have many instances of something
### When to Use Fields Instead
- **Simple attributes**: Properties that describe existing objects
- **Categories or labels**: Ways to classify existing records
- **Single values**: Information that doesn't need its own lifecycle
### Object Naming
- **Use clear, descriptive names**: Make it obvious what the object represents
- **Follow conventions**: Use singular for the object name, plural for the collection
- **Consider your team**: Choose names everyone will understand

View File

@@ -0,0 +1,88 @@
---
title: Relation Fields
description: Connect records across different objects using relation fields.
---
## Types of Relations
### One-to-Many
One record in Object A can be linked to many records in Object B.
**Example:** One Company can have many People (employees).
### Many-to-One
Many records in Object A can be linked to one record in Object B.
**Example:** Many People can belong to one Company.
### Relations to Multiple Object Types
Some objects can link to multiple object types on one side of the relation.
**Example:** A Note can be attached to one Person AND one Company AND one Opportunity simultaneously. The Note is on the "many" side, connecting to multiple "one" sides.
<img src="/images/user-guide/fields/many-to-one-morph.png" style={{width:'100%'}}/>
Similarly, a Project (on the "one" side) could receive links from multiple People, multiple Companies, and multiple Notes.
<img src="/images/user-guide/fields/one-to-many-morph.png" style={{width:'100%'}}/>
<Warning>
**Import/Export limitation**: Relations pointing to multiple object types are not yet supported for CSV import/export. This is on our roadmap.
</Warning>
### Many-to-Many
Many records in Object A can be linked to many records in Object B.
**Example:** Many People can be linked to many Projects, and vice versa.
Many-to-many relations use a **junction object** pattern: an intermediate object that connects both sides. With the junction relation feature, Twenty displays the final linked records directly, hiding the intermediate object from the UI.
<Warning>
**Beta Feature**: Junction relations must be enabled at **Settings → Community → Features** before use.
</Warning>
See [How to Create Many-to-Many Relations](/user-guide/data-model/how-tos/create-many-to-many-relations) for a complete step-by-step guide.
## Creating a Relation Field
1. Go to **Settings → Data Model**
2. Select the object where you want to add the relation
3. Click **+ New field**
4. Select **Relation** as the field type
5. Choose the target object(s) to relate to
6. Configure the relation settings:
- **Field name on source object**: The name of the relation field on the object you're editing
- **Field name on destination object**: The name of the relation field that will appear on the target object
- Relation type (one-to-many, many-to-one)
7. Click **Save**
## Standard Relations
Twenty comes with pre-built relations between standard objects:
| From Object | To Object | Relation Type |
|-------------|-----------|---------------|
| People | Companies | Many-to-One |
| Opportunities | Companies | Many-to-One |
| Opportunities | People | Many-to-One |
## Best Practices
### Planning Relations
- **Map your data model**: Plan relations before creating them
- **Consider direction**: Think about which object "owns" the relationship
- **Avoid circular dependencies**: Keep your data model clean
### Naming Relations
- **Use clear names**: Make it obvious what the relation represents
- **Be consistent**: Use similar naming patterns across relations
- **Consider both sides**: Name both sides of the relation appropriately
### Performance
- **Don't over-relate**: Too many relations can slow down your workspace
## Limitations
- **Deleting relations** removes the link but not the related records
- **Circular relations** should be avoided for data integrity

View File

@@ -0,0 +1,71 @@
---
title: Create Custom Fields
description: Step-by-step guide to adding custom fields to any object.
---
Custom fields let you capture information specific to your business. Add them to any object—standard or custom.
## Steps
1. Go to **Settings → Data Model**
2. Select the object you want to add a field to
3. Click **+ New Field**
4. Choose a **field type** (see [Fields](/user-guide/data-model/capabilities/fields) for all types)
5. Enter the **field name** and optional description
6. Configure field-specific settings (see below)
7. Click **Save**
**Quick method:** Click the **+** at the end of column headers in any table view → **Customize fields**.
## Show the Field in Views
New fields aren't automatically visible. To display:
1. Open the object's table view
2. Click **Options → Fields**
3. Click the **eye icon** next to your field to show it
4. Drag to reorder
## Configuration Options
### For Select / Multi-Select
1. Click **+ Add option** to create choices
2. Set a **default option** if desired
3. Drag to reorder options
<Note>
**Use API names for imports.** Enable **Advanced mode** in Settings to see API names. See [Field Mapping](/user-guide/data-migration/capabilities/field-mapping).
</Note>
### For Currency Fields
Set the **default currency** (USD, EUR, etc.) for new records.
### For Phone Fields
Set the **default country code** to pre-fill for new phone numbers.
### Making a Field Unique
Toggle **Unique** to prevent duplicate values across records.
<Note>
If duplicates exist (including in deleted records), you'll get an error. Clean up duplicates first.
</Note>
### Setting Default Values
For Select fields, you can choose which option is pre-selected for new records. For Checkbox fields, set whether it's checked or unchecked by default.
## Deactivating a Field
1. Go to **Settings → Data Model**
2. Find the field
3. Click **⋮ → Deactivate**
Data is preserved. You can reactivate or permanently delete later.
## Related
- [Fields](/user-guide/data-model/capabilities/fields) — all field types explained
- [Data Model FAQ](/user-guide/data-model/how-tos/data-model-faq) — common questions

View File

@@ -0,0 +1,50 @@
---
title: Create Custom Objects
description: Step-by-step guide to creating custom objects in Twenty.
---
Custom objects let you store information unique to your business that standard objects don't cover. For example: Projects, Products, Tickets, or Listings.
<Note>
**Not sure if you need an object or a field?** See [Understanding Your Data Model](/user-guide/data-model/overview) for guidance.
</Note>
## Steps
1. Go to **Settings → Data Model**
2. Click **+ Add object**
3. Fill in:
- **Singular name** (e.g., "Listing")
- **Plural name** (e.g., "Listings")
- **Icon**
- **Description** (optional)
4. Click **Save**
Your object appears in the sidebar immediately.
## Next: Add Fields
New objects start with basic fields. Add custom fields to capture the data you need:
1. In **Settings → Data Model**, select your object
2. Click **+ New Field**
3. Choose a field type, configure, and save
See [How to Create Custom Fields](/user-guide/data-model/how-tos/create-custom-fields) for details on field types and configuration.
## Connecting to Other Objects
To link your object to People, Companies, or other objects, create a relation field. See [How to Create Relation Fields](/user-guide/data-model/how-tos/create-relation-fields).
## Deactivating an Object
If you no longer need an object:
1. Go to **Settings → Data Model → object of your choice → Settings**
2. Click the **Deactivate** button
The object is hidden but data is preserved. You can reactivate or permanently delete later.
## Related
- [Objects](/user-guide/data-model/capabilities/objects) — standard vs custom objects
- [Data Model FAQ](/user-guide/data-model/how-tos/data-model-faq) — common questions

View File

@@ -0,0 +1,170 @@
---
title: Create Many-to-Many Relations
description: Connect records where many items on both sides can be linked together using junction objects.
---
Many-to-many relations let you connect multiple records on both sides. For example: many People can work on many Projects, and each Project can have many People.
<Warning>
**Beta Feature**: Junction relations are currently in beta. Enable them at **Settings → Community → Features** before following this guide.
</Warning>
<Note>
This feature also requires **Advanced mode** to be enabled (toggle at the bottom left of Settings).
</Note>
## When to Use Many-to-Many
Use many-to-many when both sides of a relationship can have multiple connections:
| Relationship | Example |
|-------------|---------|
| People ↔ Projects | A person works on multiple projects; a project has multiple team members |
| Companies ↔ Tags | A company can have multiple tags; a tag can apply to multiple companies |
| Products ↔ Orders | A product can be in multiple orders; an order contains multiple products |
## How It Works
Twenty uses a **junction object** pattern for many-to-many relations. A junction object sits between two objects and holds the connections:
```
People ←→ Project Assignments ←→ Projects
```
The **Project Assignments** object (junction) has:
- A relation to People (many-to-one)
- A relation to Projects (many-to-one)
When you enable the junction relation toggle, Twenty displays linked records directly instead of showing the intermediate junction records.
## Prerequisites
1. **Enable Junction Relations in Beta Features**: Go to **Settings → Community → Features** and enable **Junction Relations**
2. **Enable Advanced mode**: Toggle on **Advanced mode** at the bottom left of the Settings sidebar
3. Plan your data model:
- Which two objects are you connecting?
- What should the junction object be called?
## Step 1: Create the Junction Object
First, create the intermediate object that will hold the connections.
1. Go to **Settings → Data Model**
2. Click **+ Add object**
3. Name it descriptively (e.g., "Project Assignment", "Team Member", "Product Order")
4. Toggle "Skip creating a Name field" on
<img src="/images/user-guide/fields/new-pivot-object.png" alt="New pivot object" />
5. Click **Save**
<Tip>
**Naming convention**: Use a name that describes the relationship, like "Project Assignment" or "Team Membership". This makes the data model easier to understand.
</Tip>
## Step 2: Create Relations Between Objects and the Junction
Add relation fields from each of your two objects to the junction object.
### First Relation (Object A → Junction)
1. Select your first object in **Settings → Data Model**
2. Click **+ Add Relation**
3. Select the junction object (e.g., "Project Assignments")
4. Set the relation type to **One-To-Many** (one person can link to many assignments)
5. Name the fields:
- Field on People: e.g., "Project Assignments"
- Field on junction: e.g., "Person"
6. Click **Save**
### Second Relation (Object B → Junction)
1. Select your second object in **Settings → Data Model**
2. Click **+ Add Relation**
3. Select the junction object (e.g., "Project Assignments")
4. Set the relation type to **One-To-Many** (one project can link to many assignments)
5. Enable **"This is a relation to a Junction Object"**
<img src="/images/user-guide/fields/junction-relation-toggle.png" style={{width:'100%'}}/>
6. Name the fields:
- Field on junction: e.g., "Project"
- Field on Projects: e.g., "Team Members"
7. Click **Save**
## Step 3: Configure the Junction Relation Display
Now configure the source objects to display linked records directly, skipping the intermediate junction object.
1. Go to **Settings → Data Model**
2. Select the first object (e.g., "People")
3. Find the relation field pointing to the junction object (e.g., "Project Assignments")
4. Click to edit the field
5. Enable **"This is a relation to a Junction Object"**
6. Select the **Target relation** (e.g., "Project" — the field on the junction that points to the other side)
7. Click **Save**
## Result
After configuration:
- On a **Person** record, the "Project Assignments" field displays **Projects** directly (not assignment records)
- On a **Project** record, the "Team Members" field displays **People** directly
The junction object still exists and stores the connections, but the UI presents a cleaner many-to-many view.
## Example: People ↔ Projects
Here's a complete walkthrough:
### Create the Junction Object
- Name: **Project Assignment**
- Description: "Links people to projects they work on"
### Add Relations
1. **People → Project Assignment**
- Type: One-to-Many
- Field on People: "Project Assignments"
- Field on Assignment: "Person"
2. **Projects → Project Assignment**
- Type: One-to-Many
- Field on Projects: "Team Members"
- Field on Assignment: "Project"
### Configure Junction Display
1. On **People** object:
- Edit "Project Assignments" field
- Enable junction toggle
- Target: "Project"
2. On **Projects** object:
- Edit "Team Members" field
- Enable junction toggle
- Target: "Person"
### Use It
- Open a Person record → See their Projects directly
- Open a Project record → See team members directly
- Create new connections from either side
## Adding Extra Data to Connections
Since the junction object is a real object, you can add custom fields to store information about the relationship:
- **Role**: "Developer", "Designer", "Manager"
- **Start Date**: When the person joined the project
- **Hours Allocated**: Weekly hours on this project
To access this data, navigate to the junction object directly or query it via the API.
## Limitations
- **CSV Import/Export**: Importing many-to-many relations directly is not supported. Import records to the junction object instead.
- **Filters**: Filtering by many-to-many relations may have limited options.
## Related
- [Relation Fields](/user-guide/data-model/capabilities/relation-fields) — relation types explained
- [Create Custom Objects](/user-guide/data-model/how-tos/create-custom-objects) — how to create objects
- [Create Relation Fields](/user-guide/data-model/how-tos/create-relation-fields) — basic relation setup

View File

@@ -0,0 +1,69 @@
---
title: Create Relation Fields
description: Step-by-step guide to connecting objects with relation fields.
---
Relation fields connect records from different objects—for example, linking People to Companies.
<Note>
**Relation names cannot be changed after creation** (they affect the API). Plan your names carefully.
</Note>
## Before You Start
Decide:
- Which objects are you connecting? (e.g., People → Companies)
- Which is the "one" side? (e.g., Company)
- Which is the "many" side? (e.g., People — many people work at one company)
- What should the field be named on each side?
See [Relation Fields](/user-guide/data-model/capabilities/relation-fields) for relation types explained.
## Steps
1. Go to **Settings → Data Model**
2. Select the object where you want the relation (typically the "many" side)
3. Click **+ New Field**
4. Select **Relation** as the field type
5. Choose the **target object**
6. Select **One-to-Many** or **Many-to-One**
7. Enter field names for **both sides** of the relation
8. Click **Save**
## Example: People → Companies
- Go to **Settings → Data Model → People**
- Add a Relation field
- Target: **Companies**
- Type: **Many-to-One**
- Field on People: **Company**
- Field on Companies: **Employees**
Now each Person can be linked to a Company, and each Company shows its People.
## Deactivating a Relation
1. Go to **Settings → Data Model → object of your choice**
2. Find the relation field and click it
3. Click **Deactivate** button
Links are preserved but hidden. Reactivate to restore.
<Note>
**Deactivating a relation doesn't delete records.** Only the link between them is removed.
</Note>
## Deleting a Relation
1. Go to **Settings → Data Model → object of your choice**
2. Find the relation field and click it
3. Click **Delete** button
<Note>
Applies only to custom relations. Standard relations can only be deactivated.
</Note>
## Related
- [Relation Fields](/user-guide/data-model/capabilities/relation-fields) — types and limitations
- [How to Import Relations](/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv) — bulk import linked records

View File

@@ -0,0 +1,22 @@
---
title: Customize Your Data Model
description: Overview of data model customization options.
---
Twenty's data model is fully customizable. Create objects, fields, and relations to match your business.
## Quick Links
| I want to... | Guide |
|--------------|-------|
| Create a new object | [How to Create Custom Objects](/user-guide/data-model/how-tos/create-custom-objects) |
| Add fields to an object | [How to Create Custom Fields](/user-guide/data-model/how-tos/create-custom-fields) |
| Connect objects together | [How to Create Relation Fields](/user-guide/data-model/how-tos/create-relation-fields) |
## Learn More
- [Understanding Your Data Model](/user-guide/data-model/overview) — key concepts and planning tips
- [Objects](/user-guide/data-model/capabilities/objects) — standard vs custom objects
- [Fields](/user-guide/data-model/capabilities/fields) — all field types
- [Relation Fields](/user-guide/data-model/capabilities/relation-fields) — connecting objects
- [Data Model FAQ](/user-guide/data-model/how-tos/data-model-faq) — common questions

View File

@@ -0,0 +1,157 @@
---
title: Data Model FAQ
description: Frequently asked questions about Twenty's data model.
---
## Object Management
<AccordionGroup>
<Accordion title="Can I delete a custom object?">
Yes, custom objects can be deleted. You can also deactivate them first, which hides the object and its data from the interface while preserving the data.
</Accordion>
<Accordion title="Can I delete standard objects (People, Companies, etc.)?">
No, standard objects cannot be deleted. You can only deactivate them, which hides them from the interface but preserves the data.
</Accordion>
<Accordion title="How many custom objects can I create?">
You can create as many custom objects and fields as you need — the price doesn't change.
</Accordion>
<Accordion title="Can I rename a standard object?">
You can rename the label of standard objects (People, Companies, Opportunities), but not their API names. The API names are fixed for consistency across all Twenty workspaces.
</Accordion>
<Accordion title="Can I change an object's icon?">
Yes, you can change the icon for both standard and custom objects in **Settings → Data Model**.
</Accordion>
<Accordion title="Can I reorder objects in the sidebar?">
Yes. With the **Layouts** permission, enter sidebar customization mode to drag and drop items in the **Workspace** section. This order is shared across the workspace. Items in **Favorites** are personal to each user and can be reordered without entering customization mode. See the [Sidebar guide](/user-guide/layout/capabilities/navigation).
</Accordion>
<Accordion title="Can I hide objects from the sidebar?">
You can hide objects you don't use from the sidebar without deleting them. You can show them again from **Settings → Data Model**. See the [Sidebar guide](/user-guide/layout/capabilities/navigation).
</Accordion>
</AccordionGroup>
## Field Capabilities
<AccordionGroup>
<Accordion title="Can I change a field type after creation?">
No, field types cannot be changed after creation. If you need a different type, create a new field with the correct type, migrate your data, then deactivate the old field.
</Accordion>
<Accordion title="Why do I need different singular and plural names?">
Our GraphQL API uses both forms for different operations:
- `createPerson` (singular) for single record actions
- `createPeople` (plural) for bulk operations
This creates limitations when singular and plural forms are the same, but it improves the developer experience.
</Accordion>
<Accordion title="Why are some field names protected?">
Certain field names like `Type` or `Application` are reserved for system use. Choose alternative names like `Category` or `Classification` instead.
</Accordion>
<Accordion title="What happens when I deactivate a field?">
- The field is hidden from the interface
- Existing data is preserved
- You can still access the field via API
- Existing relations remain but you can't create new ones
- You can reactivate the field later
</Accordion>
<Accordion title="Can I make a field required?">
Currently, you cannot make custom fields required. All fields accept empty values. You can use workflows to enforce required fields by sending alerts or blocking actions when fields are empty.
</Accordion>
<Accordion title="What's the difference between unique and required?">
- **Unique**: No two records can have the same value in this field
- **Required**: The field must have a value (not currently supported for custom fields)
</Accordion>
<Accordion title="Can I create formula fields?">
Formula fields are coming in **H2 2026**. In the meantime, you can use workflows to calculate and update field values automatically.
</Accordion>
<Accordion title="Can I have nested fields in my objects?">
Nested fields are coming in **H2 2026**. Currently, you can use workflows to bring field values from related objects. For example, to display a company's industry on a Person record, create a custom field on People and use a workflow to synchronize the value.
</Accordion>
<Accordion title="Can I reorder fields in objects?">
Yes, go to Settings → Data model → object of your choice → Layout and click **Customize record page**. If this button is disabled, you must create a record.
</Accordion>
</AccordionGroup>
## Relations
<AccordionGroup>
<Accordion title="Can I have a relation pointing to the same object?">
Yes! Self-referencing relations are supported and recommended for use cases like account hierarchies. For example, create a relation from Companies to Companies to track parent/child accounts.
</Accordion>
<Accordion title="Can I create many-to-many relationships?">
Many-to-many relationships are coming in **H2 2026**. Currently, create an intermediate object with two one-to-many relationships as a workaround.
For example, to link People and Projects (many-to-many), create a "Project Assignments" object with:
- A relation to People (many assignments → one person)
- A relation to Projects (many assignments → one project)
</Accordion>
<Accordion title="What are relations to multiple object types (Morph relationships)?">
These allow one object to relate to multiple different object types through a single field. For example, Notes can be attached to People AND Companies AND Opportunities simultaneously.
Each Note links to one Person, one Company, and one Opportunity at the same time.
Learn more in [Relation Fields](/user-guide/data-model/capabilities/relation-fields).
</Accordion>
<Accordion title="Can I have multiple relations between the same objects?">
Yes, you can create multiple relations between the same two objects. For example, a Company could have both a "Primary Contact" and "Billing Contact" relation to People.
</Accordion>
<Accordion title="What happens to relations when I delete a record?">
When you delete a record, the relation link is removed from the related records. The related records themselves are not deleted.
</Accordion>
<Accordion title="Can I create circular relations?">
While technically possible, circular relations (A → B → C → A) should be avoided as they can cause confusion and potential performance issues.
</Accordion>
</AccordionGroup>
## Access and Permissions
<AccordionGroup>
<Accordion title="Where can I see and edit my data model?">
Go to **Settings → Data Model** to view and edit all your objects and fields.
</Accordion>
<Accordion title="Why can't I see the Data Model under Settings?">
Reach out to your workspace administrator. Data model access is usually restricted to administrators only.
</Accordion>
</AccordionGroup>
## Data Management
<AccordionGroup>
<Accordion title="Is there a limit to how many records I can have?">
There's no hard limit on record counts. However, very large datasets may impact performance in some views. Use filters and views to manage large datasets effectively.
</Accordion>
<Accordion title="Can I import data into custom objects?">
Yes, you can import CSV data into any object, including custom objects. The import process supports field mapping for custom fields. See [How to Prepare Your CSV Files](/user-guide/data-migration/how-tos/prepare-your-csv-files).
</Accordion>
<Accordion title="Can I export my data model configuration?">
Currently, there's no built-in export for data model configuration. Contact support if you need to migrate your data model between workspaces.
</Accordion>
<Accordion title="How many fields can a single object have?">
The maximum number of fields a single object can have is 1600 fields as per Postgres limits, including both existing and deleted fields. Be aware that Twenty won't fix your workspace if the limit of 1600 fields is reached as it falls under our Fair Usage policy.
</Accordion>
</AccordionGroup>
## Need More Help?
Check our [Implementation Services](/user-guide/getting-started/capabilities/implementation-services) for help with complex data model design.

View File

@@ -0,0 +1,166 @@
---
title: Data Model
description: Learn what a data model is and how to design one that fits your business.
---
## What is a Data Model?
A data model is the structure that defines how information is organized in your CRM. Think of it as the **blueprint** of your customer data — you design it once, then fill it with your actual data.
## Key Concepts
### Objects
**Objects** are the main categories of data in your CRM. Each object represents a type of thing you want to track.
Twenty comes with standard objects:
- **People** — individuals (contacts, leads, partners)
- **Companies** — organizations
- **Opportunities** — deals or sales
- **Notes** — notes attached to records
- **Tasks** — to-dos linked to records
You can also create **custom objects** for anything specific to your business (e.g., Projects, Subscriptions, Events).
### Fields
**Fields** are the properties or attributes that describe each object. They store the actual information.
For example, the **People** object has fields like:
- Name
- Email
- Phone
- Job Title
- Company (a relation to the Companies object)
Fields have different **types**: text, number, date, select, multi-select, relation, and more. You can add custom fields to any object.
### Records
**Records** are the individual entries within an object — the actual data you create and manage.
For example:
- "John Smith" is a **record** in the People object
- "Acme Corp" is a **record** in the Companies object
**An analogy:**
| Data Model Concept | Real-World Analogy |
|-------------------|-------------------|
| **Objects** | Sections in a book (the categories) |
| **Fields** | Columns in a spreadsheet (the properties) |
| **Records** | Rows in a spreadsheet (the actual entries) |
You design the data model (objects + fields) once, then create many records within that structure.
## Why Customize Your Data Model?
Every business works differently. Customizing your data model means you can shape Twenty around **your** processes instead of forcing yours into a rigid system.
Twenty offers full flexibility:
- Create as many custom objects as you need
- Add unlimited custom fields
- The price doesn't change based on customization
## Tips to Design Your Data Model
### 1. Start with Your Core Objects
Identify the main concepts you work with. Twenty already provides:
- **People** — your contacts
- **Companies** — your accounts
- **Opportunities** — your deals
Think about what else you might need:
- Stripe would need a `Subscriptions` object
- Airbnb would need a `Trips` object
- An accelerator would need a `Batches` object
### 2. Use Fields for Variations, Not New Objects
If something is just a characteristic of an existing object, make it a **field**.
**Use fields for:**
- Categories and labels (e.g., `Industry` for Companies)
- Status values (e.g., `Stage` for Opportunities)
- Attributes and properties
### 3. Create an Object When It Stands on Its Own
If the concept has its own lifecycle, properties, or relationships, it deserves an object.
**Create an object for:**
- **Projects** — have deadlines, owners, and tasks
- **Subscriptions** — connect companies, products, and invoices
- **Events** — involve attendees and follow-up actions
These go beyond a single field because they carry their own data and relationships.
### 4. Create an Object When Records Are Open-Ended
If something can be linked multiple times and you don't know how many, use an object.
**Bad approach:**
Creating fields like `Product 1`, `Product 2`, `Product 3`...
**Good approach:**
Create a `Products` object and relate it to records. This supports one, two, or a hundred products without changing your model.
### 5. Keep It Simple First
Start with fields. Move to new objects only when you feel the limits:
- Too many fields on one object
- Repeated records that should be separate
- Relationships that don't fit neatly
## Special Note on People, Companies, and Opportunities
<Warning>
**Email and calendar sync only works with People, Companies, and Opportunities.**
These are the only objects where you can access synchronized emails and meetings from your mailbox/calendar. We recommend using them as much as possible.
</Warning>
**Best practices:**
- If you need categories of People, use fields (not new objects)
- Example: Use a `Person Type` field with values "Prospect" and "Partner" instead of creating separate objects
- Create different **views** to filter: one showing partners, another showing prospects
**It's okay to have fields that don't apply to every record.** For example, a `Referral Link` field on People that only applies when `Person Type = Partner`. Hide this field from views where it's not relevant.
## Questions to Guide Your Choice
Ask yourself:
<Check>Is this just a property of something I already have, or does it need its own properties?</Check>
<Check>Will I ever need to track multiple of these per record, without knowing how many?</Check>
<Check>Does this concept connect to several different objects, not just one?</Check>
<Check>Will it have its own lifecycle (stages, start/end dates)?</Check>
If the answer is "yes" to one or more, it's probably time for a new object.
## Accessing Your Data Model
1. Go to **Settings** in the left sidebar
2. Click **Data Model**
3. View all your objects (standard and custom)
4. Click any object to see and edit its fields
<Note>
**Don't see Data Model in Settings?**
Access to the data model is usually restricted to administrators. Contact your workspace admin if you need access.
</Note>
## Next Steps
Once you've planned your data model:
- [How to Create Custom Objects](/user-guide/data-model/how-tos/create-custom-objects)
- [How to Create Custom Fields](/user-guide/data-model/how-tos/create-custom-fields)
- [How to Create Relation Fields](/user-guide/data-model/how-tos/create-relation-fields)
## Need Help?
<Tip>
Want help designing your data model? [Find a certified Twenty partner](https://twenty.com/partners/list?categories=SOLUTIONING&ref=docs-data-model) to design and build your objects, fields, and relationships.
</Tip>

View File

@@ -0,0 +1,80 @@
---
title: Glossary
description: Get familiar with essential terminology used in Twenty.
---
## API
API (Application Programming Interface) allows you to connect Twenty with other software systems and build custom integrations.
## Apps
Apps are custom extensions built as code that can define data models and logic functions. They enable developers to create reusable customizations that can be deployed across multiple workspaces.
## Code Actions
Code Actions are workflow steps that let you write custom JavaScript to transform data, make calculations, or perform complex logic that isn't possible with built-in actions.
## Command Menu
The Command Menu is a quick-access interface (opened with `Cmd + K` on Mac and `Ctrl + K` on Windows) that lets you perform actions, create records, and navigate your workspace efficiently.
## Company & People
The CRM has two fundamental types of records:
- A `Company` represents a business or organization.
- `People` represent your company's current and prospective customers or clients.
## Custom Fields
Custom Fields are data fields you create to capture information specific to your business needs and processes.
## Data Model
A Data Model is the structure that defines how information is organized in your CRM, including what objects exist, their properties (fields), and how they relate to each other.
## Favorites
Favorites are records you've marked for quick access, appearing in your sidebar for instant navigation to important data.
## Field
A field refers to a specific area where particular data is stored for an entity.
## Iterator
An Iterator is a workflow action that loops through an array of items, executing subsequent actions for each item in the list.
## Kanban
A `Kanban` is a visual way to track your business processes using cards and columns. Each column represents a stage in your process (for example: new, ongoing, won, lost), and you move records through these stages as they progress.
## Object
An Object is a data structure that represents a specific type of entity in your CRM (like People, Companies, or Opportunities). Objects can be standard (built-in) or custom (created by you).
## Opportunities
Opportunities in Twenty CRM are potential deals or sales with accounts or contacts.
## Record
A Record is an instance of an object, like a specific account or contact.
## Relation Fields
Relation Fields create connections between different objects, allowing you to link records together (like connecting a Person to a Company).
## Standard Fields
Standard Fields are pre-built data fields that come with objects by default and provide common functionality across all workspaces.
## Tasks
Tasks in Twenty CRM are assigned activities relating to contacts, accounts, or opportunities.
## Triggers
Triggers are the starting point of a workflow — the event or condition that initiates the automation. Examples include record creation, record updates, webhooks, or scheduled times.
## Views
You can customize the display of your records using views, setting different filters, layouts and sorting options for each view.
## Upsert
Upsert is an operation that combines "update" and "insert" — it updates an existing record if a match is found, or creates a new record if no match exists.
## Webhooks
Webhooks are automated messages sent from Twenty to other applications when specific events occur, enabling real-time data synchronization.
## Workflows
Workflows are automated processes that trigger actions based on specific conditions, helping you automate repetitive tasks and business processes.
## Workspace
A `Workspace` typically represents a company using Twenty. It holds all the records and data that you and your team members add to Twenty.
It has a single domain name, which is typically the domain name your company uses for employee email addresses.
## Workspace Members
Workspace Members are the Twenty users from your team who have access to your workspace. They can be assigned as owners or assignees for records.

View File

@@ -0,0 +1,17 @@
---
title: Implementation Services
description: Whether you need help getting started or creating advanced customizations, we have a solution.
---
## Implementation Partners
Work with certified Twenty partners for advanced customizations, integrations, and dedicated implementation support.
<CardGroup cols={2}>
<Card title="Browse certified partners" icon="magnifying-glass" href="https://twenty.com/partners/list?ref=docs-implementation-services">
Find a partner and reach out directly — filter by region, language, and expertise.
</Card>
<Card title="Get matched by Twenty" icon="envelope" href="mailto:contact@twenty.com">
Tell us what you need and we'll connect you with the right partner.
</Card>
</CardGroup>

View File

@@ -0,0 +1,44 @@
---
title: What is Twenty
description: Twenty is an open-source CRM that gives you the building blocks to create exactly what your business needs.
---
## Vision
Creating a good CRM is hard because it's a balancing act.
For each business, the requirements seem straightforward, yet everyone's needs are distinct.
The result is a CRM that's either too basic, or one that's attempting to be a jack-of-all-trades but ending up as a master of none.
At first, Twenty looks like most CRMs you already know: you can track deals, organize contacts, manage tasks and notes.
**But what sets it apart is our approach to extensibility. We are building an open platform that provides the building blocks for you to solve your unique business problems.**
We prioritize universal principles and common patterns over feature lists.
We don't try to have all the answers and instead empower users to find what works best for them.
Open-source is the bedrock of our approach, ensuring that Twenty evolves with its community, for its community.
## Benefits
**Customizable:** Designed to fit your business needs.
**Community-driven:** Built and maintained by a large open-source community.
**Cost-effective:** You'll never be vendor-locked, because you can always self-host.
## Main Features
- **Calendar & Emails:** Sync your mailbox and calendar to see all communications on your CRM records. [Learn more](/user-guide/calendar-emails/overview).
- **Data Model:** Create custom objects and fields to match your unique business processes. [Explore](/user-guide/data-model/overview).
- **Data Migration:** Import and export your data via CSV or API. [Get started](/user-guide/data-migration/overview).
- **Views & Pipelines:** Organize your data with table views, kanban boards, and sales pipelines. [Discover](/user-guide/views-pipelines/overview).
- **Workflows:** Automate your business processes and integrate with external tools. [Build automations](/user-guide/workflows/overview).
- **AI:** Enhance your CRM with AI-powered features and agents. [Explore AI](/user-guide/ai/overview).
- **Dashboards:** Track performance with custom reports and visualizations. [View dashboards](/user-guide/dashboards/overview).
- **Permissions & Access:** Control who can view, edit, and manage your data with role-based permissions. [Configure access](/user-guide/permissions-access/overview).
- **Notes & Tasks:** Create notes and tasks linked to your records for better collaboration.
- **API & Webhooks:** Connect to other apps and build custom integrations. [Start integrating](/developers/extend/api).
## Join Now
[Register here](https://app.twenty.com) or [become a contributor on GitHub](https://github.com/twentyhq/twenty).

View File

@@ -0,0 +1,67 @@
---
title: Configure Your Workspace
description: "Every business works differently. Start with these 3 steps to shape Twenty around your needs."
---
<Note>**Quick Win**: Start with connecting your mailbox. This gives you immediate value and helps your team see Twenty in action with real data. You can do so under Settings → Accounts.</Note>
## 1. Customize your data model
Twenty offers the flexibility you need to shape the data model that will best support your day-to-day.
Create objects and fields of any type, including relations between your different objects. You can do so under Settings → Data Model.
Here are a few tips:
- **You are not limited in the number of custom fields or custom objects**. Adding custom objects and fields will not lead to upgrading your plan.
- **People, Companies and Opportunities are the three objects from where you can access the emails and meetings synchronized from your mailbox and calendar**. We recommend using those as much as possible, adding fields to categorize your records if need be. Here is an example:
- It is best to use the People object for your prospects and partners, creating a field on the People object named ```Person Type```, instead of creating a Partner custom object, because you would not be able to access the emails exchanged with this person from the Partner records.
- Create different views under People, one to display partners and one to display prospects.
- Two People cannot have the same email address. Two Companies cannot have the same domain.
- You can deactivate standard fields and objects you do not want to use.
- You can hide fields from views: don't be afraid of creating fields, you won't have to display all of them.
Read [this article](/user-guide/data-model/overview) to learn how to design your data model.
## 2. Bring your data in
Bringing your existing data into Twenty gives your team context from the start.
### Connect your mailbox
If you have not done so when creating your workspace, connect your **Google or Microsoft account** under Settings → Accounts. This allows Twenty to:
- Import your messages and meetings
- Auto-create contacts based on interactions (optional)
- Keep communication history visible for your team
**Using another provider?**
You can add another mailbox via SMTP or another calendar via CalDAV. Go to **Settings → Accounts** to configure.
### Import data via CSV
Use the Command menu (```Cmd + K``` or ```Ctrl + K```) to import People, Companies, Opportunities, or any custom objects via CSV.
**Key guidelines**:
- Download the sample file to understand the expected format
- Limit each file to 10k records
- Remove duplicate emails for People or duplicate domains for Companies
- Review and fix errors (highlighted in yellow) before importing
Read [this article](/user-guide/data-migration/overview) to learn more about data import.
## 3. Create your first view
Creating different views is key to making the data actionable for your team.
Here is how to proceed:
- **Add or hide columns**
Manage the fields visible in a given view by clicking on Options → Fields (from the top right). You can show/hide fields from there.
- **Reorder fields**
Reorder the fields from a given view by clicking on Options → Fields (from the top right). Drag and drop the fields to reorder them.
- **Filter your view**
Narrow down the records displayed using the Filters from the top right.
- **Sort records**
Reorder records displayed using the Sort function from the top right, or by clicking directly on the column name.
- **Choose the layout**
You can switch to a **Kanban layout** or a list **Group By** layout, as long as the object has a `Stage` or similar select-type field.
- **Save your view as Favorites**
This can be done using the dropdown menu showing the different views.
## What's next?
Start creating automations using [workflows](/user-guide/workflows/overview).

View File

@@ -0,0 +1,43 @@
---
title: Create a Workspace
description: Follow a step-by-step guide on how to register on Twenty, choose a subscription plan, and set up your account.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Step 1: Registration
1. Navigate to [Twenty Sign Up](https://app.twenty.com).
2. Select your preferred sign-up method:
- **Continue with Google** for Google account registration.
- **Continue with Microsoft** for Microsoft account registration.
- Or, **Continue with Email** for email registration.
<VimeoEmbed videoId="927066829" title="Video demonstration" />
## Step 2: Choosing a Trial Period
Choose between two trial periods:
### 30 days
With credit card
### 7 days
Without credit card
Both trials include:
- Full access
- Unlimited contacts
- Email integration
- Custom objects
- API & Webhooks
You can click on "Change plan" to choose a different plan or billing interval.
<img src="/images/user-guide/create-workspace/choose-plan.png" style={{width:'100%'}}/>
## Step 3: Payment Confirmation & Account Setup
After payment approval via Stripe, you're directed to create your workspace and user profile. Remember that you can cancel your subscription anytime.
## Support
For queries or help, connect with the dedicated support team at [contact@twenty.com](mailto:contact@twenty.com) or send a message on [Discord](https://discord.gg/cx5n4Jzs57).

View File

@@ -0,0 +1,81 @@
---
title: Navigate Around Twenty
description: Get a quick overview of how to navigate through the platform and where to take different types of actions.
---
## The Main Layout
The center of the screen is **where your records live**: People, Companies, Opportunities, Tasks, Notes, Dashboards, Workflows and any other object you created. This is where the day-to-day work happens.
You can **view, edit, or delete records** from there, as well as **create new views**.
<img src="/images/user-guide/home/main-layout.png" style={{width:'100%'}}/>
<span id="the-navigation-bar" />
## The Sidebar
On the left side, from the top to the bottom, you'll be able to:
- Switch between your **several workspaces** using the dropdown menu or create a new workspace
- Use the **search bar** (press `/` to focus on it instantly)
- Open the **Settings** section
- Have direct access to your **Favorite views**. Favorites are unique for each user.
- Switch between different objects
- **Create automations** using workflows
Use the collapse button at the top of the sidebar, or choose **Collapse sidebar** from the command menu. When collapsed, use **Expand sidebar** to show it again.
<img src="/images/user-guide/home/navigation-bar.png" style={{width:'100%'}}/>
## The Command Menu
The command menu gives you **quick access to actions** in Twenty. You can access it in two ways:
- **Keyboard shortcut**: Press `Cmd + K` (Mac) or `Ctrl + K` (Windows)
- **Mouse**: Click the three dots in the top right corner
From there, you can:
- Create new records
- **Import and export data via CSV**
- Create new views
- Access deleted records (Twenty supports soft and hard deletes)
- See the keyboard shortcuts to quickly access objects in your workspace
<img src="/images/user-guide/home/command-menu.png" style={{width:'100%'}}/>
## The Search Bar
The search bar is accessible via the Command Menu, at the top of your sidebar, or by pressing `/` to focus on it instantly. Search works across all objects.
<img src="/images/user-guide/home/search-bar.png" style={{width:'100%'}}/>
## The Side Panel
When you click on a record, the side panel appears on the right. This gives you a quick overview of the record's key information, without bringing you to another page. From there, you can decide to close this overview or to get additional information about this record, by clicking on the Open button.
<img src="/images/user-guide/home/side-panel.png" style={{width:'100%'}}/>
## Views
Every object (like Opportunities or People) supports multiple views. You're not limited in the number of views per object.
Use the dropdown menu at the top left of the main layout to switch between the different views. For example:
- Use a Kanban view to track opportunities by stage
- Use Group By view to create sections and improve efficiency
- Use filters to focus on specific records (e.g. leads created last week)
- Save filtered views to reuse them later
- Favorite views for fast access
<img src="/images/user-guide/home/view-menu.png" style={{width:'100%'}}/>
If you're new to Views, read our [Views & Pipelines guide](/user-guide/views-pipelines/overview) to learn how to create and customize them.
## Settings
Open your Settings from the top left to:
- **Connect your mailbox and calendar** accounts for seamless email and calendar sync
- Customize your **data model**: create custom objects, fields, and relationships
- **Access the API playground and configure webhooks**
- **Manage user permissions** and workspace access controls
- Invite team members and manage user roles
- Edit your profile and workspace preferences
- Configure billing and monitor workflow credits usage
- Discover and enable upcoming features (under Updates → Early Access)
- **Access Support** to reach out via live chat
- **Open the Documentation** to browse the User Guide and developer docs
<Note>If you do not see all those sections under Settings, reach out to your workspace administrator — some sections have restricted access.</Note>

View File

@@ -0,0 +1,59 @@
---
title: User Guide
description: Welcome to Twenty User Guide, your resources for advanced configurations and best practices.
---
import { CardTitle } from "/snippets/card-title.mdx"
<CardGroup cols={3}>
<Card href="/user-guide/data-model/overview" img="/images/user-guide/halftone/data-model.png">
<CardTitle>Data Model</CardTitle>
Customize your data model to fit your business processes.
</Card>
<Card href="/user-guide/data-migration/overview" img="/images/user-guide/halftone/data-migration.png">
<CardTitle>Data Migration</CardTitle>
Import and export your data via CSV or API.
</Card>
<Card href="/user-guide/calendar-emails/overview" img="/images/user-guide/halftone/calendar-emails.png">
<CardTitle>Calendar & Emails</CardTitle>
Centralize your team's meetings and emails.
</Card>
<Card href="/user-guide/workflows/overview" img="/images/user-guide/halftone/workflows.png">
<CardTitle>Workflows</CardTitle>
Automate processes and integrate with external tools.
</Card>
<Card href="/user-guide/ai/overview" img="/images/user-guide/halftone/ai.png">
<CardTitle>AI</CardTitle>
Enhance your team with AI agents.
</Card>
<Card href="/user-guide/layout/overview" img="/images/user-guide/halftone/layout.png">
<CardTitle>Layout</CardTitle>
Sidebar, views, and record page customization.
</Card>
<Card href="/user-guide/dashboards/overview" img="/images/user-guide/halftone/dashboards.png">
<CardTitle>Dashboards</CardTitle>
Real-time insights to track performance.
</Card>
<Card href="/user-guide/permissions-access/overview" img="/images/user-guide/halftone/permissions.png">
<CardTitle>Permissions & Access</CardTitle>
Manage roles and access to Twenty.
</Card>
<Card href="/user-guide/billing/overview" img="/images/user-guide/halftone/billing.png">
<CardTitle>Billing</CardTitle>
Understand how Twenty pricing and billing works.
</Card>
<Card href="/user-guide/settings/overview" img="/images/user-guide/halftone/settings.png">
<CardTitle>Settings</CardTitle>
Configure your workspace preferences.
</Card>
</CardGroup>

View File

@@ -0,0 +1,49 @@
---
title: Sidebar
description: Customize the left sidebar to match how your team works.
---
The left sidebar is your primary way to move around Twenty. It's fully customizable — you can reorganize it to match your workflow without touching any settings page.
## Collapsing and expanding the sidebar
On desktop, click the collapse button at the top of the sidebar to make more room for your records. Hover over the button to see the **Collapse sidebar** tooltip. When collapsed, the button's tooltip changes to **Expand sidebar**.
You can also open the command menu with `Cmd+K` (Mac) or `Ctrl+K` (Windows), search for **sidebar**, and choose **Collapse sidebar** or **Expand sidebar**. The command reflects the sidebar's current state and closes the command menu after you select it.
## Reordering items
The order of items in the **Workspace** section is shared across the workspace. With the **Layouts** permission, hover over **Workspace** and click the wrench icon to enter sidebar customization mode. Drag and drop items to change their positions, then save your changes.
Items in **Favorites** are personal to each user and can be reordered by dragging and dropping them without entering customization mode.
## Folders
Group related items into folders. For example, you might create a "Sales" folder containing your pipeline views, a "Support" folder for tickets, or an "Operations" folder for internal objects.
To create a folder, right-click in the sidebar or use the `+` button.
## Hiding objects
Objects you don't use can be hidden from the sidebar. They're not deleted — they're just out of the way. You can show them again anytime from Settings → Data Model.
## Favorites
Pin views, records, or searches to the Favorites section at the top of the sidebar for one-click access. Favorites are personal — each user manages their own.
## Custom links
Add links to external tools directly in the sidebar. Useful for linking to your wiki, dashboards in other tools, or any URL your team uses regularly.
## Command menu
Press `Cmd+K` (or `Ctrl+K`) to open the command menu — a quick-access search bar for jumping to any record, view, or action without navigating the sidebar.
- Choose **Copy link to page** to copy the current page URL, including its view and tab, to your clipboard.
- Search for **theme** to switch to light, dark, or system appearance. The menu offers the themes you aren't currently using, and your choice is saved to your profile.
## Customizing the sidebar
To customize the sidebar, hover over the "Workspace" section in the sidebar and click the wrench icon.
<img src="/images/user-guide/layout/navigation-edit-icon.png" alt="Sidebar customization icon" />

View File

@@ -0,0 +1,68 @@
---
title: Record Pages
description: Customize the layout of individual record detail pages with tabs and widgets.
---
## Overview
When you open a record in Twenty, the detail page is composed of **tabs** and **widgets**. Both are fully customizable per object type.
## Tabs
Each record page can have multiple tabs — similar to tabs in a browser. Use them to organize different aspects of a record. For example, a Company record might have tabs for Overview, Communication, Tasks, and Files.
You can:
- Add and remove tabs
- Rename tabs
- Reorder tabs by dragging
- Set which tab shows by default
## Widgets
Widgets are the building blocks inside each tab. Available widget types include:
| Widget | What it shows |
|--------|--------------|
| **Fields** | Record fields, grouped or individually |
| **Related records** | Table of records linked via a relation |
| **Emails** | Email history from connected accounts |
| **Calendar** | Calendar events associated with the record |
| **Timeline** | Activity and event history |
| **Tasks** | Associated tasks |
| **Notes** | Rich text notes |
| **Files** | File attachments |
| **Charts** | Visual data from related records |
| **iFrame** | Embedded external content |
| **Rich text** | Static content or descriptions |
### Editing related records
Related-record table and kanban widgets are editable by default. To make one read-only:
1. Open the record page layout editor
2. Select the related-record widget
3. Turn off **Allow editing** under **Data and display**
For tables, this prevents cell editing. For kanban boards, it prevents editing cards, moving them between columns, and creating records. Role permissions still apply when editing is allowed.
## Customizing a record page
1. Open any record
2. Press `Cmd+K` and search for "Edit record page layout"
or
1. Go to Settings → Data Model → object of your choice → Layout
2. Click the "Customize record page" button for that object
3. You're now in customization mode:
- **Add widgets** from the widget picker
- **Drag widgets** to reposition them on the grid
- **Resize widgets** by dragging their edges
- **Configure fields** shown within each widget
- **Manage tabs** — add, remove, rename, reorder
4. Save your changes — they apply to all records of that object type
## Field visibility
Within a Fields widget, you can control which fields are visible and in what order. This lets you create focused layouts — for example, showing only the most important fields on the Overview tab and putting detailed fields in a separate tab.

View File

@@ -0,0 +1,47 @@
---
title: Layout
description: Customize how you navigate, browse, and view records in Twenty.
---
Twenty's layout is customizable at three levels: how you navigate the app, how you browse lists of records, and what you see when you open an individual record.
<span id="navigation" />
## Sidebar
The left sidebar is fully customizable. You can:
- **Reorder items** by dragging and dropping
- **Create folders** to group related objects and views
- **Hide objects** you don't use
- **Add custom links** to external tools
- **Pin favorites** for quick access to views, records, or searches
- **Collapse or expand the sidebar** from its button or the command menu
[Sidebar reference →](/user-guide/layout/capabilities/navigation)
## Views
Views control how lists of records are displayed. Twenty supports three view types:
| View | Best for |
|------|----------|
| **Table** | Working with many records at once — spreadsheet-style rows and columns |
| **Kanban** | Pipeline tracking — drag-and-drop cards organized by stage |
| **Calendar** | Time-based planning — records plotted by a date field |
Each view saves its own filters, sorting, field visibility, and grouping configuration. Views can be shared with the workspace or kept private.
[Table views →](/user-guide/views-pipelines/capabilities/table-views) · [Kanban views →](/user-guide/views-pipelines/capabilities/kanban-views) · [Calendar view →](/user-guide/views-pipelines/capabilities/calendar-view)
## Record pages
When you open a record, the detail page is built from configurable tabs and widgets. You can:
- **Add, remove, and reorder tabs** on any record type
- **Configure widgets** — fields, related records, emails, timeline, calendar, tasks, notes, files, charts, iFrames, and more
- **Drag and resize widgets** on a grid layout
- **Control field visibility** per widget
Enter layout customization mode from the command menu (`Cmd+K` → "Edit record page layout").
[Record pages reference →](/user-guide/layout/capabilities/record-pages)

View File

@@ -0,0 +1,125 @@
---
title: Legal FAQ
description: Frequently asked legal questions.
---
## Data residency and international transfers
<AccordionGroup>
<Accordion title="In which country and region would our workspace data, attachments, logs, and backups be stored?">
Twenty Cloud runs on AWS servers located in Frankfurt, Germany.
</Accordion>
<Accordion title="Can the hosting region be contractually fixed for our workspace?">
Hosting region selection will be available starting in 2027, initially for new workspaces. Users will be able to request a region change for an existing workspace at a later date. Alternatively, you can reach out to [our Partners](https://twenty.com/partners/list?categories=HOSTING) to help you set up your instance.
</Accordion>
<Accordion title="Which sub-processors may process or access our CRM data, and in which countries are they located?">
A list of all sub-processors is available in [our Trust Center](https://trust.twenty.com/?tab=subprocessors).
</Accordion>
<Accordion title="What safeguards apply to international data transfers?">
EU Standard Contractual Clauses, together with the UK Addendum and Swiss amendments, apply to international transfers of data outside the EU, including transfers to all sub-processors.
</Accordion>
</AccordionGroup>
## Data Processing Agreement and legal roles
<AccordionGroup>
<Accordion title="Where can we find the current Data Processing Agreement?">
You can generate your signed DPA at https://{your-domain}/settings/legal/dpa (e.g. https://getting-started.twenty.com/settings/legal/dpa).
</Accordion>
<Accordion title="Does Twenty act as the data processor for merchant and contact information stored in the CRM, while our company remains the data controller?">
As per our [Privacy Policy](https://twenty.com/privacy-policy), Twenty acts as the data processor for merchant and contact information stored in the CRM, while your company remains the data controller.
</Accordion>
<Accordion title="Is CRM content ever used to train Twenty or third-party AI models?">
CRM content can be used to train AI models depending on sub-processors' Terms and Conditions. Twenty does not have its own AI model — all AI models available on Twenty Cloud are provided by our sub-processors.
</Accordion>
<Accordion title="If optional AI processing exists, can it be fully disabled for our workspace?">
AI can be fully disabled by turning off all AI models in Settings → AI → Models. Additionally, no data is sent to AI unless you actively interact with the AI chat or an AI node in a workflow.
</Accordion>
</AccordionGroup>
## Security and access controls
<AccordionGroup>
<Accordion title="Is encryption used in transit and at rest, what are your key-management practices, and how is tenant data isolated?">
All data is encrypted in transit and at rest. Tenant data is isolated through a schema-per-tenant setup, and encryption keys are periodically rotated.
</Accordion>
<Accordion title="Which Twenty personnel or sub-processors may access customer workspaces, for what purposes, and how is access approved and logged?">
Twenty's engineering and support teams may access customer workspaces to investigate and resolve issues. Workspace owners control this: support access can be disabled at any time in Settings → General → Security, and it stays off until you turn it back on.
</Accordion>
<Accordion title="What is your incident-notification process and target notification timeframe following a confirmed security incident affecting our data?">
In the event of a confirmed personal data breach affecting your data, we will notify you without undue delay and in any event within 48 hours of becoming aware of it. Our notification will include, to the extent known at the time: the nature of the breach, the categories and approximate volume of data and individuals affected, likely consequences, and the remediation and mitigation measures taken or planned. We will provide updates as the investigation progresses.
</Accordion>
</AccordionGroup>
## Data retention and deletion
<AccordionGroup>
<Accordion title="When an individual CRM record is deleted, when is it removed from active systems?">
When a record is deleted, it is first soft-deleted and can still be restored. It is permanently deleted and removed from active systems once the retention period elapses or a user manually destroys it.
</Accordion>
<Accordion title="How long are soft-deleted records kept in the system?">
By default, soft-deleted records are kept for 14 days, after which they are permanently removed from the system. The retention period for soft-deleted records can be changed in Settings → General → Security.
</Accordion>
<Accordion title="How long may that record remain in backups or technical logs?">
A removed record remains in backups for 30 days, after which it is permanently deleted.
</Accordion>
<Accordion title="When a workspace is closed or full deletion is requested, what exact timeline applies to production data, attachments, logs, and backups?">
When a workspace is deleted, its data is removed from live systems within approximately 90 days of service termination, and usually much sooner. Back-up and archival copies are then overwritten or purged within a further 90 days, after which all data is permanently deleted. Throughout both periods the data is isolated from any operational use. On request, we can provide written certification once the purge is complete. See clause 4.9 of your Data Processing Agreement for the full terms.
</Accordion>
<Accordion title="During any backup-retention period, is deleted data isolated from operational access and use?">
Yes, during any backup-retention period, deleted data is isolated from operational use.
</Accordion>
<Accordion title="Are any categories of data retained longer for legal, billing, fraud-prevention, security, or audit purposes? If so, which categories and for how long?">
For more info about data retention, you can request our Data Management and Retention Policy available in [our Trust Center](https://trust.twenty.com/?tab=documents).
</Accordion>
<Accordion title="Can Twenty provide written confirmation when a full deletion request has been completed?">
We acknowledge erasure requests and provide written confirmation once deletion is complete.
</Accordion>
</AccordionGroup>
## Backups and resilience
<AccordionGroup>
<Accordion title="What are the backup frequency and retention period?">
Backups are created continuously with snapshots taken daily, and the retention period is 30 days.
</Accordion>
<Accordion title="What are the recovery-point objective and recovery-time objective for Twenty Cloud?">
RTO and RPO are both 6 hours (as per our DPA).
</Accordion>
<Accordion title="Are backups encrypted and stored in the same region as the primary workspace data?">
All backups are encrypted and stored in geographically separate locations within the same jurisdiction (e.g. within EU for EU data).
</Accordion>
</AccordionGroup>
## Compliance
<AccordionGroup>
<Accordion title="Is Twenty GDPR compliant?">
Yes, Twenty is [GDPR compliant](https://trust.twenty.com/?tab=securityControls&frameworks=gdpr_v1).
</Accordion>
<Accordion title="Is Twenty SOC 2 compliant?">
Yes, Twenty is [SOC 2 compliant](https://trust.twenty.com/?tab=securityControls&frameworks=soc2_v1).
</Accordion>
<Accordion title="Is Twenty HIPAA compliant?">
No, Twenty is in the process of becoming HIPAA compliant.
</Accordion>
</AccordionGroup>
## Licensing
<AccordionGroup>
<Accordion title="If I change the code to add features only for internal use by my team, do I have to publish those changes?">
No. Running a modified version for your own team is not distribution, so no publication obligation arises. The AGPL's network clause applies when people outside your organization interact with your modified instance over the network.
</Accordion>
<Accordion title="If I create a separate front end and use Twenty as a backend as-is, do I have to publish those changes?">
No. Your front end is your own, separate work, and talking to Twenty through its APIs does not change that. Since Twenty itself is unmodified, there is nothing to publish.
</Accordion>
<Accordion title="If I change the code to add features to re-sell it, do I have to publish those changes?">
Yes, since you're modifying code to distribute it to others, you're required to publish those changes. If you don't want to publish your changes, you can obtain Organization license.
</Accordion>
<Accordion title="Are applications built on Twenty required to be AGPL licensed?">
Applications that only interact with Twenty via its published APIs/SDKs can be licensed under terms of your choice (see the “Twenty Application Exception” in the repository LICENSE). Twenty itself is mostly AGPLv3, and some packages (including the Twenty SDK) are MIT licensed.
</Accordion>
</AccordionGroup>
If you have more questions, please check our [Terms and Conditions](https://twenty.com/terms), [Privacy Policy](https://twenty.com/privacy-policy) and [Trust Center](https://trust.twenty.com/). If your questions are still unanswered, send them to [contact@twenty.com](mailto:contact@twenty.com) or via support chat.

View File

@@ -0,0 +1,11 @@
---
title: Legal
description: Legal-related things
---
Check our [FAQ](/user-guide/legal/how-tos/legal-faq).
## Useful links
- [Terms and Conditions](https://twenty.com/terms)
- [Privacy Policy](https://twenty.com/privacy-policy)
- [Trust Center](https://trust.twenty.com/)

View File

@@ -0,0 +1,207 @@
---
title: Permissions
description: Control access to objects, fields, and settings with role-based permissions.
---
Twenty's permission system allows you to control access to three main areas:
- **Objects and Fields**: Control who can view, edit, or delete records and individual fields
- **Settings**: Manage access to workspace configuration and administrative functions
- **Actions**: Control general workspace actions like importing data or sending emails
## Create a Role
To create a new role:
1. Go to **Settings → Members → Roles**
2. Under **All Roles**, click on **+ Create Role**
3. Enter a role name
4. In the default **Permissions** tab, [configure permissions](#customize-permissions)
5. Click **Save** to finish
## Delete a Role
To delete a role:
1. Go to **Settings → Members → Roles**
2. Click on the role you want to remove
3. Open the **Settings** tab, then click **Delete Role**
4. Click **Confirm** in the modal
<Note>
If a role is deleted, any workspace member assigned to it will be automatically reassigned to the default role. All roles except the **Admin** role can be deleted. There must always be at least one member assigned to the **Admin** role.
</Note>
## Assign Roles to Members
### View Current Assignments
- Go to **Settings → Members → Roles**
- See all roles and how many members are assigned to each
- View which members have which roles
### Assign a Role to a Member
1. Go to **Settings → Members → Roles**
2. Click on the role you want to assign
3. Open the **Assignment** tab
4. Click **+ Assign to member**
5. Select the workspace member from the list
6. Confirm the assignment
### Set Default Role
1. Go to **Settings → Members → Roles**
2. In the **Options** section, find **Default Role**
3. Select which role new members should automatically receive
4. New workspace members will be assigned this role when they join
<Note>
You can only assign roles to existing workspace members. To invite new members, use [Member Management](/user-guide/settings/capabilities/member-management).
</Note>
## Customize Permissions
Permissions determine what each role can access or modify within your workspace, including workspace objects, records, settings, and actions.
### Object Permissions
The **Objects** section controls what this role can do with records across your workspace.
#### Set Default Permissions (All Objects)
First, configure the baseline permissions that apply to **all objects** by default:
| Permission | Description |
|------------|-------------|
| **See Records on All Objects** | View records in lists and detail pages |
| **Edit Records on All Objects** | Modify existing records |
| **Delete Records on All Objects** | Soft-delete records (can be restored) |
| **Destroy Records on All Objects** | Permanently delete records |
Select or unselect based on what should be the default behavior for this role.
<Note>
**Example — Intern role**: An intern should be able to see all objects but not edit them by default. Enable "See Records on All Objects" but leave "Edit Records on All Objects" unchecked.
</Note>
#### Add Object-Level Exceptions
After setting defaults, use the **Object-Level** sub-section to add rules that override the defaults for specific objects.
Click **+ Add rule** and select an object to create an exception.
**Example rules for an Intern role:**
| Rule | Effect |
|------|--------|
| Opportunities → disable "See Records" | Intern cannot see the Opportunities object at all |
| People → enable "Edit Records" | Intern can edit People records (but not other objects) |
### Row-Level Permissions
<Note>
Row-level permissions are a **Premium feature** available on the **Organization** plan (Cloud and Self-Hosted).
</Note>
Row-level permissions let you restrict which individual records a role can see or edit, based on dynamic criteria. Unlike object permissions (which apply to an entire object type), row-level permissions evaluate each record independently.
**Example use cases:**
- Sales reps can only see their own opportunities
- Managers can see all records in their region
- Support agents can only view tickets assigned to them
To configure row-level permissions, open a role, navigate to the **Objects** tab, and use the **Row-Level** section to define filter conditions for a specific object.
### Field Permissions
Within each object-level rule, you can go further and configure **field-level permissions** to control access to specific fields.
| Permission | Description |
|------------|-------------|
| **See Field** | View the field value |
| **Edit Field** | Modify the field value |
| **No Access** | Field is completely hidden |
**Example — Restrict sensitive fields:**
For the Intern role with People edit access, you might want to restrict certain fields:
- People → Email → **See Field** only (cannot edit)
- People → Address → **No Access** (completely hidden)
This allows the intern to edit most People fields while protecting sensitive information.
### How Permission Inheritance Works
Permissions cascade from general to specific:
1. **All Objects** → sets the baseline for all objects
2. **Object-Level rules** → override the baseline for specific objects
3. **Field-Level rules** → override the object setting for specific fields
More specific settings always take precedence.
### Managing Permission Overrides
To override inherited permissions:
1. Click **X** to remove the inherited rule
2. Select the specific permissions you want
3. Click the orange **Undo** icon (circular arrow) to revert changes
When done, click **Finish**, then **Save** once redirected to the role page.
### Workspace Settings Permissions
Control access to workspace settings in two ways:
- Toggle **Settings All Access** to grant full access
- Or enable specific permissions (e.g., API key generation, workspace preferences, role assignment, data model configuration, security settings, and workflow management)
<Note>
**Current limitation**: Access to workflow management is currently required to manually trigger workflows. This behavior may change in future releases.
</Note>
### Workspace Action Permissions
Control access to general workspace actions:
- Toggle **Application All Access** to grant full permissions
- Or enable individual actions such as **Send Email**, **Import CSV**, and **Export CSV**
## Assign Roles to API Keys and AI Agents
Beyond workspace members, roles can also be assigned to **API Keys** and **AI Agents**. This is particularly helpful for teams who want to control exactly "who" can do what in their workspace—including automated processes and integrations.
### Why Assign Roles to API Keys and AI Agents?
- **Security**: Limit what automated processes can access or modify
- **Compliance**: Ensure integrations only touch the data they need
- **Control**: Prevent accidental data changes from misconfigured automations
- **Auditability**: Track which actions were performed by which integration or agent
### Assign a Role to an API Key
1. Go to **Settings → Members → Roles**
2. Click on the role you want to assign
3. Open the **Assignment** tab
4. Under **API Keys**, click **+ Assign to API key**
5. Select the API key from the list
6. Confirm the assignment
The API key will now inherit all permissions defined by that role. Any API calls made with this key will be restricted accordingly.
<Note>
API keys without an assigned role use default permissions. For tighter security, always assign a specific role to production API keys.
</Note>
### Assign a Role to an AI Agent
1. Go to **Settings → Members → Roles**
2. Click on the role you want to assign
3. Open the **Assignment** tab
4. Under **AI Agents**, click **+ Assign to AI agent**
5. Select the AI agent from the list
6. Confirm the assignment
The AI agent will only be able to access data and perform actions allowed by its assigned role.
<Note>
For AI agents running within workflows, this ensures the agent cannot access or modify data outside its intended scope—even if the workflow has broader permissions.
</Note>

View File

@@ -0,0 +1,105 @@
---
title: SSO Configuration
description: Configure Single Sign-On for secure enterprise authentication.
---
## About SSO
Single Sign-On (SSO) allows your team members to log into Twenty using your organization's identity provider. This provides:
- **Centralized access control**: Manage access from one place
- **Enhanced security**: Leverage your existing security policies
- **Better user experience**: One set of credentials for all tools
## Supported Providers
Twenty supports SSO with:
- **SAML 2.0**: Works with most enterprise identity providers
- **Google Workspace**: For organizations using Google
- **Microsoft Entra ID** (formerly Azure AD): For Microsoft environments
## Setting Up SSO
### Prerequisites
- Organization plan (cloud and self-hosted workspaces)
- Admin access to your identity provider
- Admin access to your Twenty workspace
### Configuration Steps
#### 1. Access SSO Settings
1. Go to **Settings → Security**
2. Find the **SSO Configuration** section
3. Click **Configure SSO**
#### 2. Choose Your Provider
Select your identity provider from the list or choose "Custom SAML" for other providers.
#### 3. Configure Your Identity Provider
You'll need to configure your identity provider with:
- **Entity ID**: Provided by Twenty
- **ACS URL**: The callback URL for authentication
- **Certificate**: For secure communication
#### 4. Enter Provider Details in Twenty
- **SSO URL**: Login URL from your provider
- **Entity ID**: Your provider's identifier
- **Certificate**: X.509 certificate from your provider
#### 5. Test and Enable
1. Click **Test Configuration** to verify setup
2. Enable SSO when testing is successful
3. Configure user provisioning preferences
## User Provisioning
### Just-in-Time (JIT) Provisioning
- Users are created automatically on first login
- Users are assigned a default role automatically
- No manual user creation needed
### Manual Provisioning
- Invite users before they can log in
- Pre-assign specific roles
- More control over who can access the workspace
## Managing SSO Users
### Role Assignment
SSO users can be assigned roles like regular users:
1. Go to **Settings → Members**
2. Find the user
3. Change their role as needed
### Access Revocation
To remove access for SSO users:
- Remove them from your identity provider, or
- Remove them from the Twenty workspace
## Best Practices
### Security
- **Require SSO**: Disable password login for SSO users
- **Regular audits**: Review access periodically
- **Strong IdP policies**: Enforce MFA at the identity provider
### User Management
- **Clear naming**: Use consistent naming from your directory
- **Group mapping**: Map IdP groups to Twenty roles (if available)
- **Offboarding process**: Include Twenty in your deprovisioning workflow
## Troubleshooting
### Common Issues
- **Certificate errors**: Ensure the certificate hasn't expired
- **URL mismatches**: Verify the ACS URL matches exactly
- **User not found**: Check JIT provisioning settings
### Getting Help
If you encounter issues, contact support with:
- Error messages received
- Identity provider being used
- Configuration details (without sensitive data)
<Tip>
Need SSO configured for your organization? [Find a certified Twenty partner](https://twenty.com/partners/list?categories=SOLUTIONING&ref=docs-sso) who specializes in SSO and identity setup. *(Prefer to loop in Twenty directly? [contact@twenty.com](mailto:contact@twenty.com))*
</Tip>

View File

@@ -0,0 +1,121 @@
---
title: Permissions FAQ
description: Frequently asked questions about roles and permissions.
---
## Roles
<AccordionGroup>
<Accordion title="What roles come with Twenty by default?">
Twenty comes with **Admin** and **Member** roles by default. You can create additional custom roles based on your team's needs (e.g., Sales Rep, Manager, Read-Only User).
</Accordion>
<Accordion title="Can I delete the Admin role?">
No, the Admin role cannot be deleted. There must always be at least one member assigned to the Admin role.
</Accordion>
<Accordion title="What happens when I delete a role?">
Any workspace member assigned to that role will be automatically reassigned to the default role.
</Accordion>
<Accordion title="How do I set a default role for new members?">
Go to **Settings → Members → Roles**, find the **Default Role** option, and select which role new members should automatically receive when they join.
</Accordion>
<Accordion title="Can I assign multiple roles to one user?">
No, each user can only have one role at a time. Create a custom role if you need a combination of permissions.
</Accordion>
</AccordionGroup>
## Permissions
<AccordionGroup>
<Accordion title="What's the difference between object and field permissions?">
- **Object permissions**: Control access to entire records (e.g., can see/edit/delete People records)
- **Field permissions**: Control access to specific fields within an object (e.g., can see but not edit the Salary field)
Field permissions allow more granular control over sensitive data.
</Accordion>
<Accordion title="How do permission overrides work?">
Permissions cascade from general to specific:
1. **All Objects** sets the baseline for all objects
2. **Object-Level Permissions** can override the global setting for specific objects
3. **Field-Level Permissions** can override the object setting for specific fields
More specific settings always take precedence.
</Accordion>
<Accordion title="What do the different permission levels mean?">
For objects:
- **See Records**: View records in lists and detail pages
- **Edit Records**: Modify existing records
- **Delete Records**: Soft-delete records (can be restored)
- **Destroy Records**: Permanently delete records
For fields:
- **See Field**: View the field value
- **Edit Field**: Modify the field value
- **No Access**: Field is completely hidden
</Accordion>
<Accordion title="Can I restrict access to specific records (row-level permissions)?">
Row-level permissions are available on the **Organization** plan. This allows you to restrict access to specific records based on criteria (e.g., only see your own opportunities).
</Accordion>
<Accordion title="How do I make a field read-only for certain users?">
1. Go to **Settings → Members → Roles**
2. Select the role
3. Navigate to the object containing the field
4. Set the field permission to **See Field** (without Edit Field)
</Accordion>
</AccordionGroup>
## Settings & Actions
<AccordionGroup>
<Accordion title="What settings permissions are available?">
You can control access to:
- API key generation
- Workspace preferences
- Role assignment
- Data model configuration
- Security settings
- Workflow management
Use **Settings All Access** to grant full access, or enable specific permissions.
</Accordion>
<Accordion title="What action permissions are available?">
You can control:
- **Send Email**: Ability to send emails from Twenty
- **Import CSV**: Ability to import data via CSV
- **Export CSV**: Ability to export data to CSV
Use **Application All Access** to grant all actions, or enable specific ones.
</Accordion>
</AccordionGroup>
## SSO
<AccordionGroup>
<Accordion title="Is SSO available on all plans?">
No, SSO is a Premium feature available on the **Organization** plan only.
</Accordion>
<Accordion title="Which identity providers are supported?">
Twenty supports:
- **SAML 2.0** (works with most enterprise identity providers)
- **Google Workspace**
- **Microsoft Entra ID** (formerly Azure AD)
</Accordion>
<Accordion title="What is Just-in-Time (JIT) provisioning?">
With JIT provisioning, user accounts are automatically created in Twenty when someone logs in via SSO for the first time. They're assigned the default role automatically.
</Accordion>
<Accordion title="Can I require SSO for all users?">
Yes, once SSO is configured, you can disable password login for SSO users to enforce authentication through your identity provider.
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,34 @@
---
title: Permissions & Access
description: Manage roles, permissions, and access control in your workspace.
---
Twenty's permission system lets you control who can access and modify data in your workspace. Create roles, assign permissions, and configure SSO for secure access.
## What's in this section
<CardGroup cols={2}>
<Card title="Permissions" icon="lock" href="/user-guide/permissions-access/capabilities/permissions">
Create roles and configure object, field, and settings permissions.
</Card>
<Card title="SSO Configuration" icon="key" href="/user-guide/permissions-access/capabilities/sso-configuration">
Set up Single Sign-On with your identity provider.
</Card>
<Card title="FAQ" icon="circle-question" href="/user-guide/permissions-access/how-tos/permissions-faq">
Common questions about roles, permissions, and SSO.
</Card>
</CardGroup>
## Key features
- **Role-based access**: Create custom roles with specific permissions
- **Object permissions**: Control who can view, edit, or delete records
- **Field permissions**: Restrict access to sensitive fields
- **Settings permissions**: Control access to workspace configuration
- **SSO integration**: Configure single sign-on for enterprise security (Organization plan)
## Quick links
- [Create a Role](/user-guide/permissions-access/capabilities/permissions#create-a-role)
- [Configure SSO](/user-guide/permissions-access/capabilities/sso-configuration)
- [Manage team members](/user-guide/settings/capabilities/member-management)

View File

@@ -0,0 +1,34 @@
---
title: Community Settings
description: Enable Early Access features in Twenty.
---
## About Community Settings
The Community section allows you to enable Early Access features before they're generally available as well as search for Twenty partners.
## Early Access Features
Early Access features are capabilities that are still being tested before general availability.
**Currently in Early Access:**
- **Junction relations** — Many-to-many relations
### How to Enable Early Access Features
1. Go to **Settings → Community**
2. Navigate to the **Features** section
3. Find the feature you want to enable
4. Toggle it on
5. The feature will be available immediately
<Note>
Early Access features may change based on user feedback. Your input helps us improve Twenty!
</Note>
## Feature Feedback
Your feedback helps improve Twenty:
- Report issues with Early Access features
- Share how you're using new features
- Suggest improvements via the [community Discord](https://discord.gg/cx5n4Jzs57)

View File

@@ -0,0 +1,49 @@
---
title: Domain Settings
description: Configure workspace domain, approved access domains, and app custom domains.
---
Domain settings live in three places, depending on what you're configuring.
## Workspace Domain
Configure under **Settings → General**.
Edit your subdomain name or set a custom domain for your workspace.
### Customize Domain
1. Click **Subdomain** to edit your subdomain (e.g., `yourcompany.twenty.com`)
2. Or click **Custom domain** to set up a custom domain (e.g., `crm.yourcompany.com`)
For custom domains, you'll need to configure DNS settings with your domain provider.
## Approved Domains
Configure under **Settings → Members → Invite**.
Add your company domain to let team members sign up for this workspace automatically.
### Add Approved Access Domain
1. Click **Add Approved Access Domain**
2. Enter your company domain (e.g., `yourcompany.com`)
3. Save
Once configured, anyone with an email address at that domain can join your workspace without needing a direct invitation.
<Note>
This is useful for allowing your entire team to self-register while keeping the workspace restricted to your organization.
</Note>
## App Custom Domains
Configure under **Settings → Apps → your app → Settings → App URL**.
Apps that expose routes on the web are served from a dedicated URL, shown in the **App URL** section. You can serve an app from a domain you own instead.
### Add Custom Domain
1. Click **Custom Domain**
2. Enter the domain you want to use (e.g., `app.yourcompany.com`)
3. Configure DNS settings as instructed
4. Verify the domain
Only that app's routes are reachable on the domain. SSL certificates are provisioned automatically.

View File

@@ -0,0 +1,37 @@
---
title: Experience Settings
description: Customize your interface theme and regional preferences.
---
Personalize your Twenty experience under **Settings → Experience**.
## Appearance
Choose your visual theme:
- **Light**: Clean, bright interface
- **Dark**: Easier on the eyes in low-light conditions
- **System settings**: Automatically matches your device's theme
## Language
Select your preferred language for the Twenty interface from the dropdown menu.
## Formats
Configure date, time, number, time zone, and calendar start day.
| Setting | Description |
|---------|-------------|
| **Time zone** | Your local time zone for accurate timestamps and scheduling |
| **Date format** | How dates appear (e.g., Dec 12, 2025) |
| **Time format** | 12-hour (7:22 PM) or 24-hour format |
| **Number format** | Decimal and thousands separators (e.g., 1,234.56) |
| **Calendar start day** | First day of the week (Sunday or Monday) |
Each setting can be set to **System settings** to automatically match your device preferences, or you can choose a specific format.
## How to Update
1. Go to **Settings → Experience**
2. Adjust your preferences in each section
3. Changes save automatically

View File

@@ -0,0 +1,78 @@
---
title: Member Management
description: Invite team members and manage workspace access.
---
Manage who has access to your workspace under **Settings → Members**.
## Invite New Members
### Using Email Invitation
1. Go to **Settings → Members → Invite**
2. Click **+ Invite**
3. Enter the person's email address
4. Select a role for the new member
5. Click **Send invite**
The invited person will receive an email with a link to join your workspace.
### Using Invite Link
1. Go to **Settings → Members → Invite**
2. Copy the workspace invite link
3. Share the link with new team members
4. They'll receive access once they sign up
## View and Manage Members
### View All Members
Go to **Settings → Members → Team** to see all active members
Go to **Settings → Members → Invite** to see pending invitations
### Edit a Member's Profile
Click on a member to open their profile page. As an admin, you can:
- Edit their **name**
- Update their **profile picture**
- **Impersonate** their account (useful for troubleshooting)
- **Delete** their account
### Change a Member's Role
On the member's profile page:
1. Open the **Permissions** tab
2. View the currently assigned role
3. Select a different role from the dropdown
4. The change takes effect immediately
→ [Learn more about roles and permissions](/user-guide/permissions-access/capabilities/permissions)
### Remove a Member
1. Click on the member to open their profile
2. Click **Delete account** to remove them from the workspace
<Warning>
Removed members lose access immediately. Their data (records, notes, tasks) remains in the workspace.
</Warning>
<Note>
Emails and calendar events of the deleted member are archived and available for other members.
</Note>
## Pending Invitations
Manage invitations that haven't been accepted:
- **Resend**: Send the invitation email again
- **Cancel**: Revoke the invitation before it's accepted
## Approved Access Domains
Allow team members to join automatically based on their email domain:
1. Go to **Settings → Members → Invite**
2. Add your company domain (e.g., `yourcompany.com`)
3. Anyone with that email domain can join without an invitation
## Related
- [Permissions](/user-guide/permissions-access/capabilities/permissions) — configure what each role can do
- [Domain Settings](/user-guide/settings/capabilities/domains-settings) — configure approved domains

View File

@@ -0,0 +1,37 @@
---
title: Profile Settings
description: Manage your personal profile and security settings.
---
## Personal Information
### Name and Email
- **Display Name**: Update how your name appears to other workspace members
- **Email Address**: Change your login email (requires verification)
- **Profile Picture**: Upload a custom avatar or use your initials
## Security Settings
### Two-Factor Authentication (2FA)
Enable 2FA to add an extra layer of security to your account:
1. Go to **Settings → Profile**
2. Click **Authenticator app**
3. Scan the QR code with your authenticator app
4. Enter the verification code to confirm
### Password Management
- **Change Password**: Update your current password
- **Password Requirements**: Must be at least 8 characters long
## Profile Management
### Delete Account
<Warning>
Deleting your account will permanently remove your access to all workspaces. This action cannot be undone. You'll lose access to all workspaces where you're a member. If you only want to exit specific teams, consider leaving individual workspaces instead.
</Warning>
To delete your account:
1. Go to **Settings → Profile**
2. Scroll to **Danger Zone**
3. Click **Delete Account**
4. Confirm by typing your email address

View File

@@ -0,0 +1,25 @@
---
title: Workspace Settings
description: Customize your workspace name and branding.
---
Your workspace picture, name, and deletion options are all accessible under **Settings → General**.
## Workspace Picture
- **Upload Logo**: Add a custom workspace logo
- **Supported formats**: PNG, JPEG, and GIF files under 10MB
- **Remove**: Delete the current workspace logo
## Workspace Name
- **Name**: Change your workspace display name
- This name appears to all workspace members
## Danger Zone
<Warning>
Deleting your workspace permanently removes all data and immediately revokes access for all members — this action cannot be undone.
</Warning>
To delete your workspace:
1. Click the **Delete workspace** button
2. Confirm the deletion when prompted
**Note**: Only workspace administrators can delete workspaces.

View File

@@ -0,0 +1,171 @@
---
title: Settings FAQ
description: Frequently asked questions about Twenty settings.
---
## Workspace Settings
<AccordionGroup>
<Accordion title="How do I change my workspace name?">
1. Go to **Settings → General**
2. Find the Workspace Name field
3. Enter your new name
4. Changes save automatically
</Accordion>
<Accordion title="How do I update my workspace logo?">
1. Go to **Settings → General**
2. Click on the current logo or upload area
3. Select an image file (PNG, JPEG, or GIF under 10MB)
4. The logo updates immediately
</Accordion>
<Accordion title="Can I have multiple workspaces?">
Yes, you can create and be a member of multiple workspaces. Each workspace has its own data, settings, and subscription.
</Accordion>
<Accordion title="How do I delete my workspace?">
1. Go to **Settings → General**
2. Scroll to Danger Zone
3. Click **Delete workspace**
4. Confirm the deletion
Note: This permanently deletes all data and cannot be undone.
</Accordion>
<Accordion title="I accidentally created multiple workspaces. What should I do?">
Delete the workspaces you no longer need under **Settings → General → Delete workspace**.
<Warning>
Do not delete your **account** (accessible under Settings → Profile): your account is shared among all your workspaces. Deleting your account removes access to ALL workspaces.
</Warning>
</Accordion>
<Accordion title="How do I disable my workspace without deleting it?">
If you want to temporarily disable your workspace (not permanently delete it), go to **Settings → Billing** and click **Cancel Plan**. Your data will be preserved for a grace period.
</Accordion>
</AccordionGroup>
## Profile Settings
<AccordionGroup>
<Accordion title="How do I change my password?">
1. Go to **Settings → Profile**
2. Find the Password section
3. Enter your current password
4. Enter your new password
5. Save changes
</Accordion>
<Accordion title="How do I enable two-factor authentication?">
1. Go to **Settings → Profile**
2. Find the 2FA section
3. Click **Enable 2FA**
4. Scan the QR code with your authenticator app
5. Enter the verification code
</Accordion>
<Accordion title="Can I change my email address?">
To change your email address, please reach out to [contact@twenty.com](mailto:contact@twenty.com).
</Accordion>
<Accordion title="How do I delete my account?">
1. Go to **Settings → Profile**
2. Scroll to Danger Zone
3. Click **Delete Account**
4. Confirm by typing your email
Note: This removes your access to all workspaces and deletes all emails synced from your connected accounts.
</Accordion>
</AccordionGroup>
## Experience Settings
<AccordionGroup>
<Accordion title="How do I switch between light and dark mode?">
1. Go to **Settings → Experience**
2. Find the Theme section
3. Select Light, Dark, or System
</Accordion>
<Accordion title="How do I change the date format?">
1. Go to **Settings → Experience**
2. Find Date Format
3. Select your preferred format
4. Changes apply immediately
</Accordion>
<Accordion title="How do I change my time zone?">
1. Go to **Settings → Experience**
2. Find Time Zone
3. Select your local time zone
4. All timestamps will adjust
</Accordion>
<Accordion title="Can I change the language?">
1. Go to **Settings → Experience**
2. Find Language
3. Select from available languages
4. The interface updates to your selection
</Accordion>
</AccordionGroup>
## Account Settings
<AccordionGroup>
<Accordion title="How do I connect my email account?">
1. Go to **Settings → Accounts**
2. Click **Add account**
3. Choose Google or Microsoft
4. Authorize access
5. Configure sync settings
</Accordion>
<Accordion title="Can I connect multiple email accounts?">
Yes, you can connect multiple email accounts. Go to **Settings → Accounts** and add additional accounts as needed.
</Accordion>
<Accordion title="How do I disconnect an email account?">
1. Go to **Settings → Accounts**
2. Find the account to remove
3. Click **Disconnect**
4. Confirm the action
</Accordion>
</AccordionGroup>
## Domains
<AccordionGroup>
<Accordion title="Can I customize my workspace domain?">
Yes! Go to **Settings → General → Workspace Domain** and click **Customize Domain**. You have two options:
- **Subdomain**: Use a Twenty subdomain like `yourcompany.twenty.com`
- **Custom domain**: Use your own domain like `crm.yourcompany.com` (requires DNS configuration)
A subdomain is quick to set up, while a custom domain provides a fully branded experience for your team.
</Accordion>
<Accordion title="How do approved access domains work?">
You can configure approved access domains so team members with company email addresses can automatically join your workspace. Go to **Settings → Members → Invite** and add your company domain (e.g., `yourcompany.com`).
</Accordion>
</AccordionGroup>
## Early Access Features
<AccordionGroup>
<Accordion title="What are Early Access features?">
Early Access features are capabilities being tested before general release.
</Accordion>
<Accordion title="Are Early Access features safe to use?">
Early Access features are functional and safe to use, but may change based on user feedback before general availability.
</Accordion>
<Accordion title="How do I enable Early Access features?">
1. Go to **Settings → Community**
2. Scroll down to the **Features** section
3. Find the feature you want
4. Toggle it on
5. The feature becomes available immediately
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,57 @@
---
title: Settings
description: Set up your Twenty workspace with essential configurations.
---
## Initial Setup
When you first create your workspace, there are several key settings to configure.
### Workspace Name and Logo
1. Go to **Settings → General**
2. Update your workspace name
3. Upload your company logo
4. Save your changes
### Time Zone and Date Format
1. Go to **Settings → Experience**
2. Select your time zone
3. Choose your preferred date format
4. Save your changes
## Essential Configurations
### Connect Email and Calendar
Set up email and calendar sync:
1. Go to **Settings → Accounts**
2. Click **Add account**
3. Connect your Google or Microsoft account
4. Configure sync settings
→ [Complete email & calendar setup guide](/user-guide/calendar-emails/overview)
### Invite Your Team
Add team members to your workspace:
1. Go to **Settings → Members**
2. Click **+ Invite**
3. Enter email addresses
4. Assign appropriate roles
<Note>
Before inviting your team, check the default role under **Settings → Members → Roles**. New members are automatically assigned this role when they join.
</Note>
## Workspace Settings Checklist
- Workspace name and logo configured
- Time zone and date format set
- Email and calendar connected
- Team members invited
- Roles and permissions configured
## Next Steps
- [Workspace settings](/user-guide/settings/capabilities/workspace-settings)
- [Profile settings](/user-guide/settings/capabilities/profile-settings)
- [Experience settings](/user-guide/settings/capabilities/experience-settings)

View File

@@ -0,0 +1,42 @@
---
title: Calendar View
description: Display records with date fields on a calendar.
---
## About Calendar View
Calendar view displays your records on a calendar based on a date field. Each record appears as an event on the corresponding date.
<img src="/images/user-guide/views/calendar-view-zoom.png" style={{width:'100%'}}/>
## Creating a Calendar View
1. Navigate to an object with date fields
2. Click the view dropdown → **+ Add view**
3. Name your view and click **Create**
4. Open the **Options** on the right
5. Select **Calendar** as the layout
6. Choose the **date field** to use for positioning records
7. Click **Update view**
## Configuring the Calendar
### Choose the Date Field
Under **Options**, select which date field determines where records appear on the calendar.
### Display Fields
Configure which fields show on each calendar event:
1. Click **Options → Fields**
2. Toggle fields on/off
3. Drag to reorder
## Use Cases
- **Meetings and calls**: View upcoming appointments
- **Deadlines**: Track due dates and close dates
- **Events**: Plan and visualize scheduled activities
- **Follow-ups**: See when tasks are due
## Related
- [Views Overview](/user-guide/views-pipelines/overview) — creating and managing views
- [Filters and Sorting](/user-guide/views-pipelines/capabilities/filters-and-sorting) — filtering calendar data

View File

@@ -0,0 +1,49 @@
---
title: Fields & Columns
description: Choose which fields to display and how to organize them.
---
## Selecting Fields to Display
Each view can show a different set of fields. Customize what's visible to focus on the information that matters.
### Show or Hide Fields
1. Click **Options** in the top right
2. Click **Fields**
3. Click the **eye icon** next to each field to show/hide it
### Reorder Fields
Change the order fields appear in your view:
1. Click **Options → Fields**
2. Drag fields up or down
3. Changes save automatically
## Field Display by View Type
### Table Views
- Fields appear as columns
- Resize columns by dragging borders
### Kanban Views
- Fields appear on cards
- Reorder via Options → Fields
- Use Compact view to hide all fields
### Calendar Views
- Selected fields show on calendar events
- Configure via Options → Fields
## Best Practices
- **Show only what's needed** — too many fields clutter the view
- **Put important fields first** — most-used columns on the left
- **Create multiple views** — different field sets for different purposes
- **Use field visibility per view** — same object, different focus
## Related
- [Table Views](/user-guide/views-pipelines/capabilities/table-views) — list view features
- [Kanban Views](/user-guide/views-pipelines/capabilities/kanban-views) — card-based views

View File

@@ -0,0 +1,75 @@
---
title: Filters & Sorting
description: Filter and sort records to find exactly what you need.
---
## Filtering Data
Filters help you focus on specific records by showing only those that match your criteria.
### Adding a Filter
1. Click the **Filter** button in the toolbar
2. Select the field to filter by
3. Choose the operator (equals, contains, etc.)
4. Enter the filter value
5. Click **Apply**
### Filter Operators
| Field Type | Available Operators |
|------------|---------------------|
| Text | Equals, Contains, Starts with, Ends with, Is empty |
| Number | Equals, Greater than, Less than, Is empty |
| Date | Equals, Before, After, Is empty |
| Select | Equals, Is any of, Is empty |
| Checkbox | Is true, Is false |
| Relation | Equals, Is empty |
### Multiple Filters
Combine multiple filters to narrow down results:
- All filters are applied with AND logic
- Each additional filter further restricts results
### Removing Filters
- Click the **X** on individual filter chips
- Click **Clear all** to remove all filters
## Sorting Data
Sorting determines the order records appear.
### Adding a Sort
1. Click the **Sort** button in the toolbar
2. Select the field to sort by
3. Choose ascending (A-Z, 0-9) or descending (Z-A, 9-0)
4. Click **Apply**
### Multiple Sorts
Add multiple sort levels:
- First sort is primary
- Subsequent sorts apply within groups of equal values
### Quick Column Sorting
Click any column header to sort:
- First click: Ascending
- Second click: Descending
- Third click: Remove sort
## Saving Filter and Sort Settings
Filters and sorts are saved with the view:
1. Configure your filters and sorts
2. Click **Save** to update the current view
3. Or click **Save as new view** to create a variant
## Related
- [Table Views](/user-guide/views-pipelines/capabilities/table-views) — group by feature
- [Views Overview](/user-guide/views-pipelines/overview) — building and managing views

View File

@@ -0,0 +1,93 @@
---
title: Kanban Board Views
description: Learn how to use Kanban views to visualize and manage your workflows.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## About Kanban Views
Kanban views visually map out process flows, where each column stands for a distinct stage and each card represents a record.
## Move Cards between Stages
You can move each card between stages as it goes through your workflow by clicking and holding a card, then dragging it to the next stage.
<VimeoEmbed videoId="927888627" title="Video demonstration" />
## Add and Delete Stages
You can tailor your workflow to suit your needs using stages, each of which represents a value in a Select field:
### Add Stages
To add a stage, access the Select field settings by navigating to Settings > Data Model, selecting your object, and then selecting the field your Kanban board depends on.
<VimeoEmbed videoId="927890428" title="Video demonstration" />
### Remove Stages
To remove a stage, hover over the stage name or the `⋮` icon, click `Edit from settings` in the Select field settings, and then click **Delete** next to the relevant stage.
## Display Fields
You can configure your Kanban board to display some fields and hide others. To show or hide a field, click on **Options** on the top right, then on **Fields** to bring up the list of options, and click the eye icon next to the field to show or hide it.
You can also rearrange the order of fields by holding down the field name and dragging it to where you want it.
<img src="/images/user-guide/kanban-views/filter.png" style={{width:'100%'}}/>
## Compact view
You can hide all the fields and get an overview of all records at a glance. To enable:
1. Click **Options** on the top right
2. Turn on the toggle for **Compact view**
<img src="/images/user-guide/kanban-views/compact-view.png" style={{width:'100%'}}/>
## Column Aggregations
Each column in a Kanban view can display aggregated values at the top, helping you understand your data at a glance.
### Available Aggregations
| Aggregation | Description |
|-------------|-------------|
| **Count** | Number of records in the column |
| **Sum** | Total of a numeric field (e.g., deal amounts) |
| **Average** | Average value of a numeric field |
| **Min** | Lowest value |
| **Max** | Highest value |
### Configuring Aggregations
1. Click on the number displayed next to the Stage value, at the top of a column
2. Select the aggregation type
3. Choose the field to aggregate
**Example:** Show total deal value per stage by aggregating the Amount field with Sum.
## When to Use Kanban Views
Kanban views are ideal for:
- **Sales pipelines**: Track deals through stages from lead to close
- **Project management**: Monitor tasks through workflow states
- **Recruitment**: Track candidates through hiring stages
- **Any staged process**: Visualize any workflow with defined stages
## Best Practices
### Organize Your Stages
- **Limit stages**: 5-7 stages is ideal for visibility
- **Clear naming**: Use descriptive stage names
- **Logical order**: Arrange stages in process order
### Optimize Card Display
- **Show key fields**: Display only the most important information
- **Use Compact view**: For high-level overviews
- **Color coding**: Use stage colors to quickly identify status
### Maintain Data Quality
- **Update regularly**: Keep cards moving through stages
- **Archive completed**: Move closed items out of active view
- **Review stale cards**: Follow up on cards stuck in stages

View File

@@ -0,0 +1,59 @@
---
title: Table Views
description: Display your data in a spreadsheet-like list format.
---
## About Table Views
Table views display records in rows with customizable columns—like a spreadsheet. This is the default view type for most objects.
<img src="/images/user-guide/table-views/table-view.png" style={{width:'100%'}}/>
## Features
### Column Configuration
- Show or hide columns (fields)
- Resize column widths
- Reorder columns by dragging
### Group By a Select Field
Organize records into collapsible groups based on a field of select type.
<img src="/images/user-guide/table-views/table-group-by.png" style={{width:'100%'}}/>
1. Click **Options**
2. Select **Group**
3. Choose a Select field
4. Configure group order under **Options → Group → Sort**:
- **Alphabetical** or **Reverse alphabetical**
- **Manual order**: Drag groups under "Visible groups" to reorder
- Click the **eye icon** next to a group to hide it
**Use cases:**
- Group Companies by Type
- Group Opportunities by Stage
- Group Tasks by Status
<Note>
**For best performance, limit to 10-15 visible groups per view.** If you need more groups, consider using a Dashboard instead.
</Note>
### Column Widths
Resize columns to show more or less content:
1. Hover between two column headers
2. Click and drag the column border
3. Release to set the new width
## When to Use Table Views
Table views work best for:
- **Browsing large datasets** — scan many records quickly
- **Data entry** — edit multiple records efficiently
- **Detailed analysis** — see many fields at once
- **Sorting and filtering** — find specific records
## Related
- [Fields and Columns](/user-guide/views-pipelines/capabilities/fields-and-columns) — configuring which fields to display
- [Filters and Sorting](/user-guide/views-pipelines/capabilities/filters-and-sorting) — narrowing down records

View File

@@ -0,0 +1,73 @@
---
title: View Settings
description: Manage view visibility, naming, icons, and organization.
---
## View Visibility
Control who can see your custom views.
### Visibility Options
| Setting | Who Can See |
|---------|-------------|
| **Workspace** | All workspace members |
| **Unlisted** | Only you |
### Changing Visibility
1. Open the view
2. Click **Options → Visibility**
3. Select **Workspace** or **Unlisted**
<Note>
The default "All [Object Name]" views cannot have their visibility changed.
</Note>
## Rename a View
1. Open the view dropdown
2. Click the **⋮** menu next to the view
3. Select **Edit**
4. Enter the new name
## Change View Icon
1. Open the view dropdown
2. Click the **⋮** menu next to the view
3. Select **Edit**
4. Click the icon to change it
## Reorder Views
Change the order views appear in the dropdown:
1. Open the view dropdown
2. Drag views by their handle
3. Drop in the desired position
4. Order saves automatically
## Favorite a View
Pin frequently used views for quick access:
1. Open the view dropdown
2. Click the **⋮** menu next to a view
3. Select **Add to favorites**
Favorited views appear in a dedicated section for easy access.
## Delete a View
1. Open the view dropdown
2. Click the **⋮** menu next to the view
3. Select **Delete**
4. Confirm deletion
<Warning>
Deleted views cannot be recovered.
</Warning>
## Related
- [Views Overview](/user-guide/views-pipelines/overview) — creating views
- [How to Restrict Access](/user-guide/views-pipelines/how-tos/restrict-access-to-your-view) — step-by-step guide

View File

@@ -0,0 +1,59 @@
---
title: Create a Calendar View for Tasks Due
description: Visualize your tasks and deadlines on a calendar.
---
<img src="/images/user-guide/views/calendar-view-zoom.png" style={{width:'100%'}}/>
## Prerequisites
Your Tasks object needs a **Due Date** field (Date or Date & Time type).
## Steps
1. Navigate to **Tasks**
2. Click the view dropdown → **+ Add view**
3. Name your view (e.g., "Tasks Calendar")
4. Click **Create**
5. Click **Options** and select **Calendar** as the layout
6. Choose **Due Date** as the date field
7. Click **Save**
## Configure Your Calendar
### Display Fields on Events
1. Click **Options → Fields**
2. Click the **eye icon** to show/hide fields
3. Drag to reorder
Recommended fields to display:
- **Title** — task name
- **Assignee** — who's responsible
- **Status** — current progress
### Filter Your Calendar
Create focused views:
- **My Tasks**: Filter by Assignee = Me
- **This Week**: Filter by Due Date = This week
- **Overdue**: Filter by Due Date < Today, Status ≠ Done
## Other Calendar Use Cases
| Object | Date Field | Purpose |
|--------|------------|---------|
| Opportunities | Close Date | Track expected closes |
| Custom Events | Event Date | Plan activities |
| Projects | Deadline | Monitor project timelines |
## Tips
- **Review weekly**: Start each week by checking your calendar view
- **Combine with table view**: Use calendar for overview, table for details
- **Set visibility**: Keep personal task calendars as Unlisted
## Related
- [Calendar View](/user-guide/views-pipelines/capabilities/calendar-view) — all calendar features
- [Filters and Sorting](/user-guide/views-pipelines/capabilities/filters-and-sorting) — filter your calendar

View File

@@ -0,0 +1,71 @@
---
title: Create a Kanban View for Projects
description: Track projects through stages using a visual board.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
Use a Kanban view to visualize your projects (or any object with stages) as cards moving through columns.
<VimeoEmbed videoId="927888627" title="Video demonstration" />
## Prerequisites
Your object needs a **Select field** to use as columns (e.g., Status, Stage, Phase).
If you don't have one:
1. Go to **Settings → Data Model**
2. Select your object
3. Add a Select field with your stage options
## Steps
1. Navigate to your object (e.g., Projects, Tasks)
2. Click the view dropdown → **+ Add view**
3. Name your view (e.g., "Project Board")
4. Click **Create**
5. Click **Options** and select **Kanban** as the layout
6. The view uses your Select field for columns automatically
7. Click **Save**
## Configure Your Board
### Show Key Fields on Cards
1. Click **Options → Fields**
2. Find fields in the "Hidden Fields" section
3. Click the **eye icon** to display them on cards
4. Drag to reorder
<img src="/images/user-guide/kanban-views/filter.png" style={{width:'100%'}}/>
### Enable compact view
For a high-level overview:
1. Click **Options**
2. Turn on **Compact view**
Cards show only the record name.
<img src="/images/user-guide/kanban-views/compact-view.png" style={{width:'100%'}}/>
### Add Aggregations
Show counts or totals at the top of each column:
1. Click the number next to a column name
2. Select an aggregation (Count, Sum, etc.)
3. Choose a field if needed
## Moving Cards
Drag and drop cards between columns to update their status.
<VimeoEmbed videoId="927888627" title="Video demonstration" />
## Example: Task Board
| Column (Status) | Cards |
|-----------------|-------|
| **To Do** | New tasks |
| **In Progress** | Active work |
| **Review** | Awaiting approval |
| **Done** | Completed |
## Related
- [Kanban Views](/user-guide/views-pipelines/capabilities/kanban-views) — aggregations, compact view, stages
- [How to Set Up a Sales Pipeline](/user-guide/views-pipelines/how-tos/set-up-a-sales-pipeline) — Kanban for Opportunities

View File

@@ -0,0 +1,51 @@
---
title: Create a Table View with Grouping
description: Organize your records into collapsible groups by field value.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
Group your table view by a Select field to organize records into collapsible sections.
<img src="/images/user-guide/table-views/table-group-by.png" style={{width:'100%'}}/>
## Steps
1. Navigate to the object (People, Companies, etc.)
2. Click the view dropdown → **+ Add view**
3. Name your view (e.g., "Companies by Type")
4. Click **Create**
5. Click **Options → Group**
6. Choose a Select field to group by
7. Click **Save**
## Configure Group Order
Under **Options → Group → Sort**, choose how groups are ordered:
| Option | Description |
|--------|-------------|
| **Alphabetical** | A to Z |
| **Reverse alphabetical** | Z to A |
| **Manual order** | Drag groups to reorder under "Visible groups" |
Click the **eye icon** next to a group to hide it from the view.
<Note>
**For best performance, limit to 10-15 visible groups.** If you need more, consider using a Dashboard instead.
</Note>
## Example: Companies by Industry
1. Go to **Companies**
2. Create a new view named "By Industry"
3. Click **Options → Group**
4. Select the **Industry** field
5. Save
Now your companies are organized by industry, making it easy to focus on one segment at a time.
## Related
- [Table Views](/user-guide/views-pipelines/capabilities/table-views) — all table view features
- [Filters and Sorting](/user-guide/views-pipelines/capabilities/filters-and-sorting) — combine grouping with filters

View File

@@ -0,0 +1,32 @@
---
title: Restrict Access to Your View
description: Control who can see your custom views.
---
Each view (except the default "All [Object Name]" views) has its own visibility setting.
## Steps
1. Open the view you want to restrict
2. Click **Options** in the top right
3. Click **Visibility**
4. Select **Unlisted**
Your view is now visible only to you.
## Visibility Options
| Setting | Who Can See |
|---------|-------------|
| **Workspace** | All workspace members |
| **Unlisted** | Only you |
## Notes
- The default "All [Object Name]" views cannot be made unlisted
- Unlisted views don't appear in other users' view dropdowns
- You can change visibility back to Workspace at any time
## Related
- [View Settings](/user-guide/views-pipelines/capabilities/view-settings) — all view configuration options

View File

@@ -0,0 +1,108 @@
---
title: Set Up a Sales Pipeline
description: Configure your sales pipeline to track opportunities through stages.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
A sales pipeline in Twenty is a Kanban view of your Opportunities object, where each column represents a stage in your sales process.
## Step 1: Configure Your Stages
Stages are defined in the Opportunities object's **Stage** field.
1. Go to **Settings → Data Model**
2. Select **Opportunities**
3. Find and click the **Stage** field
4. Add, remove, or rename stages to match your process
<VimeoEmbed videoId="927890428" title="Video demonstration" />
### Recommended Stages
| Stage | Purpose |
|-------|---------|
| **New** | Fresh opportunities just identified |
| **Qualified** | Confirmed as a good fit |
| **Meeting** | Engaged in discussions |
| **Proposal** | Proposal sent |
| **Negotiation** | Working on terms |
| **Closed Won** | Deal successful |
| **Closed Lost** | Deal unsuccessful |
<Note>
**5-7 stages is optimal.** Too many stages make the pipeline hard to scan; too few lose visibility into deal progress.
</Note>
## Step 2: Create a Pipeline View
1. Go to **Opportunities**
2. Click the view dropdown → **+ Add view**
3. Name it "Sales Pipeline"
4. Click **Create**
5. Open **Options** and select **Kanban** as the layout
The view automatically uses the Stage field for columns.
## Step 3: Configure Your View
### Show Key Fields
1. Click **Options → Fields**
2. Look for fields in the "Hidden Fields" section
3. Click the **eye icon** to display: Company, Amount, Close Date, Owner
### Enable Aggregations
Show totals at the top of each column:
1. Click the number displayed next to a Stage name at the top of a column
2. Select the aggregation type (Count, Sum, Average, etc.)
3. Choose the field to aggregate (e.g., Amount)
**Example:** Show total deal value per stage by aggregating the Amount field with Sum.
### Use compact view (optional)
For a high-level overview with minimal card content:
1. Click **Options**
2. Turn on the toggle for **Compact view**
## Step 4: Create Personal and Team Views
### "My Pipeline"
- **Filter**: Owner = Me
- **Visibility**: Unlisted (personal view)
### "Team Pipeline"
- **Filter**: None (show all)
- **Visibility**: Workspace (shared view)
### "Closing This Month"
- **Type**: Table
- **Filter**: Close Date = This month, Stage ≠ Closed Won, Stage ≠ Closed Lost
- **Sort**: Close Date ascending
## Working with Opportunities
### Creating Opportunities
- Click **+ New** in the Opportunities view
- Or click **+** in a specific stage column
### Moving Through Stages
Drag and drop opportunity cards between columns to update their stage.
<VimeoEmbed videoId="927888627" title="Video demonstration" />
## Best Practices
### Pipeline Hygiene
- Update deals daily as they progress
- Move or close stale deals promptly
- Keep close dates realistic
### Stage Discipline
- Define clear criteria for each stage
- Move deals promptly when criteria are met
- Don't let deals sit in stages too long
## Related
- [Kanban Views](/user-guide/views-pipelines/capabilities/kanban-views) — aggregations and compact view
- [Filters and Sorting](/user-guide/views-pipelines/capabilities/filters-and-sorting) — creating filtered views

View File

@@ -0,0 +1,147 @@
---
title: Show Expected Amount in Your Pipeline
description: Calculate and display weighted deal values based on stage probability.
---
The Expected Amount is a calculated value: **Amount × Probability**. This helps you forecast revenue by weighting deals based on how likely they are to close.
<Tip>
This is an example of creating [Formula Fields](/user-guide/workflows/how-tos/crm-automations/formula-fields) using workflows.
</Tip>
This guide walks you through setting up the custom fields and workflows needed to calculate and display expected amounts in your pipeline.
## Step 1: Create Custom Fields
You need two custom fields on the Opportunities object.
### Create the Probability Field
1. Go to **Settings → Data Model → Opportunities**
2. Click **+ Add Field**
3. Configure:
- **Name**: Probability
- **Type**: Number
- **Description**: Stage-based probability (0-100%)
4. Click **Save**
### Create the Expected Amount Field
1. Click **+ Add Field**
2. Configure:
- **Name**: Expected Amount
- **Type**: Currency
- **Description**: Calculated: Amount × Probability
3. Click **Save**
### Optional: Make Fields Read-Only for Users
If you don't want users manually editing these calculated fields:
1. Go to **Settings → Members → Roles**
2. Select the role to configure
3. Find the Opportunities object
4. Set **Probability** and **Expected Amount** fields to read-only
This ensures only the workflows can update these values.
## Step 2: Create Workflow #1 — Update Probability on Stage Change
This workflow automatically sets the Probability when an opportunity moves to a new stage.
### Create the Workflow
1. Go to **Workflows**
2. Click **+ New Workflow**
3. Name it "Update Probability on Stage Change"
### Configure the Trigger
1. Add a **Record Created or Updated** trigger
2. Select **Opportunities** as the object
3. Filter on: **Stage** field is updated
### Add Branches for Each Stage
Create a branch for each stage with its probability:
| Stage | Probability |
|-------|-------------|
| New | 10% |
| Qualified | 25% |
| Meeting | 40% |
| Proposal | 60% |
| Negotiation | 80% |
| Closed Won | 100% |
| Closed Lost | 0% |
<Note>
To create a new branch, right click on the workflow canvas and click **New action**. Then, link this action to the previous node by dragging the arrow from the previous node to this new action.
</Note>
For each stage:
1. Add a **Filter** node: Stage = [stage name]
2. Add an **Update Record** action:
- Record: The triggering Opportunity
- Field: Probability
- Value: [probability for that stage]
### Calculate Expected Amount
After the branches rejoin:
1. Add a **Filter** node: Amount is not empty
2. Add an **Update Record** action:
- Record: The triggering Opportunity
- Field: Expected Amount
- Value: Amount × Probability
## Step 3: Create Workflow #2 — Recalculate on Amount Change
This workflow updates the Expected Amount when the deal Amount changes.
### Create the Workflow
1. Go to **Workflows**
2. Click **+ New Workflow**
3. Name it "Recalculate Expected Amount on Amount Change"
### Configure the Trigger
1. Add a **Record Created or Updated** trigger
2. Select **Opportunities** as the object
3. Filter on: **Amount** field is updated
### Add the Logic
1. Add a **Filter** node: Amount is not empty
2. Add an **Update Record** action:
- Record: The triggering Opportunity
- Field: Expected Amount
- Value: Amount × Probability
## Step 4: Display in Your Pipeline
Now show the Expected Amount totals in your Kanban view:
1. Open your **Sales Pipeline** Kanban view
2. Click the **number** next to any Stage name at the top of a column
3. Select **Sum**
4. Choose **Expected Amount**
Each column now shows the total weighted pipeline value for that stage.
## Summary
| Component | Purpose |
|-----------|---------|
| **Probability field** | Stores the stage-based win probability |
| **Expected Amount field** | Stores Amount × Probability |
| **Workflow #1** | Updates Probability when Stage changes, then recalculates Expected Amount |
| **Workflow #2** | Recalculates Expected Amount when Amount changes |
| **Aggregation** | Displays Sum of Expected Amount per stage |
## Related
- [Formula Fields](/user-guide/workflows/how-tos/crm-automations/formula-fields) — create calculated fields using workflows
- [Kanban Views](/user-guide/views-pipelines/capabilities/kanban-views) — column aggregations
- [How to Create Custom Fields](/user-guide/data-model/how-tos/create-custom-fields) — field configuration

View File

@@ -0,0 +1,226 @@
---
title: Track How Long Opportunities Stay in Each Stage
description: Monitor deal velocity by tracking when opportunities enter each stage.
---
<Tip>
This is an example of creating [Formula Fields](/user-guide/workflows/how-tos/crm-automations/formula-fields) using workflows — specifically date calculations.
</Tip>
Tracking when opportunities enter each stage helps you identify bottlenecks and measure deal velocity.
This guide walks you through setting up custom fields and a workflow to automatically record when an opportunity moves to each stage, and calculate how many days it spent in the previous stage.
## Step 1: Create Custom Fields
You need two types of fields for each stage:
- **Date & Time fields**: Record when the opportunity entered each stage
- **Number fields**: Store how many days the opportunity spent in each stage
### Create the "Last Entered" Fields
1. Go to **Settings → Data Model → Opportunities**
2. For each stage, click **+ Add Field** and configure:
- **Name**: Last Entered [Stage Name] (e.g., "Last Entered New", "Last Entered Qualified")
- **Type**: Date & Time
- **Description**: Timestamp when opportunity entered this stage
3. Click **Save**
Create these fields:
- Last Entered New
- Last Entered Qualified
- Last Entered Meeting
- Last Entered Proposal
- Last Entered Negotiation
- Last Entered Closed Won
- Last Entered Closed Lost
### Create the "Days in Stage" Fields
1. For each stage, click **+ Add Field** and configure:
- **Name**: Days in [Stage Name] (e.g., "Days in New", "Days in Qualified")
- **Type**: Number
- **Description**: Number of days spent in this stage
2. Click **Save**
Create these fields:
- Days in New
- Days in Qualified
- Days in Meeting
- Days in Proposal
- Days in Negotiation
<Note>
You don't need "Days in" fields for Closed Won and Closed Lost since those are final stages.
</Note>
### Optional: Make Fields Read-Only
If you don't want users manually editing these calculated fields:
1. Go to **Settings → Members → Roles**
2. Select the role to configure
3. Find the Opportunities object
4. Set the "Last Entered" and "Days in" fields to read-only
## Step 2: Create the Workflow
This single workflow handles both tasks:
- Records the timestamp when entering a new stage
- Calculates days spent in the previous stage
### Create the Workflow
1. Go to **Workflows**
2. Click **+ New Workflow**
3. Name it "Track Stage Time"
### Configure the Trigger
1. Add a **Record Updated** trigger
2. Select **Opportunities** as the object
3. Filter on: **Stage** field is updated
### Add Branches for Each Stage
<Note>
To create a new branch, right click on the workflow canvas and click **New action**. Then, link this action to the previous node by dragging the arrow from the previous node to this new action.
</Note>
---
**Branch 1: Stage = New (first stage)**
Since this is the first stage, only the entry timestamp is recorded — there's no previous stage to calculate from.
1. Add a **Filter** node: Stage = New
2. Add a **Code** action:
```javascript
export const main = async (): Promise<object> => {
return { now: new Date().toISOString() };
};
```
3. Add an **Update Record** action:
- Record: The triggering Opportunity
- Field: Last Entered New
- Value: `now` from Code node
---
**Branch 2: Stage = Qualified**
When moving to Qualified, record entry time AND calculate days spent in New.
1. Add a **Filter** node: Stage = Qualified
2. Add a **Code** action:
```javascript
export const main = async (params: {
lastEnteredPreviousStage: Date;
}): Promise<object> => {
const { lastEnteredPreviousStage } = params;
const now = new Date();
const entryDate = new Date(lastEnteredPreviousStage);
const diffTime = Math.abs(now.getTime() - entryDate.getTime());
const daysInPreviousStage = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return {
now: now.toISOString(),
daysInPreviousStage: daysInPreviousStage
};
};
```
3. Configure the Code node input: map `lastEnteredPreviousStage` to the **Last Entered New** field
4. Add an **Update Record** action:
- Record: The triggering Opportunity
- Fields to update:
- Last Entered Qualified = `now`
- Days in New = `daysInPreviousStage`
---
**Branch 3: Stage = Meeting**
When moving to Meeting, record entry time AND calculate days spent in Qualified.
1. Add a **Filter** node: Stage = Meeting
2. Add a **Code** action:
```javascript
export const main = async (params: {
lastEnteredPreviousStage: Date;
}): Promise<object> => {
const { lastEnteredPreviousStage } = params;
const now = new Date();
const entryDate = new Date(lastEnteredPreviousStage);
const diffTime = Math.abs(now.getTime() - entryDate.getTime());
const daysInPreviousStage = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return {
now: now.toISOString(),
daysInPreviousStage: daysInPreviousStage
};
};
```
3. Configure the Code node input: map `lastEnteredPreviousStage` to the **Last Entered Qualified** field
4. Add an **Update Record** action:
- Record: The triggering Opportunity
- Fields to update:
- Last Entered Meeting = `now`
- Days in Qualified = `daysInPreviousStage`
---
**Continue for remaining stages:**
| Stage | Records | Calculates |
|-------|---------|------------|
| Proposal | Last Entered Proposal | Days in Meeting |
| Negotiation | Last Entered Negotiation | Days in Proposal |
| Closed Won | Last Entered Closed Won | Days in Negotiation |
| Closed Lost | Last Entered Closed Lost | Days in Negotiation |
The branches do not need to rejoin—each runs independently when its stage condition is met.
## Step 3: Analyze Time in Stage
With timestamps and day counts recorded, you can now analyze deal velocity.
### Create a "Slow Deals" View
1. Create a Table view of Opportunities
2. Add columns: Name, Stage, Days in [previous stage], Amount
3. Sort by "Days in" field (descending)
4. Filter by Stage to focus on one stage at a time
Deals at the top spent the most time in the previous stage.
### Use Aggregations
In your pipeline Kanban view:
1. Click the number next to a Stage name
2. Select **Average**
3. Choose a "Days in" field
This shows the average time deals spend in each stage.
## Summary
| Component | Purpose |
|-----------|---------|
| **Last Entered fields** | Store when opportunity entered each stage |
| **Days in fields** | Store how many days spent in each stage |
| **Workflow** | Records timestamp AND calculates days in one pass |
| **Views & Aggregations** | Analyze deal velocity and identify bottlenecks |
## Related
- [Workflows](/user-guide/workflows/overview) — automation basics
- [How to Create Custom Fields](/user-guide/data-model/how-tos/create-custom-fields) — field configuration
- [Kanban Views](/user-guide/views-pipelines/capabilities/kanban-views) — aggregations

View File

@@ -0,0 +1,115 @@
---
title: Views & Pipelines
description: Learn how to create and manage views in Twenty.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## Understanding Views
Views are saved configurations that determine how your data is displayed. Each view can have its own:
- **Layout**: Table, Kanban, or Calendar
- **Filters**: Which records to show
- **Sorting**: How records are ordered
- **Fields**: Which columns are visible
## View Types
### Table View
The default spreadsheet-like view showing records in rows with customizable columns.
### Kanban View
A visual board view where records appear as cards organized by stages. Ideal for:
- Sales pipelines
- Project tracking
- Any workflow with defined stages
### Calendar View
A calendar view that displays records with date fields. Perfect for:
- Meetings and events
- Deadlines and due dates
- Time-based planning
## Creating a View
There are two ways to create a new view.
### Use the View Dropdown Menu
1. Navigate to any object (People, Companies, etc.)
2. Click the view name at the top left (shows current view with a dropdown arrow)
3. Click **+ Add view**
4. Name your view and click **Create**
5. Choose a layout (Table, Kanban, or Calendar) under **Options**
6. Add filters and sorting as needed
7. Select which fields to display and reorder them
8. Click **Save**
<VimeoEmbed videoId="1145648745" title="Video demonstration" />
### Start by Editing an Existing View
1. Navigate to any object (People, Companies, etc.)
2. Choose a layout (Table, Kanban, or Calendar) under **Options**, and add filters and sorting as needed
3. Click on **Save as new view**
4. Name your view and click **Create**
5. Keep editing your new view
6. Click on **Update view** to save your additional configurations
<VimeoEmbed videoId="1145654005" title="Video demonstration" />
## Managing Views
### Edit a View
1. Select the view from the dropdown
2. Make your changes (filters, sorting, columns)
3. Click **Save** to update the view
### Rename a View or Change Its Icon
1. Open the view dropdown
2. Click the **⋮** menu next to the view name
3. Select **Edit**
4. Change the name or icon
5. Click **Save**
### Reorder Views
1. Open the view dropdown
2. Click and drag a view by its handle
3. Drop it in the desired position
4. The new order is saved automatically
### Add to Favorites
Pin frequently used views for quick access:
1. Open the view dropdown
2. Click the **⋮** menu next to a view
3. Select **Add to favorites**
4. The view appears in your favorites section
### Delete a View
1. Select the view to delete
2. Click the view dropdown
3. Click the **⋮** menu next to the view
4. Select **Delete**
5. Confirm deletion
<Warning>
Deleted views cannot be recovered. Make sure you want to remove it before confirming.
</Warning>
## View Visibility
Each view (except the default "All [Object Name]" views) has its own visibility setting.
To change visibility:
1. Open the view
2. Click **Options → Visibility**
3. Choose:
- **Workspace**: Visible to all workspace members
- **Unlisted**: Visible only to you
<Note>
The default "All [Object Name]" views cannot have their visibility changed.
</Note>
## Next Steps
- [Table Views](/user-guide/views-pipelines/capabilities/table-views)
- [Kanban Views](/user-guide/views-pipelines/capabilities/kanban-views)
- [Filters and Sorting](/user-guide/views-pipelines/capabilities/filters-and-sorting)
- [View Settings](/user-guide/views-pipelines/capabilities/view-settings)

View File

@@ -0,0 +1,163 @@
---
title: Send Emails from Workflows
description: Send personalized emails automatically using workflow actions.
---
Automatically send emails when specific events occur in your CRM—welcome new contacts, follow up on opportunities, or notify team members.
## Prerequisites
Before you can send emails from workflows:
1. Connect an email account under **Settings → Accounts**
2. Ensure the account has sending permissions enabled
## Basic Email Workflow
### Example: Welcome Email for New Contacts
**Goal**: Send a welcome email when a new person is added to the CRM.
**Setup**:
1. **Create workflow**: Go to **Settings → Workflows** and click **+ New Workflow**
2. **Add trigger**: Select **Record is Created** → **People**
3. **Add Send Email action**:
- Click **+** to add an action
- Select **Send Email**
- Configure the email:
| Field | Value |
|-------|-------|
| **To** | `{{trigger.object.email}}` |
| **Subject** | `Welcome to {{Your Company Name}}` |
| **Body** | `Hi {{trigger.object.firstName}}, ...` |
4. **Test and activate**: Test with a sample record, then activate
## Using Variables in Emails
Reference data from previous steps using `{{variable}}` syntax:
```text
Hi {{trigger.object.firstName}},
Thank you for connecting with us!
Your company, {{trigger.object.company.name}}, is now in our system.
Best regards,
The Team
```
### Available Variables from Triggers
| Trigger Type | Common Variables |
|--------------|------------------|
| **Record Created/Updated** | `{{trigger.object.fieldName}}` |
| **Manual** | `{{trigger.selectedRecord.fieldName}}` |
| **Webhook** | `{{trigger.body.fieldName}}` |
## Advanced: Conditional Emails
### Example: Different Emails Based on Lead Source
**Goal**: Send different welcome emails based on where the lead came from.
**Setup**:
1. **Trigger**: Record is Created (People)
2. **Add Filter action**:
- Condition: `{{trigger.object.source}}` equals `"Website"`
- If true → continue to website welcome email
3. **Branch for other sources**:
- Create parallel branches for different sources
- Each branch has its own Send Email action
## Sending Emails to Multiple Recipients
### Example: Notify Team When Deal Closes
**Goal**: Email the sales rep and their manager when an opportunity is won.
**Setup**:
1. **Trigger**: Record is Updated (Opportunities, Stage = "Closed Won")
2. **Search Records**: Find the opportunity owner's manager
3. **Send Email #1**: To opportunity owner
- To: `{{trigger.object.owner.email}}`
- Subject: `Congratulations on closing {{trigger.object.name}}!`
4. **Send Email #2**: To manager
- To: `{{searchRecords.manager.email}}`
- Subject: `Deal Won: {{trigger.object.name}}`
## Scheduled Follow-up Emails
### Example: Follow Up 3 Days After Meeting
**Goal**: Send a follow-up email 3 days after a meeting is logged.
**Setup**:
1. **Trigger**: Record is Created (Activities, Type = "Meeting")
2. **Delay action**: Wait 3 days
3. **Send Email**:
- To: Meeting attendee
- Subject: Following up on our conversation
- Body: Reference meeting details from trigger
## Email Attachments
You can attach files to emails sent from workflows. The attachment is a static file that you upload when configuring the workflow.
### How to Add an Attachment
1. In the **Send Email** action, click on the **Attachments** button
2. Click to upload a file from your computer
3. The file will be attached to all emails sent by this action
### Common Use Cases
| Use Case | Example File |
|----------|--------------|
| **Welcome emails** | Company brochure (PDF) |
| **Onboarding sequences** | Getting started guide |
| **Sales follow-ups** | Product catalog or price list |
| **Event confirmations** | Event details or agenda |
<Note>
Attachments are static—the same file is sent to all recipients. For dynamic documents (like personalized quotes), generate and attach files using a [Logic Function](/user-guide/workflows/how-tos/connect-to-other-tools/generate-pdf-from-twenty).
</Note>
## Best Practices
### Email Content
- Keep subject lines concise and relevant
- Personalize with recipient's name
- Include a clear call to action
- Test emails before activating
### Deliverability
- Don't send too many emails too quickly
- Use professional email signatures
- Avoid spam trigger words
- Ensure unsubscribe options for marketing emails
### Troubleshooting
- Verify email account is connected and active
- Check recipient email address is valid
- Review workflow runs for error messages
- Test with your own email address first
## Related
- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers)
- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions)

View File

@@ -0,0 +1,89 @@
---
title: Use Branches in Workflows
description: Understand how branches work and how to control which path is executed.
---
## How Branches Work
In the workflow editor, you can create multiple paths (branches) going out from a single node. This allows you to build complex automations with different outcomes.
**Important**: When a workflow runs, **all branches execute in parallel by default**. There is no built-in "if/else" logic to choose one branch over another—every path will run simultaneously.
## Controlling Which Branch Runs
To execute only one branch based on specific conditions, **add a Filter node at the beginning of each branch**.
### Example Setup
1. Create your workflow with multiple branches from a single node
2. Add a **Filter** node as the first step in each branch
3. Set conditions on each Filter to determine when that branch should continue
4. Only the branch(es) whose Filter conditions are met will proceed
### How Filters Work
- If the Filter condition is **met**: The branch continues executing
- If the Filter condition is **not met**: The branch stops at the Filter node
This effectively creates conditional logic where only the appropriate branch runs based on your data.
## Example: Route by Deal Size
**Scenario**: When a deal is closed, send different notifications based on deal size.
1. **Trigger**: Opportunity updated (Stage = Closed Won)
2. **Branch 1**: Filter for Amount > $10,000 → Send Slack message to #big-deals
3. **Branch 2**: Filter for Amount ≤ $10,000 → Send email to sales manager
Both branches start, but only the one matching the deal amount will continue past its Filter.
## Creating Branches
<Note>
To create a new branch from an existing step, click the **+** button on the step and add your action. You can add multiple branches by clicking **+** multiple times.
</Note>
1. In the workflow editor, select the step you want to branch from
2. Click the **+** button to add an action
3. This creates one branch
4. Click **+** again on the same step to create additional branches
5. Each branch can have its own sequence of actions
## Merging Branches Back Together
After parallel branches complete their work, you can merge them back into a single path:
1. Complete your branched actions
2. Add a new step that should run after all branches
3. Drag a connection from the last step of each branch to this new step
4. The merged step waits for all connected branches to complete before executing
### Example: Process Then Notify
```
Trigger
│
├── Branch A: Update Customer Record
│
└── Branch B: Create Support Ticket
↘ ↙
Merged Step: Send Confirmation Email
```
The confirmation email is sent only after both the customer update and ticket creation are done.
## Best Practices
- Always use **Filter nodes** at the start of branches when you want conditional execution
- Keep branch conditions **mutually exclusive** to avoid duplicate actions
- Test your workflows with different data to ensure the correct branches run
- **Rename branch steps** descriptively so it's clear what each path does
- **Merge branches** when you need a final action after parallel processing
## Related
- [Workflows FAQ](/user-guide/workflows/how-tos/need-more-help/workflows-faq) — answers about parallel execution
- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) — available actions for branches

View File

@@ -0,0 +1,181 @@
---
title: Use Iterator
description: Loop through arrays of records to perform actions on each item.
---
Iterator lets you loop through an array of records and perform actions on each one. It's essential for workflows that need to process multiple records returned by Search Records or received via webhooks.
## When to Use Iterator
| Scenario | Example |
|----------|---------|
| **Process search results** | Send email to each person found |
| **Handle webhook arrays** | Create records for each item in order |
| **Bulk updates** | Update multiple records with calculated values |
| **Notifications** | Alert multiple people about an event |
## Understanding Iterator
Iterator expects an **array** as input. It then:
1. Takes the first item from the array
2. Runs all actions inside the Iterator with that item
3. Moves to the next item
4. Repeats until all items are processed
### Selecting the array to loop over
Most array sources (Search Records, a webhook array field, a Bulk manual trigger) can be selected directly in the variable picker.
When a **Code** or **Logic Function** step returns a *top-level array*, its output appears in the variable picker as indexed entries (`0`, `1`, `2`, …). To loop over the array as a whole, select the **Whole list** option for that step — the Iterator then infers the shape of each item from the list automatically.
## Basic Setup
### Example: Email Everyone in Search Results
**Goal**: Find all contacts in a specific company and send each one a personalized email.
### Step 1: Search for Records
1. Add **Search Records** action
2. Object: **People**
3. Filter: Company equals "Acme Inc"
4. This returns an array of people
### Step 2: Check Results Exist
1. Add **Filter** action
2. Condition: `{{searchRecords.length}}` is greater than 0
3. This prevents Iterator errors on empty results
### Step 3: Add Iterator
1. Add **Iterator** action
2. Array input: Select `{{searchRecords}}`
3. This creates a loop
### Step 4: Add Actions Inside Iterator
Actions placed after Iterator run for each item:
1. Add **Send Email** action (inside Iterator)
2. To: `{{iterator.currentItem.email}}`
3. Subject: Hello `{{iterator.currentItem.firstName}}`!
4. Body: Personalized message using current item fields
### Result
If Search Records returns 5 people, the Iterator:
- Sends email to person 1
- Sends email to person 2
- ... continues for all 5
## Accessing Current Item Data
Inside Iterator, use `{{iterator.currentItem}}` to access the current record:
| Variable | Description |
|----------|-------------|
| `{{iterator.currentItem}}` | The entire current record object |
| `{{iterator.currentItem.id}}` | Record ID |
| `{{iterator.currentItem.email}}` | Email field |
| `{{iterator.currentItem.company.name}}` | Related company name |
| `{{iterator.index}}` | Current position in array (0-based) |
In the variable picker, you can either drill into a specific field of the current item, or pick **Use the whole item** to reference the entire current item (`{{iterator.currentItem}}`). Selecting the whole item is handy when you want to pass a full record straight into a downstream step rather than rebuilding it field by field.
## Common Patterns
### Update Multiple Records
**Goal**: Mark all overdue tasks as "Late"
```
1. Search Records (Tasks, Due Date < Today, Status ≠ Completed)
2. Filter (length > 0)
3. Iterator (searchRecords)
└── Update Record
- Object: Tasks
- Record: {{iterator.currentItem.id}}
- Status: Late
```
### Create Records from Array
**Goal**: Webhook receives order with multiple items, create a record for each
```
1. Webhook Trigger (receives items array)
2. Filter (items.length > 0)
3. Iterator (trigger.body.items)
└── Create Record
- Object: Order Items
- Name: {{iterator.currentItem.name}}
- Quantity: {{iterator.currentItem.qty}}
- Related Order: {{trigger.body.orderId}}
```
### Conditional Processing Inside Loop
**Goal**: Only send email to contacts with valid emails
```
1. Search Records (People)
2. Iterator (searchRecords)
└── Filter (currentItem.email is not empty)
└── Send Email
- To: {{iterator.currentItem.email}}
```
## Troubleshooting
### "Iterator expects an array"
**Cause**: You passed a single record instead of an array.
**Fix**: Make sure you're passing the result of Search Records or an array field, not a single record.
```
✅ Correct: {{searchRecords}}
❌ Wrong: {{searchRecords[0]}}
```
### Iterator Doesn't Run
**Cause**: The array is empty.
**Fix**: Add a Filter before Iterator to check array length:
```
Filter: {{searchRecords.length}} > 0
```
### Actions Run Too Many Times
**Cause**: Search Records returned more records than expected.
**Fix**:
- Add more specific filters to Search Records
- Set a limit on Search Records (max 200)
- Add Filter inside Iterator for additional conditions
## Performance Considerations
- **Credit usage**: Each iteration consumes credits for its actions
- **Time**: Large arrays take longer to process
- **Limits**: Consider batching very large operations
- **Rate limits**: External API calls may hit rate limits with many iterations
## Best Practices
1. **Always check array length** before Iterator to avoid errors
2. **Add filters inside loops** when not all items need processing
3. **Rename your Iterator step** to describe what it's looping through
4. **Test with small arrays** before processing large datasets
5. **Monitor workflow runs** to ensure iterations complete as expected
## Related
- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions)
- [How to Use Branches](/user-guide/workflows/capabilities/use-branches-in-workflows)
- [Workflows FAQ](/user-guide/workflows/how-tos/need-more-help/workflows-faq)

View File

@@ -0,0 +1,286 @@
---
title: Workflow Actions
description: Learn about the actions available in Twenty workflows.
---
import { VimeoEmbed } from '/snippets/vimeo-embed.mdx';
## About Actions
Actions define what happens after a trigger fires. You can chain multiple actions together to build complex automations.
<Tip>
- Use the variable picker (click the `(x+)` icon) to browse available data from previous steps
- Hover over any input field to see which step a variable comes from — helpful when the same field (e.g., ID) exists in multiple previous steps
- Give each action a descriptive name for easier maintenance
</Tip>
## Record Actions
<img src="/images/user-guide/workflows/workflow_actions.png" style={{width:'100%'}}/>
### Create Record
Adds a new record to a selected object.
**Configuration**:
- Select the target object
- Fill out the required and optional fields
- Use data from previous steps or input values manually to populate fields
**Output**: The newly created record data is available for use in subsequent steps.
### Update Record
Modifies an existing record in a selected object.
<img src="/images/user-guide/workflows/update_record.png" style={{width:'100%'}}/>
**Configuration**:
- Select the target object
- Choose the specific record to update.
- You can either choose a fixed record, using the drop down menu displaying all available records.
- Or you can have the record dynamically selected, by designating a record found in a previous step, using the `(x+)`. You cannot search for the record based on different criteria at this stage. If you've not yet identified the record, add a `Search Record` step before this `Update Record` step.
- Select fields to modify and enter new values
**Output**: The updated record data is available for use in subsequent steps.
### Delete Record
Removes a record from a selected object.
**Configuration**:
- Select the target object
- Choose the specific record to delete
**Output**: The deleted record data remains available for use in subsequent steps.
### Search Records
Finds records within a selected object using filter conditions.
**Configuration**:
- Select the object to search
- Set filter criteria to narrow results
- Configure sorting and limits
**Output**: Returns matching records that can be used in subsequent steps.
<Note>
**Limit**: Search Records returns a maximum of **200 records**. If you need to process more, add specific filters to reduce results or use scheduled workflows to process in batches.
</Note>
**Best Practice**: Use [branches](/user-guide/workflows/capabilities/workflow-branches) after Search Records to handle "found" vs "not found" scenarios.
### Upsert Record
Creates a new record or updates an existing one based on matching criteria. This is useful when you're not sure if a record already exists.
<img src="/images/user-guide/workflows/upsert_double_identifier.png" style={{width:'100%'}}/>
**Configuration**:
- Select the target object
- Note which fields can be used for matching: email for People, domain for Companies, ID for any object, or any field marked as Unique. You'll need to populate at least one of these below.
- Fill out the field values. Do not forget to populate at least one of the unique identifiers.
<Note>
**Matching usually works even better when adding only one unique identifier.** For example, the screenshot below will match companies based on their domain. The ID is not necessarily needed.
</Note>
<img src="/images/user-guide/workflows/upsert_simple_identifier.png" style={{width:'100%'}}/>
- Use data from previous steps to populate fields
**How it works**:
1. Searches for a record matching your criteria
2. If found → updates the existing record
3. If not found → creates a new record
**Output**: The created or updated record data is available for use in subsequent steps.
## Flow Actions
### Iterator
**Loops through an array of records** returned from a previous step, allowing you to perform actions on each record individually.
**Configuration**:
- Select the array of records from a previous step (e.g., results from Search Records, from a Manual trigger with Bulk availability, from a Code node). When a Code or Logic Function step returns a top-level array, select its **Whole list** option to loop over the entire output.
- Define the actions to perform on each record in the loop.
<Note>
- You can add several actions within an Iterator.
- When using branches inside an Iterator, make sure the last step of each branch connects back to the Iterator to close the loop.
</Note>
- Access `Current Item` Fields: to use fields from the record currently being processed, click on the **Iterator** step, then select **Current item**. The list of available fields from that record will be displayed and can be selected for use in subsequent actions. You can also select **Use the whole item** to pass the entire current item into a downstream step.
<VimeoEmbed videoId="1146577247" title="Video demonstration" />
### Filter
Filters records based on specified conditions, allowing only records that meet the criteria to pass through.
**Configuration**:
- Select the record to filter
- Define filter conditions and criteria
- Configure which records should pass through to subsequent steps
<Note>
1. **Output**: Filter nodes don't return data—they act as gates. If the conditions are met, the workflow continues. If not, the workflow stops at that branch.
2. The `IS` operator can be used with numeric fields. It performs as an `EQUAL`.
</Note>
### Delay
Pauses workflow execution for a specified duration or until a specific date/time.
**Delay Types**:
| Type | Description |
|------|-------------|
| **Duration** | Wait for a specific amount of time (days, hours, minutes, seconds) |
| **Scheduled Date** | Wait until a specific date and time |
**Configuration for Duration**:
- Set days, hours, minutes, and/or seconds
- Combine multiple units (e.g., 2 days and 4 hours)
**Configuration for Scheduled Date**:
- Select a date and time
- Can reference a date field from a previous step (e.g., follow up 3 days after a meeting)
**Use cases**:
- Wait 24 hours before sending a follow-up email
- Pause until an opportunity's close date
- Schedule actions for business hours
<Note>
The scheduled date cannot be in the past. If a date field from a previous step is used and the date has already passed, the workflow will fail.
</Note>
**Limits & Credits**:
- **No maximum duration limit**—you can set delays of minutes, days, weeks, or longer
- **1 credit consumed** when the Delay node executes, regardless of duration
- **No credits consumed** while waiting—a 5-minute delay costs the same as a 5-day delay
## Communication Actions
### Send Email
Sends an email from your workflow. This is great for templated group emails. Emails will look like the ones you send from your mailbox.
It's not suited for newsletters (which require richer formatting) or automated email sequences.
**Prerequisites**: Add an email account in Settings → Accounts
**Configuration**:
- Select the sender email account
<Note>
You can only send emails from mailboxes synced to your own Twenty account. Sending from other team members' mailboxes (e.g., the account owner's email) is on the roadmap.
</Note>
For all the following steps, you can reference variables from previous steps for personalization.
- Enter recipient email address.
<Note>
Only one recipient is possible at the moment.
</Note>
- Set subject line.
- Compose message body. You can format links, create numbered lists, bullet point lists, and add attachments.
<Note>
Adding HTML signatures is not possible at the moment.
</Note>
### Form
Prompts a form during workflow execution to collect user input. The responses can then be used in subsequent steps to create records, send emails, or execute any other action based on the input.
<Warning>
**Forms are designed for manual triggers only**. For workflows with other triggers (Record Created, Updated, etc.), forms are only accessible via the workflow run interface, which is not the expected user experience. A notification center will be released in 2026 to properly support forms in automated workflows.
</Warning>
**Configuration**:
- Configure the fields that users will be asked to fill. For each field, choose
- a type among text, number, date, a given record, a select field. Fields from all objects are available for selection.
- a label
- a default value under `Placeholder` (optional)
- Edit the form title
**Output**: Form responses are available for use in subsequent steps.
**Example**: The "Quick Lead" workflow is available by default in all workspaces, available anywhere in the Command Menu `Cmd+K`.
**How to fill the form**:
- Trigger your manual workflow from the Command Menu `Cmd+K`
- Fill the form that is displayed in the side panel and click `Submit`.
<Note>
The fields cannot be made mandatory.
</Note>
<VimeoEmbed videoId="1147277989" title="Video demonstration" />
## Integration Actions
### Code
Runs custom JavaScript within your workflow.
Behind the scenes, each Code action is backed by its own **logic function** — a server-side TypeScript function that runs on the Twenty platform. When you add a Code action, Twenty creates a dedicated logic function for that step and exposes its editor inline, so the code you write lives with the workflow.
**Configuration**:
- Access variables from previous steps. You can edit the variables' names dynamically.
<VimeoEmbed videoId="1147281795" title="Video demonstration" />
- Write JavaScript code in the editor
- Return variables for use in subsequent steps
- Test code directly in the step
<Note>
If you need to use external API keys in your code, you must input them directly in the function body. You cannot configure API keys elsewhere and reference them in the logic function.
</Note>
<Tip>
**Working with arrays?** Arrays from external systems or previous steps may come as strings. See [How to handle arrays in Code actions](/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions) for the solution.
</Tip>
<Tip>
Click the square icon at the top right of the code editor to display it in full screen — helpful since the default editor width is limited.
</Tip>
#### Reusing a logic function across workflows
The inline Code action is great for one-off logic, but the code it holds belongs to that single step. When you want to share the same logic across several workflows — or maintain it as versioned source in an app — define a **reusable logic function** instead of copy-pasting code into each Code action.
A logic function is defined once in an app (using the SDK's `defineLogicFunction`) and exposed to the workflow builder by adding `workflowActionTriggerSettings`. Once your app is installed, that function appears as its own action in the workflow builder, alongside the built-in actions. Selecting it renders the input fields you declared (with variable pickers, just like other actions) and runs your shared code — no inline JavaScript required.
| | Code action | Reusable logic function |
|---|---|---|
| **Where the code lives** | Inline editor, tied to one workflow step | Defined in an app, versioned in source control |
| **Reuse** | Copy-pasted per step | Added as an action in any workflow |
| **Inputs** | Variables wired in the editor | Fields rendered from your declared input schema |
| **Best for** | Quick, workflow-specific logic | Shared logic used across multiple workflows |
Both run on the same logic function runtime, so a Code action you've prototyped inline can later be promoted into a reusable logic function with minimal changes.
<Tip>
For the developer-facing reference on defining logic functions and exposing them to the workflow builder, see [Logic Functions](/developers/extend/apps/logic/logic-functions) — in particular the **Exposing a function as an AI tool or workflow action** section and `workflowActionTriggerSettings`.
</Tip>
### HTTP Request
Sends a request to an external API as part of your workflow.
<img src="/images/user-guide/workflows/http_action.png" style={{width:'100%'}}/>
**Configuration**:
- Enter the API endpoint URL. Using parameters from previous steps is possible.
- Select HTTP method (GET, POST, PUT, PATCH, DELETE)
- Add required headers and values
- Provide sample response for structure preview
## AI Actions
### AI Agent - Coming Soon
Runs an AI agent within your workflow to perform intelligent tasks.
**Configuration**:
- **Agent**: Select an existing AI agent or use the default agent
- **Prompt**: Write the instruction for the AI agent
- Reference variables from previous steps in the prompt
**What AI Agents can do**:
- Analyze and summarize data
- Classify or categorize records
- Generate text content
- Make decisions based on data
- Interact with your CRM data using tools
**Output**: The AI agent's response is available for use in subsequent steps. If the agent has a structured output schema, the response will follow that format.
<Note>
AI Agent actions consume workflow credits based on the AI model used. See [Workflow Credits](/user-guide/workflows/capabilities/workflow-credits) for details.
</Note>
<Note>
AI agents respect role-based permissions. You can assign specific roles to agents under **Settings → Members → Roles** to control what data they can access. See [Permissions](/user-guide/permissions-access/capabilities/permissions) for details.
</Note>

View File

@@ -0,0 +1,69 @@
---
title: Workflow Branches
description: Create parallel paths and conditional logic in your workflows.
---
Branches allow you to split your workflow into multiple paths that can run simultaneously or conditionally based on your data.
<img src="/images/user-guide/workflows/branches.png" style={{width:'100%'}}/>
## How Branches Work
When you create multiple connections from a single node, each path becomes a branch. By default, **all branches execute in parallel**—they don't wait for each other.
## Creating Branches
### Add a New Branch
1. **Right-click on the main canvas** of the workflow (not on an existing node)
2. Click **Add node**
3. Choose the node type for your new branch
4. Drag an arrow from the bottom of the previous step to the top of this new action
5. Repeat to add more branches from the same node
<Note>
Each branch is independent. Adding a branch doesn't affect other existing paths from that node.
</Note>
### Visual Layout
Branches appear as parallel paths in the workflow editor. You can drag nodes to rearrange the visual layout without affecting execution.
## Conditional Branches
Since all branches run by default, use **Filter** nodes to control which paths actually execute:
| Branch | Filter Condition | Action |
|--------|------------------|--------|
| A | Stage = "Won" | Send congratulations email |
| B | Stage = "Lost" | Create follow-up task |
| C | Stage = "Negotiation" | Notify manager |
1. Create branches from your trigger or action
2. Add a **Filter** node as the first step of each branch
3. Configure each filter with mutually exclusive conditions
4. Add your actions after each filter
Only the branch(es) where the filter condition is met will continue executing.
## Merging Branches
**Branches don't automatically merge.** Each branch runs independently until it ends. You have full flexibility in how you handle this:
- **Option 1: Keep branches separate**
Each branch handles its own follow-up actions independently. This is the simplest approach when branches don't need to converge.
- **Option 2: Merge branches manually**
When creating your workflow, you can manually connect multiple branches to the same downstream action. Simply drag arrows from the end of each branch to a common node.
<Note>
While you can use a [Delay](/user-guide/workflows/capabilities/workflow-actions#delay) node to pause execution, it's not currently configurable to wait "until another branch ends."
</Note>
## Related
- [How to Use Branches in Workflows](/user-guide/workflows/capabilities/use-branches-in-workflows) - Step-by-step guide
- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) - Available actions including Filter

View File

@@ -0,0 +1,73 @@
---
title: Workflow Credits
description: Understand workflow credit consumption and management.
---
Workflow credits power your automations in Twenty. Understanding how they work helps you optimize costs and manage your automation budget effectively.
## Credit Allocation
Workflow credits are allocated based on your billing cycle, not your plan tier:
| Billing Cycle | Credits |
|---------------|---------|
| **Monthly subscription** | 5 credits per month |
| **Yearly subscription** | 50 credits per year |
<Note>
5 monthly credits are generous for standard automations. Most teams won't exceed this limit with typical workflow usage. Additional credits are primarily needed for advanced Code actions and AI-powered workflows.
</Note>
## How Credit Consumption Works
Credits are consumed when workflows execute, not when you create them. Each workflow action consumes credits based on its complexity:
### Credit Consumption by Action Type
- **Basic internal operations**: Very low credit consumption
- Search Records
- Create Record
- Update Record
- Delete Record
- Form actions
- **Complex operations**: Higher credit consumption
- Code actions (JavaScript execution)
- HTTP Requests to external services
- **AI features**: Higher credit consumption
- AI Agent actions consume credits based on the AI model used
- More complex prompts and longer outputs use more credits
- **Delay actions**: Minimal credit consumption
- The Delay node consumes **1 credit** when it executes
- **No credits are consumed** during the wait period
- A 5-minute delay costs the same as a 5-day delay
### Real-Time Deduction
Credits are deducted in real-time as workflows execute. This means:
- Draft workflows don't consume credits
- Only active, running workflows use your credit allocation
- Failed workflows still consume credits for completed steps
## Managing Credits
### Check Credit Usage
1. Go to **Settings → Billing**
2. View your current credit consumption and remaining balance
3. Monitor usage patterns to optimize your workflows
### Purchasing Additional Credits
If you need more credits beyond your plan allocation:
1. Go to **Settings → Billing**
2. Click on the option to purchase additional credits. Packages of different sizes are available.
3. Credits are added to your current balance
## Best Practices
- **Batch Processing**: Use bulk operations and Iterator actions efficiently to reduce individual action calls
- **Manual Trigger Optimization**: For manual triggers, choose `Bulk` availability to process multiple records in a single workflow run
- Optimize Code actions for efficiency

View File

@@ -0,0 +1,84 @@
---
title: Workflow Runs
description: Monitor and manage workflow executions.
---
## About Runs
A **Run** is a record of a workflow execution. Every time a workflow is triggered—whether by a record event, schedule, manual action, or webhook—a new run is created.
## Viewing Runs
### From the Workflow Editor
1. Open the workflow you want to monitor
2. Click the **Runs** panel on the right side
3. See a list of recent runs with their status
### From the Workflow Runs View
1. Go to **Workflow Runs** in the sidebar
2. View runs across all workflows
3. Filter by status, workflow, or date
## Run Statuses
| Status | Description |
|--------|-------------|
| **Running** | Workflow is currently executing |
| **Completed** | Workflow finished successfully |
| **Failed** | Workflow encountered an error and stopped |
| **Waiting** | Workflow is paused (e.g., waiting for a Delay action or Form submission) |
## Run Details
Click on any run to see:
- **Status**: Current state of the run
- **Started at**: When the run began
- **Duration**: How long the run took
- **Trigger data**: The input that started the workflow
- **Step outputs**: Data returned by each step
- **Error messages**: If the run failed, what went wrong
## Step-by-Step Execution
Each run shows the progression through your workflow:
1. See which steps completed successfully
2. Identify where failures occurred
3. View the data passed between steps
4. Debug issues by examining step inputs and outputs
## Error Handling
When a run fails:
1. Open the failed run
2. Find the step that caused the failure
3. Check the error message for details
Common issues:
- Missing required fields
- Invalid data format
- External API errors
- Permission issues
## Re-running Workflows
If a run fails, you can:
- Fix the underlying issue and wait for the next trigger
- For manual workflows, trigger again with the same or updated data
- Review the workflow logic to prevent future failures
## Performance Tips
### Managing Run History
- Runs are retained for historical reference
- Very old runs may be archived automatically
- Export run data if you need to keep records
### Monitoring Best Practices
- Check runs regularly after activating new workflows
- Review failed runs to identify patterns
## Related
- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers)
- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions)
- [Workflow Troubleshooting](/user-guide/workflows/how-tos/need-more-help/workflow-troubleshooting)

Some files were not shown because too many files have changed in this diff Show More