diff --git a/packages/twenty-docs/developers/api-and-webhooks/api.mdx b/packages/twenty-docs/developers/api-and-webhooks/api.mdx deleted file mode 100644 index 6fd70229ab..0000000000 --- a/packages/twenty-docs/developers/api-and-webhooks/api.mdx +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: API -image: /images/docs/getting-started/api.png -info: Discover how to use our APIs. ---- - - Header - - -## Overview -The Twenty API allows developers to interact programmatically with the Twenty CRM platform. Using the API, you can integrate Twenty with other systems, automate data synchronization, and build custom solutions around your customer data. The API provides endpoints to **create, read, update, and delete** core CRM objects (such as people and companies) as well as access metadata configuration. - -**API Playground:** You can now access the API Playground within the app's settings. To try out API calls in real-time, log in to your Twenty workspace and navigate to **Settings → APIs & Webhooks**. This opens the in-app API Playground and the settings for API keys. -**[Go to API Settings](https://app.twenty.com/settings)** - -## Authentication -Twenty’s API uses API keys for authentication. Every request to protected endpoints must include an API key in the header. - -* **API Keys:** You can generate a new API key from your Twenty app’s **API settings** page. Each API key is a secret token that grants access to your CRM data, so keep it safe. If a key is compromised, revoke it from the settings and generate a new one. -* **Auth Header:** Once you have an API key, include it in the `Authorization` header of your HTTP requests. Use the Bearer token scheme. For example: - ``` - Authorization: Bearer YOUR_API_KEY - ``` - - Replace `YOUR_API_KEY` with the key you obtained. This header must be present on **all API requests**. If the token is missing or invalid, the API will respond with an authentication error (HTTP 401 Unauthorized). - -## API Endpoints -All resources can be accessed and via REST or GraphQL. - -* **Cloud:** `https://api.twenty.com/` or your custom domain / sub-domain -* **Self-Hosted Instances:** If you are running Twenty on your own server, use your own domain in place of `api.twenty.com` (for example, `https://{your-domain}/rest/`). - -Endpoints are grouped into two categories: **Core API** and **Metadata API**. The **Core API** deals with primary CRM data (e.g. people, companies, notes, tasks), while the **Metadata API** covers configuration data (like custom fields or object definitions). Most integrations will primarily use the Core API. - -### Core API -Accessed on `/rest/` or `/graphql/`. -The **Core API** serves as a unified interface for managing core CRM entities (people, companies, notes, tasks) and their relationships, offering **both REST and GraphQL** interaction models. - -### Metadata API -Accessed on `/rest/metadata/` or `/metadata/`. -The Metadata API endpoints allow you to retrieve information about your schema and settings. For instance, you can fetch definitions of custom fields, object schemas, etc. - -* **Example Endpoints:** - - * `GET /rest/metadata/objects` – List all object types and their metadata (fields, relationships). - * `GET /rest/metadata/objects/{objectName}` – Get metadata for a specific object (e.g., `people`, `companies`). - * `GET /rest/metadata/picklists` – Retrieve picklist (dropdown) field options defined in the CRM. - -Typically, the metadata endpoints are used to understand the structure of data (for dynamic integrations or form-building) rather than to manage actual records. They are read-only in most cases. Authentication is required for these as well (use your API key). diff --git a/packages/twenty-docs/developers/api-and-webhooks/webhooks.mdx b/packages/twenty-docs/developers/api-and-webhooks/webhooks.mdx deleted file mode 100644 index 89c79de1d8..0000000000 --- a/packages/twenty-docs/developers/api-and-webhooks/webhooks.mdx +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: Webhooks -image: /images/docs/getting-started/webhooks.png -info: Discover how to use our Webhooks. ---- - - Header - - -## Overview -Webhooks in Twenty complement the API by enabling **real-time notifications** to your own applications when certain events happen in your CRM. Instead of continuously polling the API for changes, you can set up webhooks to have Twenty **push** data to your system whenever specific events occur (for example, when a new record is created or an existing record is updated). This helps keep external systems in sync with Twenty instantly and efficiently. - -With webhooks, Twenty will send an HTTP POST request to a URL you specify, containing details about the event. You can then handle that data in your application (e.g., to update your external database, trigger workflows, or send alerts). - -## Setting Up a Webhook -To create a webhook in Twenty, use the **APIs & Webhooks** settings in your Twenty app: - -1. **Navigate to Settings:** In your Twenty application, go to **Settings → APIs & Webhooks**. -2. **Create a Webhook:** Under **Webhooks** click on **+ Create webhook**. -3. **Enter URL:** Provide the endpoint URL on your server where you want Twenty to send webhook requests. This should be a publicly accessible URL that can handle POST requests. -4. **Save:** Click **Save** to create the webhook. The new webhook will be active immediately. - -You can create multiple webhooks if you need to send different events to different endpoints. Each webhook is essentially a subscription for all relevant events (at this time, Twenty sends all event types to the given URL; filtering specific event types may be configurable in the UI). If you ever need to remove a webhook, you can delete it from the same settings page (select the webhook and choose delete). - -## Events and Payloads -Once a webhook is set up, Twenty will send an HTTP POST request to your specified URL whenever a trigger event occurs in your CRM data. Common events that trigger webhooks include: - -* **Record Created:** e.g. a new person is added (`person.created`), a new company is created (`company.created`), a note is created (`note.created`), etc. -* **Record Updated:** e.g. an existing person's information is updated (`person.updated`), a company record is edited (`company.updated`), etc. -* **Record Deleted:** e.g. a person or company is deleted (`person.deleted`, `company.deleted`). -* **Other Events:** If applicable, other object events or custom triggers (for instance, if tasks or other objects are updated, similar event types would be used like `task.created`, `note.updated`, etc.). - -The webhook POST request contains a JSON payload in its body. The payload will generally include at least two things: the type of event, and the data related to that event (often the record that was created/updated). For example, a webhook for a newly created person might send a payload like: - -``` -{ - "event": "person.created", - "data": { - "id": "abc12345", - "firstName": "Alice", - "lastName": "Doe", - "email": "alice@example.com", - "createdAt": "2025-02-10T15:30:45Z", - "createdBy": "user_123" - }, - "timestamp": "2025-02-10T15:30:50Z" -} -``` - -In this example: - -* `"event"` specifies what happened (`person.created`). -* `"data"` contains the new record's details (the same information you would get if you requested that person via the API). -* `"timestamp"` is when the event occurred (in UTC). - -Your endpoint should be prepared to receive such JSON data via POST. Typically, you'll parse the JSON, look at the `"event"` type to understand what happened, and then use the `"data"` accordingly (e.g., create a new contact in your system, or update an existing one). - -**Note:** It's important to respond with a **2xx HTTP status** from your webhook endpoint to acknowledge successful receipt. If the Twenty webhook sender does not get a 2xx response, it may consider the delivery failed. (In the future, retry logic might attempt to resend failed webhooks, so always strive to return a 200 OK as quickly as possible after processing the data.) - -## Webhook Validation - -To ensure the security of your webhook endpoints, Twenty includes a signature in the `X-Twenty-Webhook-Signature` header. - -This signature is an HMAC SHA256 hash of the request payload, computed using your webhook secret. - -To validate the signature, you'll need to: -1. Concatenate the timestamp (from `X-Twenty-Webhook-Timestamp` header), a colon, and the JSON string of the payload -2. Compute the HMAC SHA256 hash using your webhook secret as the key () -3. Compare the resulting hex digest with the signature header - -Here's an example in Node.js: - -```javascript -const crypto = require("crypto"); -const timestamp = "1735066639761"; -const payload = JSON.stringify({...}); -const secret = "your-secret"; -const stringToSign = `${timestamp}:${JSON.stringify(payload)}`; -const signature = crypto.createHmac("sha256", secret) - .update(stringToSign) - .digest("hex"); -``` diff --git a/packages/twenty-docs/developers/bug-and-requests.mdx b/packages/twenty-docs/developers/bug-and-requests.mdx deleted file mode 100644 index e0ca42f294..0000000000 --- a/packages/twenty-docs/developers/bug-and-requests.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Bugs and Requests -image: /images/user-guide/api/api.png -info: Ask for help on GitHub or Discord ---- - - Header - - -## Reporting Bugs -To report a bug, please [create an issue on GitHub](https://github.com/twentyhq/twenty/issues/new). - -You can also ask for help on [Discord](https://discord.gg/cx5n4Jzs57). - -## Feature Requests - -If you're not sure if it's a bug, and you feel it's closer to a feature request, then you should probably [open a discussion instead](https://github.com/twentyhq/twenty/discussions/new). - diff --git a/packages/twenty-docs/developers/backend-development/best-practices-server.mdx b/packages/twenty-docs/developers/contribute/capabilities/backend-development/best-practices-server.mdx similarity index 85% rename from packages/twenty-docs/developers/backend-development/best-practices-server.mdx rename to packages/twenty-docs/developers/contribute/capabilities/backend-development/best-practices-server.mdx index 0da8a62f74..58d4716ce2 100644 --- a/packages/twenty-docs/developers/backend-development/best-practices-server.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/backend-development/best-practices-server.mdx @@ -1,27 +1,24 @@ --- title: Best Practices -image: /images/user-guide/tips/light-bulb.png --- - - Header - + This document outlines the best practices you should follow when working on the backend. ## Follow a modular approach -The backend follows a modular approach, which is a fundamental principle when working with NestJS. Make sure you break down your code into reusable modules to maintain a clean and organized codebase. -Each module should encapsulate a particular feature or functionality and have a well-defined scope. This modular approach enables clear separation of concerns and removes unnecessary complexities. +The backend follows a modular approach, which is a fundamental principle when working with NestJS. Make sure you break down your code into reusable modules to maintain a clean and organized codebase. +Each module should encapsulate a particular feature or functionality and have a well-defined scope. This modular approach enables clear separation of concerns and removes unnecessary complexities. ## Expose services to use in modules -Always create services that have a clear and single responsibility, which enhances code readability and maintainability. Name the services descriptively and consistently. +Always create services that have a clear and single responsibility, which enhances code readability and maintainability. Name the services descriptively and consistently. -You should also expose services that you want to use in other modules. Exposing services to other modules is possible through NestJS's powerful dependency injection system, and promotes loose coupling between components. +You should also expose services that you want to use in other modules. Exposing services to other modules is possible through NestJS's powerful dependency injection system, and promotes loose coupling between components. ## Avoid using `any` type -When you declare a variable as `any`, TypeScript's type checker doesn't perform any type checking, making it possible to assign any type of values to the variable. TypeScript uses type inference to determine the type of variable based on the value. By declaring it as `any`, TypeScript can no longer infer the type. This makes it hard to catch type-related errors during development, leading to runtime errors and makes the code less maintainable, less reliable, and harder to understand for others. +When you declare a variable as `any`, TypeScript's type checker doesn't perform any type checking, making it possible to assign any type of values to the variable. TypeScript uses type inference to determine the type of variable based on the value. By declaring it as `any`, TypeScript can no longer infer the type. This makes it hard to catch type-related errors during development, leading to runtime errors and makes the code less maintainable, less reliable, and harder to understand for others. This is why everything should have a type. So if you create a new object with a first name and last name, you should create an interface or type that contains a first name and last name that defines the shape of the object you are manipulating. diff --git a/packages/twenty-docs/developers/backend-development/custom-objects.mdx b/packages/twenty-docs/developers/contribute/capabilities/backend-development/custom-objects.mdx similarity index 92% rename from packages/twenty-docs/developers/backend-development/custom-objects.mdx rename to packages/twenty-docs/developers/contribute/capabilities/backend-development/custom-objects.mdx index 146e786160..99a2baf4fa 100644 --- a/packages/twenty-docs/developers/backend-development/custom-objects.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/backend-development/custom-objects.mdx @@ -1,19 +1,16 @@ --- title: Custom Objects -image: /images/user-guide/objects/objects.png --- - - Header - + Objects are structures that allow you to store data (records, attributes, and values) specific to an organization. Twenty provides both standard and custom objects. Standard objects are in-built objects with a set of attributes available for all users. Examples of standard objects in Twenty include Company and Person. Standard objects have standard fields that are also available for all Twenty users, like Company.displayName. -Custom objects are objects that you can create to store information that is unique to your organization. They are not built-in; members of your workspace can create and customize custom objects to hold information that standard objects aren't suitable for. +Custom objects are objects that you can create to store information that is unique to your organization. They are not built-in; members of your workspace can create and customize custom objects to hold information that standard objects aren't suitable for. -## High-level schema +## High-level schema
High level schema diff --git a/packages/twenty-docs/developers/backend-development/feature-flags.mdx b/packages/twenty-docs/developers/contribute/capabilities/backend-development/feature-flags.mdx similarity index 88% rename from packages/twenty-docs/developers/backend-development/feature-flags.mdx rename to packages/twenty-docs/developers/contribute/capabilities/backend-development/feature-flags.mdx index c975c73e61..13cc5aec0d 100644 --- a/packages/twenty-docs/developers/backend-development/feature-flags.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/backend-development/feature-flags.mdx @@ -1,10 +1,7 @@ --- title: Feature Flags -image: /images/user-guide/table-views/table.png --- - - Header - + Feature flags are used to hide experimental features. For Twenty, they are set on workspace level and not on a user level. diff --git a/packages/twenty-docs/developers/backend-development/folder-architecture-server.mdx b/packages/twenty-docs/developers/contribute/capabilities/backend-development/folder-architecture-server.mdx similarity index 81% rename from packages/twenty-docs/developers/backend-development/folder-architecture-server.mdx rename to packages/twenty-docs/developers/contribute/capabilities/backend-development/folder-architecture-server.mdx index a07f0070fe..2a1e5a013b 100644 --- a/packages/twenty-docs/developers/backend-development/folder-architecture-server.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/backend-development/folder-architecture-server.mdx @@ -1,18 +1,15 @@ --- title: Folder Architecture info: A detailed look into our server folder architecture -image: /images/user-guide/fields/field.png --- - - Header - + The backend directory structure is as follows: ``` server └───ability - └───constants + └───constants └───core └───database └───decorators @@ -29,19 +26,19 @@ server Defines permissions and includes handlers for each entity. -## Decorators +## Decorators -Defines custom decorators in NestJS for added functionality. +Defines custom decorators in NestJS for added functionality. See [custom decorators](https://docs.nestjs.com/custom-decorators) for more details. ## Filters -Includes exception filters to handle exceptions that might occur in GraphQL endpoints. +Includes exception filters to handle exceptions that might occur in GraphQL endpoints. ## Guards -See [guards](https://docs.nestjs.com/guards) for more details. +See [guards](https://docs.nestjs.com/guards) for more details. ## Health @@ -53,15 +50,15 @@ Defines custom objects and makes available a GraphQL API (graphql/metadata). ## Workspace -Generates and serves custom GraphQL schema based on the metadata. +Generates and serves custom GraphQL schema based on the metadata. -### Workspace Directory Structure +### Workspace Directory Structure ``` workspace └───workspace-schema-builder - └───factories + └───factories └───graphql-types └───database └───interfaces @@ -77,28 +74,28 @@ workspace └───interfaces └───workspace-query-runner └───interfaces - └───utils + └───utils └───workspace-datasource └───workspace-manager └───workspace-migration-runner - └───utils - └───workspace.module.ts - └───workspace.factory.spec.ts - └───workspace.factory.ts + └───utils + └───workspace.module.ts + └───workspace.factory.spec.ts + └───workspace.factory.ts ``` -The root of the workspace directory includes the `workspace.factory.ts`, a file containing the `createGraphQLSchema` function. This function generates workspace-specific schema by using the metadata to tailor a schema for individual workspaces. By separating the schema and resolver construction, we use the `makeExecutableSchema` function, which combines these discrete elements. +The root of the workspace directory includes the `workspace.factory.ts`, a file containing the `createGraphQLSchema` function. This function generates workspace-specific schema by using the metadata to tailor a schema for individual workspaces. By separating the schema and resolver construction, we use the `makeExecutableSchema` function, which combines these discrete elements. This strategy is not just about organization, but also helps with optimization, such as caching generated type definitions to enhance performance and scalability. ### Workspace Schema builder -Generates the GraphQL schema, and includes: +Generates the GraphQL schema, and includes: -#### Factories: +#### Factories: -Specialised constructors to generate GraphQL-related constructs. +Specialised constructors to generate GraphQL-related constructs. - The type.factory translates field metadata into GraphQL types using `TypeMapperService`. - The type-definition.factory creates GraphQL input or output objects derived from `objectMetadata`. @@ -114,17 +111,17 @@ Contains the blueprints for GraphQL entities, and includes both predefined and c Contains the service responsible for associating FieldMetadataType with its appropriate GraphQL scalar or query modifiers. -#### Storage +#### Storage Includes the `TypeDefinitionsStorage` class that contains reusable type definitions, preventing duplication of GraphQL types. -### Workspace Resolver Builder +### Workspace Resolver Builder Creates resolver functions for querying and mutating the GraphQL schema. Each factory in this directory is responsible for producing a distinct resolver type, such as the `FindManyResolverFactory`, designed for adaptable application across various tables. -### Workspace Query Runner +### Workspace Query Runner Runs the generated queries on the database and parses the result. diff --git a/packages/twenty-docs/developers/backend-development/queue.mdx b/packages/twenty-docs/developers/contribute/capabilities/backend-development/queue.mdx similarity index 89% rename from packages/twenty-docs/developers/backend-development/queue.mdx rename to packages/twenty-docs/developers/contribute/capabilities/backend-development/queue.mdx index f67238299d..f41a484966 100644 --- a/packages/twenty-docs/developers/backend-development/queue.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/backend-development/queue.mdx @@ -1,10 +1,7 @@ --- title: Message Queue -image: /images/user-guide/emails/emails_header.png --- - - Header - + Queues facilitate async operations to be performed. They can be used for performing background tasks such as sending a welcome email on register. Each use case will have its own queue class extended from `MessageQueueServiceBase`. diff --git a/packages/twenty-docs/developers/backend-development/server-commands.mdx b/packages/twenty-docs/developers/contribute/capabilities/backend-development/server-commands.mdx similarity index 94% rename from packages/twenty-docs/developers/backend-development/server-commands.mdx rename to packages/twenty-docs/developers/contribute/capabilities/backend-development/server-commands.mdx index ee9b74896b..2513d050bf 100644 --- a/packages/twenty-docs/developers/backend-development/server-commands.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/backend-development/server-commands.mdx @@ -1,10 +1,7 @@ --- title: Backend Commands -image: /images/user-guide/kanban-views/kanban.png --- - - Header - + ## Useful commands diff --git a/packages/twenty-docs/developers/backend-development/zapier.mdx b/packages/twenty-docs/developers/contribute/capabilities/backend-development/zapier.mdx similarity index 84% rename from packages/twenty-docs/developers/backend-development/zapier.mdx rename to packages/twenty-docs/developers/contribute/capabilities/backend-development/zapier.mdx index 50a52eecb3..3aed344673 100644 --- a/packages/twenty-docs/developers/backend-development/zapier.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/backend-development/zapier.mdx @@ -1,10 +1,7 @@ --- title: Zapier App -image: /images/user-guide/integrations/plug.png --- - - Header - + Effortlessly sync Twenty with 3000+ apps using [Zapier](https://zapier.com/). Automate tasks, boost productivity, and supercharge your customer relationships! @@ -12,7 +9,7 @@ Effortlessly sync Twenty with 3000+ apps using [Zapier](https://zapier.com/). Au Zapier is a tool that allows you to automate workflows by connecting the apps that your team uses every day. The fundamental concept of Zapier is automation workflows, called Zaps, and include triggers and actions. -You can learn more about how Zapier works [here](https://zapier.com/how-it-works). +You can learn more about how Zapier works [here](https://zapier.com/how-it-works). ## Setup @@ -26,7 +23,7 @@ yarn ### Step 2: Login with the CLI -Use your Zapier credentials to log in using the CLI: +Use your Zapier credentials to log in using the CLI: ```bash zapier login @@ -67,13 +64,13 @@ yarn watch ```bash yarn validate ``` -### Deploy your Zapier app +### Deploy your Zapier app ```bash yarn deploy ``` ### List all Zapier CLI commands ```bash zapier -``` +``` diff --git a/packages/twenty-docs/developers/contribute/capabilities/bug-and-requests.mdx b/packages/twenty-docs/developers/contribute/capabilities/bug-and-requests.mdx new file mode 100644 index 0000000000..ea077fc82f --- /dev/null +++ b/packages/twenty-docs/developers/contribute/capabilities/bug-and-requests.mdx @@ -0,0 +1,76 @@ +--- +title: Bugs, Requests & Pull Requests +info: Report issues, request features, and contribute code +--- + + +## Reporting Bugs + +To report a bug, please [create an issue on GitHub](https://github.com/twentyhq/twenty/issues/new). + +You can also ask for help on [Discord](https://discord.gg/cx5n4Jzs57). + +## Feature Requests + +If you're not sure if it's a bug, and you feel it's closer to a feature request, then you should probably [open a discussion instead](https://github.com/twentyhq/twenty/discussions/new). + +## Submit a Pull Request + +Contributing code to Twenty starts with a pull request (PR). + +### Before You Start + +1. Check [existing issues](https://github.com/twentyhq/twenty/issues) for related work +2. For new features, open an issue first to discuss +3. Review our [Code of Conduct](https://github.com/twentyhq/twenty/blob/main/CODE_OF_CONDUCT.md) + +### Fork and Clone + +1. Fork the repository on GitHub +2. Clone your fork: +```bash +git clone https://github.com/YOUR_USERNAME/twenty.git +cd twenty +``` + +3. Add upstream remote: +```bash +git remote add upstream https://github.com/twentyhq/twenty.git +``` + +### Create a Branch + +```bash +git checkout -b feature/your-feature-name +``` + +Use descriptive branch names: +- `feature/add-export-button` +- `fix/login-redirect-issue` +- `docs/update-api-guide` + +### Make Your Changes + +1. Write clean, well-documented code +2. Follow existing code style +3. Add tests for new functionality +4. Update documentation if needed + +### Submit Your PR + +1. Push your branch: +```bash +git push origin feature/your-feature-name +``` + +2. Open a PR on GitHub +3. Fill in the PR template +4. Link related issues + +### PR Checklist + +- [ ] Code follows project style guidelines +- [ ] Tests pass locally +- [ ] Documentation is updated +- [ ] PR description explains the changes + diff --git a/packages/twenty-docs/developers/frontend-development/best-practices-front.mdx b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/best-practices-front.mdx similarity index 95% rename from packages/twenty-docs/developers/frontend-development/best-practices-front.mdx rename to packages/twenty-docs/developers/contribute/capabilities/frontend-development/best-practices-front.mdx index b5a02bbb79..5159bc7984 100644 --- a/packages/twenty-docs/developers/frontend-development/best-practices-front.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/best-practices-front.mdx @@ -1,10 +1,7 @@ --- title: Best Practices -image: /images/user-guide/tips/light-bulb.png --- - - Header - + This document outlines the best practices you should follow when working on the frontend. @@ -14,7 +11,7 @@ React and Recoil handle state management in the codebase. ### Use `useRecoilState` to store state -It's good practice to create as many atoms as you need to store your state. +It's good practice to create as many atoms as you need to store your state. @@ -44,7 +41,7 @@ export const MyComponent = () => { ### Do not use `useRef` to store state -Avoid using `useRef` to store state. +Avoid using `useRef` to store state. If you want to store state, you should use `useState` or `useRecoilState`. @@ -83,7 +80,7 @@ If you feel like you need to add a `useEffect` in your root component, you shoul You can apply the same for data fetching logic, with Apollo hooks. ```tsx -// ❌ Bad, will cause re-renders even if data is not changing, +// ❌ Bad, will cause re-renders even if data is not changing, // because useEffect needs to be re-evaluated export const PageComponent = () => { const [data, setData] = useRecoilState(dataState); @@ -106,7 +103,7 @@ export const App = () => ( ``` ```tsx -// ✅ Good, will not cause re-renders if data is not changing, +// ✅ Good, will not cause re-renders if data is not changing, // because useEffect is re-evaluated in another sibling component export const PageComponent = () => { const [data, setData] = useRecoilState(dataState); @@ -151,10 +148,10 @@ They are often not necessary and will make the code harder to read and maintain ## Console.logs -`console.log` statements are valuable during development, offering real-time insights into variable values and code flow. But, leaving them in production code can lead to several issues: +`console.log` statements are valuable during development, offering real-time insights into variable values and code flow. But, leaving them in production code can lead to several issues: 1. **Performance**: Excessive logging can affect the runtime performance, especially on client-side applications. - + 2. **Security**: Logging sensitive data can expose critical information to anyone who inspects the browser's console. 3. **Cleanliness**: Filling up the console with logs can obscure important warnings or errors that developers or tools need to see. @@ -240,7 +237,7 @@ const Form = () => ; Try as much as possible to pass uninstantiated components as props, so children can decide on their own of what props they need to pass. -The most common example for that is icon components: +The most common example for that is icon components: ```tsx const SomeParentComponent = () => ; @@ -264,7 +261,7 @@ For React to understand that the component is a component, you need to use Pasca Prop drilling, in the React context, refers to the practice of passing state variables and their setters through many component layers, even if intermediary components don't use them. While sometimes necessary, excessive prop drilling can lead to: 1. **Decreased Readability**: Tracing where a prop originates or where it's utilized can become convoluted in a deeply nested component structure. - + 2. **Maintenance Challenges**: Changes in one component's prop structure might require adjustments in several components, even if they don't directly use the prop. 3. **Reduced Component Reusability**: A component receiving a lot of props solely for passing them down becomes less general-purpose and harder to reuse in different contexts. diff --git a/packages/twenty-docs/developers/frontend-development/folder-architecture-front.mdx b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/folder-architecture-front.mdx similarity index 96% rename from packages/twenty-docs/developers/frontend-development/folder-architecture-front.mdx rename to packages/twenty-docs/developers/contribute/capabilities/frontend-development/folder-architecture-front.mdx index aa6fd0f0d5..6e433f73ef 100644 --- a/packages/twenty-docs/developers/frontend-development/folder-architecture-front.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/folder-architecture-front.mdx @@ -1,11 +1,8 @@ --- title: Folder Architecture info: A detailed look into our folder architecture -image: /images/user-guide/fields/field.png --- - - Header - + In this guide, you will explore the details of the project directory structure and how it contributes to the organization and maintainability of Twenty. diff --git a/packages/twenty-docs/developers/frontend-development/frontend-commands.mdx b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/frontend-commands.mdx similarity index 80% rename from packages/twenty-docs/developers/frontend-development/frontend-commands.mdx rename to packages/twenty-docs/developers/contribute/capabilities/frontend-development/frontend-commands.mdx index 914f0d32db..26e55a9dd0 100644 --- a/packages/twenty-docs/developers/frontend-development/frontend-commands.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/frontend-commands.mdx @@ -1,10 +1,7 @@ --- title: Frontend Commands -image: /images/user-guide/create-workspace/workspace-cover.png --- - - Header - + ## Useful commands @@ -75,13 +72,13 @@ The project has a clean and simple stack, with minimal boilerplate code. [React Router](https://reactrouter.com/) handles the routing. -To avoid unnecessary [re-renders](/developers/frontend-development/best-practices-front#managing-re-renders) all the routing logic is in a `useEffect` in `PageChangeEffect`. +To avoid unnecessary [re-renders](/developers/contribute/capabilities/frontend-development/best-practices-front#managing-re-renders) all the routing logic is in a `useEffect` in `PageChangeEffect`. ### State Management [Recoil](https://recoiljs.org/docs/introduction/core-concepts) handles state management. -See [best practices](/developers/frontend-development/best-practices-front#state-management) for more information on state management. +See [best practices](/developers/contribute/capabilities/frontend-development/best-practices-front#state-management) for more information on state management. ## Testing diff --git a/packages/twenty-docs/developers/frontend-development/hotkeys.mdx b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/hotkeys.mdx similarity index 95% rename from packages/twenty-docs/developers/frontend-development/hotkeys.mdx rename to packages/twenty-docs/developers/contribute/capabilities/frontend-development/hotkeys.mdx index a395774719..56991048c6 100644 --- a/packages/twenty-docs/developers/frontend-development/hotkeys.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/hotkeys.mdx @@ -1,10 +1,7 @@ --- title: Hotkeys -image: /images/user-guide/table-views/table.png --- - - Header - + ## Introduction @@ -38,7 +35,7 @@ The second use case can happen recursively : a dropdown in a modal for example. ### Listening to hotkeys in a page -Example : +Example : ```tsx const PageListeningEnter = () => { @@ -129,7 +126,7 @@ const MyDropdownComponent = ({ onClose }: { onClose: () => void }) => { }; ``` -It's important to use this pattern when you're not sure that just using a useEffect with mount/unmount will be enough to avoid conflicts. +It's important to use this pattern when you're not sure that just using a useEffect with mount/unmount will be enough to avoid conflicts. Those conflicts can be hard to debug, and it might happen more often than not with useEffects. @@ -162,7 +159,7 @@ export enum PageHotkeyScope { } ``` -Internally, the currently selected scope is stored in a Recoil state that is shared across the application : +Internally, the currently selected scope is stored in a Recoil state that is shared across the application : ```tsx export const currentHotkeyScopeState = createState({ @@ -177,4 +174,4 @@ But this Recoil state should never be handled manually ! We'll see how to use it We made a thin wrapper on top of [react-hotkeys-hook](https://react-hotkeys-hook.vercel.app/docs/intro) that makes it more performant and avoids unnecessary re-renders. -We also create a Recoil state to handle the hotkey scope state and make it available everywhere in the application. \ No newline at end of file +We also create a Recoil state to handle the hotkey scope state and make it available everywhere in the application. diff --git a/packages/twenty-docs/developers/frontend-development/storybook.mdx b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/storybook.mdx similarity index 100% rename from packages/twenty-docs/developers/frontend-development/storybook.mdx rename to packages/twenty-docs/developers/contribute/capabilities/frontend-development/storybook.mdx diff --git a/packages/twenty-docs/developers/frontend-development/style-guide.mdx b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/style-guide.mdx similarity index 96% rename from packages/twenty-docs/developers/frontend-development/style-guide.mdx rename to packages/twenty-docs/developers/contribute/capabilities/frontend-development/style-guide.mdx index 215c8554fa..9fcd36f3e5 100644 --- a/packages/twenty-docs/developers/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -1,14 +1,11 @@ --- title: Style Guide -image: /images/user-guide/notes/notes_header.png --- - - Header - + This document includes the rules to follow when writing code. -The goal here is to have a consistent codebase, which is easy to read and easy to maintain. +The goal here is to have a consistent codebase, which is easy to read and easy to maintain. For this, it's better to be a bit more verbose than to be too concise. @@ -71,11 +68,11 @@ const EmailField: React.FC<{ ``` ```tsx -/* ✅ - Good, a separate type (OwnProps) is explicitly defined for the +/* ✅ - Good, a separate type (OwnProps) is explicitly defined for the * component's props * - This method doesn't automatically include the children prop. If * you want to include it, you have to specify it in OwnProps. - */ + */ type EmailFieldProps = { value: string; }; @@ -100,7 +97,7 @@ const MyComponent = (props: OwnProps) => { ```tsx /* ✅ - Good, Explicitly lists all props * - Enhances readability and maintainability - */ + */ const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => { return ; }; @@ -111,7 +108,7 @@ Rationale: - It helps to prevent tight coupling between components via their props. - Linting tools make it easier to identify misspelled or unused props when you list props explicitly. -## JavaScript +## JavaScript ### Use nullish-coalescing operator `??` @@ -126,7 +123,7 @@ const value = process.env.MY_VALUE ?? 'default'; ### Use optional chaining `?.` ```tsx -// ❌ Bad +// ❌ Bad onClick && onClick(); // ✅ Good @@ -155,7 +152,7 @@ type MyType = { [String literals](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) are the go-to way to handle enum-like values in TypeScript. They are easier to extend with Pick and Omit, and offer a better developer experience, specially with code completion. -You can see why TypeScript recommends avoiding enums [here](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums). +You can see why TypeScript recommends avoiding enums [here](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums). ```tsx // ❌ Bad, utilizes an enum @@ -180,7 +177,7 @@ You should use enums that GraphQL codegen generates. It's also better to use an enum when using an internal library, so the internal library doesn't have to expose a string literal type that is not related to the internal API. -Example: +Example: ```TSX const { @@ -263,7 +260,7 @@ const StyledButton = styled.button` ``` ## Enforcing No-Type Imports -Avoid type imports. To enforce this standard, an ESLint rule checks for and reports any type imports. This helps maintain consistency and readability in the TypeScript code. +Avoid type imports. To enforce this standard, an ESLint rule checks for and reports any type imports. This helps maintain consistency and readability in the TypeScript code. ```tsx // ❌ Bad diff --git a/packages/twenty-docs/developers/frontend-development/work-with-figma.mdx b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/work-with-figma.mdx similarity index 95% rename from packages/twenty-docs/developers/frontend-development/work-with-figma.mdx rename to packages/twenty-docs/developers/contribute/capabilities/frontend-development/work-with-figma.mdx index 670d7b9c51..efe3f79549 100644 --- a/packages/twenty-docs/developers/frontend-development/work-with-figma.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/work-with-figma.mdx @@ -1,11 +1,8 @@ --- title: Work with Figma info: Learn how you can collaborate with Twenty's Figma -image: /images/user-guide/objects/objects.png --- - - Header - + Figma is a collaborative interface design tool that aids in bridging the communication barrier between designers and developers. This guide explains how you can collaborate with Figma. @@ -13,7 +10,7 @@ This guide explains how you can collaborate with Figma. ## Access 1. **Access the shared link:** You can access the project's Figma file [here](https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty). -2. **Sign in:** If you're not already signed in, Figma will prompt you to do so. +2. **Sign in:** If you're not already signed in, Figma will prompt you to do so. Key features are only available to logged-in users, such as the developer mode and the ability to select a dedicated frame. @@ -39,7 +36,7 @@ With read-only access, you can't edit the design, but you can access all feature Figma's Dev Mode enhances developers' productivity by providing easy design navigation, effective asset management, efficient communication tools, toolbox integrations, quick code snippets, and key layer information, bridging the gap between design and development. You can learn more about Dev Mode [here](https://www.figma.com/dev-mode/). -Switch to the "Developer" mode in the right part of the toolbar to see design specs, copy CSS, and access assets. +Switch to the "Developer" mode in the right part of the toolbar to see design specs, copy CSS, and access assets. ### Use the Prototype diff --git a/packages/twenty-docs/developers/local-setup.mdx b/packages/twenty-docs/developers/contribute/capabilities/local-setup.mdx similarity index 96% rename from packages/twenty-docs/developers/local-setup.mdx rename to packages/twenty-docs/developers/contribute/capabilities/local-setup.mdx index 7640f3837d..d68f78fce6 100644 --- a/packages/twenty-docs/developers/local-setup.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/local-setup.mdx @@ -1,12 +1,8 @@ --- title: Local Setup description: "The guide for contributors (or curious developers) who want to run Twenty locally." -image: /images/user-guide/fields/field.png --- - - Header - ## Prerequisites @@ -231,7 +227,7 @@ If you need a Client GUI, we recommend [redis insight](https://redis.io/insight/ ## Step 5: Setup environment variables -Use environment variables or `.env` files to configure your project. More info [here](https://docs.twenty.com/developers/self-hosting/setup) +Use environment variables or `.env` files to configure your project. More info [here](/developers/self-host/capabilities/setup) Copy the `.env.example` files in `/front` and `/server`: ```bash @@ -300,4 +296,4 @@ You can log in using the default demo account: `tim@apple.dev` (password: `tim@a ## Troubleshooting -If you encounter any problem, check [Troubleshooting](https://docs.twenty.com/developers/self-hosting/troubleshooting) for solutions. +If you encounter any problem, check [Troubleshooting](/developers/self-host/capabilities/troubleshooting) for solutions. diff --git a/packages/twenty-docs/developers/contribute/contribute.mdx b/packages/twenty-docs/developers/contribute/contribute.mdx new file mode 100644 index 0000000000..4902d7600d --- /dev/null +++ b/packages/twenty-docs/developers/contribute/contribute.mdx @@ -0,0 +1,31 @@ +--- +title: Contribute +description: Contribute to Twenty's open-source development. +--- + + AI + + +## Overview + +Twenty is open-source and welcomes contributions from the community. Whether you're fixing bugs, adding features, or improving documentation, your contributions help make Twenty better for everyone. + +## Ways to Contribute + +- **Report bugs**: Help identify and document issues +- **Submit features**: Propose and implement new functionality +- **Improve documentation**: Make our docs clearer and more helpful +- **Frontend development**: Work on the React-based UI +- **Backend development**: Contribute to the NestJS server + +## Getting Started + + + + Report issues or request features + + + Contribute to the UI + + + diff --git a/packages/twenty-docs/developers/extend/capabilities/apis.mdx b/packages/twenty-docs/developers/extend/capabilities/apis.mdx new file mode 100644 index 0000000000..e3b9b8e37b --- /dev/null +++ b/packages/twenty-docs/developers/extend/capabilities/apis.mdx @@ -0,0 +1,141 @@ +--- +title: APIs +description: Query and modify your CRM data programmatically using REST or GraphQL. +--- + +import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; + +Twenty was built to be developer-friendly, offering powerful APIs that adapt to your custom data model. We provide four distinct API types to meet different integration needs. + +## Developer-First Approach + +Twenty generates APIs specifically for your data model: +- **No long IDs required**: Use your object and field names directly in endpoints +- **Standard and custom objects treated equally**: Your custom objects get the same API treatment as built-in ones +- **Dedicated endpoints**: Each object and field gets its own API endpoint +- **Custom documentation**: Generated specifically for your workspace's data model + + +Your personalized API documentation is available under **Settings → API & Webhooks** after creating an API key. Since Twenty generates APIs that match your custom data model, the documentation is unique to your workspace. + + +## The Two API Types + +### Core API +Accessed on `/rest/` or `/graphql/` + +Work with your actual **records** (the data): +- Create, read, update, delete People, Companies, Opportunities, etc. +- Query and filter data +- Manage record relationships + +### Metadata API +Accessed on `/rest/metadata/` or `/metadata/` + +Manage your **workspace and data model**: +- Create, modify, or delete objects and fields +- Configure workspace settings +- Define relationships between objects + +## REST vs GraphQL + +Both Core and Metadata APIs are available in REST and GraphQL formats: + +| Format | Available Operations | +|--------|---------------------| +| **REST** | CRUD, batch operations, upserts | +| **GraphQL** | Same + **batch upserts**, relationship queries in one call | + +Choose based on your needs — both formats access the same data. + +## API Endpoints + +| Environment | Base URL | +|-------------|----------| +| **Cloud** | `https://api.twenty.com/` | +| **Self-Hosted** | `https://{your-domain}/` | + +## Authentication + +Every API request requires an API key in the header: + +``` +Authorization: Bearer YOUR_API_KEY +``` + +### Create an API Key + +1. Go to **Settings → APIs & Webhooks** +2. Click **+ Create key** +3. Configure: + - **Name**: Descriptive name for the key + - **Expiration Date**: When the key expires +4. Click **Save** +5. **Copy immediately** — the key is only shown once + + + + +Your API key grants access to sensitive data. Don't share it with untrusted services. If compromised, disable it immediately and generate a new one. + + +### Assign a Role to an API Key + +For better security, assign a specific role to limit access: + +1. Go to **Settings → Roles** +2. Click on the role to assign +3. Open the **Assignment** tab +4. Under **API Keys**, click **+ Assign to API key** +5. Select the API key + +The key will inherit that role's permissions. See [Permissions](/user-guide/permissions-access/capabilities/permissions) for details. + +### Manage API Keys + +**Regenerate**: Settings → APIs & Webhooks → Click key → **Regenerate** + +**Delete**: Settings → APIs & Webhooks → Click key → **Delete** + +## API Playground + +Test your APIs directly in the browser with our built-in playground — available for both **REST** and **GraphQL**. + +### Access the Playground + +1. Go to **Settings → APIs & Webhooks** +2. Create an API key (required) +3. Click on **REST API** or **GraphQL API** to open the playground + +### What You Get + +- **Interactive documentation**: Generated for your specific data model +- **Live testing**: Execute real API calls against your workspace +- **Schema explorer**: Browse available objects, fields, and relationships +- **Request builder**: Construct queries with autocomplete + +The playground reflects your custom objects and fields, so documentation is always accurate for your workspace. + +## Batch Operations + +Both REST and GraphQL support batch operations: +- **Batch size**: Up to 60 records per request +- **Operations**: Create, update, delete multiple records + +**GraphQL-only features:** +- **Batch Upsert**: Create or update in one call +- Use plural object names (e.g., `CreateCompanies` instead of `CreateCompany`) + +## Rate Limits + +API requests are throttled to ensure platform stability: + +| Limit | Value | +|-------|-------| +| **Requests** | 100 calls per minute | +| **Batch size** | 60 records per call | + + +Use batch operations to maximize throughput — process up to 60 records in a single API call instead of making individual requests. + + diff --git a/packages/twenty-docs/developers/extend/capabilities/apps.mdx b/packages/twenty-docs/developers/extend/capabilities/apps.mdx new file mode 100644 index 0000000000..dc11da9f67 --- /dev/null +++ b/packages/twenty-docs/developers/extend/capabilities/apps.mdx @@ -0,0 +1,23 @@ +--- +title: Twenty Apps +description: Build and manage Twenty customizations as code. +--- + + +Apps are currently in alpha testing. The feature is functional but still evolving. + + +## What Are Apps? + +Apps let you build and manage Twenty customizations **as code**. Instead of configuring everything through the UI, you define your data model and serverless functions in code — making it faster to build, maintain, and roll out to multiple workspaces. + +**What you can do today:** +- Define custom objects and fields as code (managed data model) +- Build serverless functions with custom triggers +- Deploy the same app across multiple workspaces + +**Coming soon:** +- Custom UI layouts and components + + +## Getting Started (Coming Soon) diff --git a/packages/twenty-docs/developers/extend/capabilities/webhooks.mdx b/packages/twenty-docs/developers/extend/capabilities/webhooks.mdx new file mode 100644 index 0000000000..d22f95a110 --- /dev/null +++ b/packages/twenty-docs/developers/extend/capabilities/webhooks.mdx @@ -0,0 +1,113 @@ +--- +title: Webhooks +description: Receive real-time notifications when events occur in your CRM. +--- + +import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; + + +Webhooks push data to your systems in real-time when events occur in Twenty — no polling required. Use them to keep external systems in sync, trigger automations, or send alerts. + +## Create a Webhook + +1. Go to **Settings → APIs & Webhooks → Webhooks** +2. Click **+ Create webhook** +3. Enter your webhook URL (must be publicly accessible) +4. Click **Save** + +The webhook activates immediately and starts sending notifications. + + + +### Manage Webhooks + +**Edit**: Click the webhook → Update URL → **Save** + +**Delete**: Click the webhook → **Delete** → Confirm + +## Events + +Twenty sends webhooks for these event types: + +| Event | Example | +|-------|---------| +| **Record Created** | `person.created`, `company.created`, `note.created` | +| **Record Updated** | `person.updated`, `company.updated`, `opportunity.updated` | +| **Record Deleted** | `person.deleted`, `company.deleted` | + +All event types are sent to your webhook URL. Event filtering may be added in future releases. + +## Payload Format + +Each webhook sends an HTTP POST with a JSON body: + +```json +{ + "event": "person.created", + "data": { + "id": "abc12345", + "firstName": "Alice", + "lastName": "Doe", + "email": "alice@example.com", + "createdAt": "2025-02-10T15:30:45Z", + "createdBy": "user_123" + }, + "timestamp": "2025-02-10T15:30:50Z" +} +``` + +| Field | Description | +|-------|-------------| +| `event` | What happened (e.g., `person.created`) | +| `data` | The full record that was created/updated/deleted | +| `timestamp` | When the event occurred (UTC) | + + +Respond with a **2xx HTTP status** (200-299) to acknowledge receipt. Non-2xx responses are logged as delivery failures. + + +## Webhook Validation + +Twenty signs each webhook request for security. Validate signatures to ensure requests are authentic. + +### Headers + +| Header | Description | +|--------|-------------| +| `X-Twenty-Webhook-Signature` | HMAC SHA256 signature | +| `X-Twenty-Webhook-Timestamp` | Request timestamp | + +### Validation Steps + +1. Get the timestamp from `X-Twenty-Webhook-Timestamp` +2. Create the string: `{timestamp}:{JSON payload}` +3. Compute HMAC SHA256 using your webhook secret +4. Compare with `X-Twenty-Webhook-Signature` + +### Example (Node.js) + +```javascript +const crypto = require("crypto"); + +const timestamp = req.headers["x-twenty-webhook-timestamp"]; +const payload = JSON.stringify(req.body); +const secret = "your-webhook-secret"; + +const stringToSign = `${timestamp}:${payload}`; +const expectedSignature = crypto + .createHmac("sha256", secret) + .update(stringToSign) + .digest("hex"); + +const isValid = expectedSignature === req.headers["x-twenty-webhook-signature"]; +``` + +## Webhooks vs Workflows + +| Method | Direction | Use Case | +|--------|-----------|----------| +| **Webhooks** | OUT | Automatically notify external systems of any record change | +| **Workflow + HTTP Request** | OUT | Send data out with custom logic (filters, transformations) | +| **Workflow Webhook Trigger** | IN | Receive data into Twenty from external systems | + +For receiving external data, see [Set Up a Webhook Trigger](/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger). diff --git a/packages/twenty-docs/developers/extend/extend.mdx b/packages/twenty-docs/developers/extend/extend.mdx new file mode 100644 index 0000000000..e0b12f41fa --- /dev/null +++ b/packages/twenty-docs/developers/extend/extend.mdx @@ -0,0 +1,33 @@ +--- +title: Extend +description: Extend Twenty's functionality with APIs, webhooks, and custom apps. +--- + + AI + + +## Overview + +Twenty is designed to be extensible. Use our APIs, webhooks, and app framework to integrate with your existing tools and build custom functionality. + +## What You Can Do + +- **APIs**: Query and modify your CRM data programmatically using REST or GraphQL +- **Webhooks**: Receive real-time notifications when events occur in Twenty +- **Apps**: Build custom applications that extend Twenty's capabilities - Coming soon! + +## Getting Started + + + + Connect to Twenty programmatically + + + Get notified of events in real-time + + + Build customizations as code (Alpha) + + + + diff --git a/packages/twenty-docs/developers/introduction.mdx b/packages/twenty-docs/developers/introduction.mdx index 34927854dc..460a358f1d 100644 --- a/packages/twenty-docs/developers/introduction.mdx +++ b/packages/twenty-docs/developers/introduction.mdx @@ -1,44 +1,23 @@ --- -title: Overview -description: Technical documentation for contributors and developers working with Twenty +title: Getting Started +description: Welcome to Twenty Developer Documentation, your resources for extending, self-hosting, and contributing to Twenty. --- import { CardTitle } from "/snippets/card-title.mdx" -## Getting started - - - - Local Setup - The guide for contributors (or curious developers) who want to run Twenty locally (on laptop, PC...) + + + Extend + Build integrations with APIs, webhooks, and custom apps. - - Self-Hosting - Learn how to host Twenty on your own server + + Self-Host + Deploy and manage Twenty on your own infrastructure. - - API and Webhooks - REST and GraphQL APIs, webhooks, and integrations - - - -## Contributing - - - - Bugs and Requests - Ask for help on GitHub or Discord - - - - Frontend Development - Frontend commands, Figma, React Best Practices... - - - - Backend Development - NestJS, Custom Objects, Queues... + + Contribute + Join our open-source community and contribute to Twenty. diff --git a/packages/twenty-docs/developers/self-hosting/cloud-providers.mdx b/packages/twenty-docs/developers/self-host/capabilities/cloud-providers.mdx similarity index 90% rename from packages/twenty-docs/developers/self-hosting/cloud-providers.mdx rename to packages/twenty-docs/developers/self-host/capabilities/cloud-providers.mdx index b155803380..a5c14cb380 100644 --- a/packages/twenty-docs/developers/self-hosting/cloud-providers.mdx +++ b/packages/twenty-docs/developers/self-host/capabilities/cloud-providers.mdx @@ -1,10 +1,6 @@ --- title: Other methods -image: /images/user-guide/notes/notes_header.png --- - - Header - This document is maintained by the community. It might contain issues. diff --git a/packages/twenty-docs/developers/self-hosting/docker-compose.mdx b/packages/twenty-docs/developers/self-host/capabilities/docker-compose.mdx similarity index 80% rename from packages/twenty-docs/developers/self-hosting/docker-compose.mdx rename to packages/twenty-docs/developers/self-host/capabilities/docker-compose.mdx index 69e8eaa40e..3cd7bb1381 100644 --- a/packages/twenty-docs/developers/self-hosting/docker-compose.mdx +++ b/packages/twenty-docs/developers/self-host/capabilities/docker-compose.mdx @@ -1,13 +1,10 @@ --- title: 1-Click w/ Docker Compose -image: /images/user-guide/objects/objects.png --- - - Header - + -Docker containers are for production hosting or self-hosting, for the contribution please check the [Local Setup](https://docs.twenty.com/developers/local-setup). +Docker containers are for production hosting or self-hosting, for the contribution please check the [Local Setup](/developers/contribute/capabilities/local-setup). ## Overview @@ -16,7 +13,7 @@ This guide provides step-by-step instructions to install and configure the Twent **Important:** Only modify settings explicitly mentioned in this guide. Altering other configurations may lead to issues. -See docs [Setup Environment Variables](https://docs.twenty.com/developers/self-hosting/setup) for advanced configuration. All environment variables must be declared in the docker-compose.yml file at the server and / or worker level depending on the variable. +See docs [Setup Environment Variables](/developers/self-host/capabilities/setup) for advanced configuration. All environment variables must be declared in the docker-compose.yml file at the server and / or worker level depending on the variable. ## System Requirements @@ -194,8 +191,50 @@ We strongly recommend setting up Twenty behind a reverse proxy with SSL terminat If deploying to a stateless environment (e.g., certain cloud services), configure external storage to persist data. +## Backup and Restore + +Regular backups protect your CRM data from loss. + +### Create a Database Backup + +```bash +docker exec twenty-postgres pg_dump -U postgres twenty > backup_$(date +%Y%m%d).sql +``` + +### Automate Daily Backups + +Add to your crontab (`crontab -e`): + +```bash +0 2 * * * docker exec twenty-postgres pg_dump -U postgres twenty > /backups/twenty_$(date +\%Y\%m\%d).sql +``` + +### Restore from Backup + +1. Stop the application: +```bash +docker compose stop twenty-server twenty-front +``` + +2. Restore the database: +```bash +docker exec -i twenty-postgres psql -U postgres twenty < backup_20240115.sql +``` + +3. Restart services: +```bash +docker compose up -d +``` + +### Backup Best Practices + +- **Test restores regularly** — verify backups actually work +- **Store backups off-site** — use cloud storage (S3, GCS, etc.) +- **Encrypt sensitive data** — protect backups with encryption +- **Retain multiple copies** — keep daily, weekly, and monthly backups + ## Troubleshooting -If you encounter any problem, check [Troubleshooting](https://docs.twenty.com/developers/self-hosting/troubleshooting) for solutions. +If you encounter any problem, check [Troubleshooting](/developers/self-host/capabilities/troubleshooting) for solutions. diff --git a/packages/twenty-docs/developers/self-hosting/setup.mdx b/packages/twenty-docs/developers/self-host/capabilities/setup.mdx similarity index 97% rename from packages/twenty-docs/developers/self-hosting/setup.mdx rename to packages/twenty-docs/developers/self-host/capabilities/setup.mdx index 4d534c4348..e5a01ad515 100644 --- a/packages/twenty-docs/developers/self-hosting/setup.mdx +++ b/packages/twenty-docs/developers/self-host/capabilities/setup.mdx @@ -1,17 +1,13 @@ --- title: Setup -image: /images/user-guide/table-views/table.png --- - - Header - import OptionTable from '@site/src/theme/OptionTable' # Configuration Management -**First time installing?** Follow the [Docker Compose installation guide](https://docs.twenty.com/developers/self-hosting/docker-compose) to get Twenty running, then return here for configuration. +**First time installing?** Follow the [Docker Compose installation guide](/developers/self-host/capabilities/docker-compose) to get Twenty running, then return here for configuration. Twenty offers **two configuration modes** to suit different deployment needs: diff --git a/packages/twenty-docs/developers/self-hosting/troubleshooting.mdx b/packages/twenty-docs/developers/self-host/capabilities/troubleshooting.mdx similarity index 94% rename from packages/twenty-docs/developers/self-hosting/troubleshooting.mdx rename to packages/twenty-docs/developers/self-host/capabilities/troubleshooting.mdx index ea763fde3a..fff725daa7 100644 --- a/packages/twenty-docs/developers/self-hosting/troubleshooting.mdx +++ b/packages/twenty-docs/developers/self-host/capabilities/troubleshooting.mdx @@ -1,10 +1,7 @@ --- title: Troubleshooting -image: /images/user-guide/what-is-twenty/20.png --- - - Header - + ## Troubleshooting @@ -71,25 +68,25 @@ This should work out of the box with the eslint extension installed. If this doe In `packages/twenty-front/.env` uncomment `VITE_DISABLE_TYPESCRIPT_CHECKER=true` to disable background checks thus reducing amount of needed RAM. -**If it does not work:** +**If it does not work:** Run only the services you need, instead of `npx nx start`. For instance, if you work on the server, run only `npx nx worker twenty-server` -**If it does not work:** +**If it does not work:** If you tried to run only `npx nx run twenty-server:start` on WSL and it's failing with the below memory error: `FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory` Workaround is to execute below command in terminal or add it in .bashrc profile to get setup automatically: -`export NODE_OPTIONS="--max-old-space-size=8192"` +`export NODE_OPTIONS="--max-old-space-size=8192"` The --max-old-space-size=8192 flag sets an upper limit of 8GB for the Node.js heap; usage scales with application demand. Reference: https://stackoverflow.com/questions/56982005/where-do-i-set-node-options-max-old-space-size-2048 -**If it does not work:** -Investigate which processes are taking you most of your machine RAM. At Twenty, we noticed that some VScode extensions were taking a lot of RAM so we temporarily disable them. +**If it does not work:** +Investigate which processes are taking you most of your machine RAM. At Twenty, we noticed that some VScode extensions were taking a lot of RAM so we temporarily disable them. -**If it does not work:** +**If it does not work:** Restart your machine helps to clean up ghost processes. #### While running `npx nx start` there are weird [0] and [1] in logs @@ -97,16 +94,16 @@ Restart your machine helps to clean up ghost processes. That's expected as command `npx nx start` is running more commands under the hood #### No emails are sent -Most of the time, it's because the `worker` is not running in the background. Try to run +Most of the time, it's because the `worker` is not running in the background. Try to run ``` npx nx worker twenty-server ``` #### Cannot connect my Microsoft 365 account -Most of the time, it's because your admin has not enabled the Microsoft 365 Licence for your account. Check [https://admin.microsoft.com/](https://admin.microsoft.com/Adminportal/Home). +Most of the time, it's because your admin has not enabled the Microsoft 365 Licence for your account. Check [https://admin.microsoft.com/](https://admin.microsoft.com/Adminportal/Home). -If you have an error code `AADSTS50020`, it probably means that you are using a personal Microsoft account. This is not supported yet. More info [here](https://learn.microsoft.com/fr-fr/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50020-user-account-identity-provider-does-not-exist) +If you have an error code `AADSTS50020`, it probably means that you are using a personal Microsoft account. This is not supported yet. More info [here](https://learn.microsoft.com/fr-fr/troubleshoot/entra/entra-id/app-integration/error-code-aadsts50020-user-account-identity-provider-does-not-exist) #### While running `yarn` warnings appear in console @@ -181,7 +178,7 @@ If you can't log in after setup: docker compose up -d ``` -Note the database:reset command will completely erase your database and recreate it from scratch. +Note the database:reset command will completely erase your database and recreate it from scratch. #### Connection Issues Behind a Reverse Proxy diff --git a/packages/twenty-docs/developers/self-hosting/upgrade-guide.mdx b/packages/twenty-docs/developers/self-host/capabilities/upgrade-guide.mdx similarity index 98% rename from packages/twenty-docs/developers/self-hosting/upgrade-guide.mdx rename to packages/twenty-docs/developers/self-host/capabilities/upgrade-guide.mdx index 7beccc9fc3..796d583043 100644 --- a/packages/twenty-docs/developers/self-hosting/upgrade-guide.mdx +++ b/packages/twenty-docs/developers/self-host/capabilities/upgrade-guide.mdx @@ -1,10 +1,6 @@ --- title: Upgrade guide -image: /images/user-guide/notes/notes_header.png --- - - Header - ## General guidelines diff --git a/packages/twenty-docs/developers/self-host/self-host.mdx b/packages/twenty-docs/developers/self-host/self-host.mdx new file mode 100644 index 0000000000..a9357b81b7 --- /dev/null +++ b/packages/twenty-docs/developers/self-host/self-host.mdx @@ -0,0 +1,28 @@ +--- +title: Self-Host +description: Deploy and manage Twenty on your own infrastructure. +--- + + AI + +## Overview + +Twenty can be self-hosted on your own infrastructure, giving you full control over your data and deployment. + +## Why Self-Host? + +- **Data ownership**: Keep all CRM data on your own servers +- **Compliance**: Meet regulatory requirements for data residency +- **Customization**: Full access to modify and extend the platform + +## Getting Started + + + + Quick setup with Docker + + + Deploy on AWS, GCP, or Azure + + + diff --git a/packages/twenty-docs/docs.json b/packages/twenty-docs/docs.json index 0d3d7af971..035515443c 100644 --- a/packages/twenty-docs/docs.json +++ b/packages/twenty-docs/docs.json @@ -40,7 +40,7 @@ "user-guide/introduction", "user-guide/getting-started/what-is-twenty", "user-guide/getting-started/create-workspace", - "user-guide/getting-started/getting-around-twenty", + "user-guide/getting-started/navigate-around-twenty", "user-guide/getting-started/configure-your-workspace", "user-guide/getting-started/implementation-services", "user-guide/getting-started/migrating-from-other-crms", @@ -276,7 +276,7 @@ "l/fr/user-guide/introduction", "l/fr/user-guide/getting-started/what-is-twenty", "l/fr/user-guide/getting-started/create-workspace", - "l/fr/user-guide/getting-started/getting-around-twenty", + "l/fr/user-guide/getting-started/navigate-around-twenty", "l/fr/user-guide/getting-started/configure-your-workspace", "l/fr/user-guide/getting-started/implementation-services", "l/fr/user-guide/getting-started/migrating-from-other-crms", @@ -512,7 +512,7 @@ "l/ar/user-guide/introduction", "l/ar/user-guide/getting-started/what-is-twenty", "l/ar/user-guide/getting-started/create-workspace", - "l/ar/user-guide/getting-started/getting-around-twenty", + "l/ar/user-guide/getting-started/navigate-around-twenty", "l/ar/user-guide/getting-started/configure-your-workspace", "l/ar/user-guide/getting-started/implementation-services", "l/ar/user-guide/getting-started/migrating-from-other-crms", @@ -748,7 +748,7 @@ "l/cs/user-guide/introduction", "l/cs/user-guide/getting-started/what-is-twenty", "l/cs/user-guide/getting-started/create-workspace", - "l/cs/user-guide/getting-started/getting-around-twenty", + "l/cs/user-guide/getting-started/navigate-around-twenty", "l/cs/user-guide/getting-started/configure-your-workspace", "l/cs/user-guide/getting-started/implementation-services", "l/cs/user-guide/getting-started/migrating-from-other-crms", @@ -984,7 +984,7 @@ "l/de/user-guide/introduction", "l/de/user-guide/getting-started/what-is-twenty", "l/de/user-guide/getting-started/create-workspace", - "l/de/user-guide/getting-started/getting-around-twenty", + "l/de/user-guide/getting-started/navigate-around-twenty", "l/de/user-guide/getting-started/configure-your-workspace", "l/de/user-guide/getting-started/implementation-services", "l/de/user-guide/getting-started/migrating-from-other-crms", @@ -1220,7 +1220,7 @@ "l/es/user-guide/introduction", "l/es/user-guide/getting-started/what-is-twenty", "l/es/user-guide/getting-started/create-workspace", - "l/es/user-guide/getting-started/getting-around-twenty", + "l/es/user-guide/getting-started/navigate-around-twenty", "l/es/user-guide/getting-started/configure-your-workspace", "l/es/user-guide/getting-started/implementation-services", "l/es/user-guide/getting-started/migrating-from-other-crms", @@ -1456,7 +1456,7 @@ "l/it/user-guide/introduction", "l/it/user-guide/getting-started/what-is-twenty", "l/it/user-guide/getting-started/create-workspace", - "l/it/user-guide/getting-started/getting-around-twenty", + "l/it/user-guide/getting-started/navigate-around-twenty", "l/it/user-guide/getting-started/configure-your-workspace", "l/it/user-guide/getting-started/implementation-services", "l/it/user-guide/getting-started/migrating-from-other-crms", @@ -1692,7 +1692,7 @@ "l/ja/user-guide/introduction", "l/ja/user-guide/getting-started/what-is-twenty", "l/ja/user-guide/getting-started/create-workspace", - "l/ja/user-guide/getting-started/getting-around-twenty", + "l/ja/user-guide/getting-started/navigate-around-twenty", "l/ja/user-guide/getting-started/configure-your-workspace", "l/ja/user-guide/getting-started/implementation-services", "l/ja/user-guide/getting-started/migrating-from-other-crms", @@ -1928,7 +1928,7 @@ "l/ko/user-guide/introduction", "l/ko/user-guide/getting-started/what-is-twenty", "l/ko/user-guide/getting-started/create-workspace", - "l/ko/user-guide/getting-started/getting-around-twenty", + "l/ko/user-guide/getting-started/navigate-around-twenty", "l/ko/user-guide/getting-started/configure-your-workspace", "l/ko/user-guide/getting-started/implementation-services", "l/ko/user-guide/getting-started/migrating-from-other-crms", @@ -2164,7 +2164,7 @@ "l/pt/user-guide/introduction", "l/pt/user-guide/getting-started/what-is-twenty", "l/pt/user-guide/getting-started/create-workspace", - "l/pt/user-guide/getting-started/getting-around-twenty", + "l/pt/user-guide/getting-started/navigate-around-twenty", "l/pt/user-guide/getting-started/configure-your-workspace", "l/pt/user-guide/getting-started/implementation-services", "l/pt/user-guide/getting-started/migrating-from-other-crms", @@ -2400,7 +2400,7 @@ "l/ro/user-guide/introduction", "l/ro/user-guide/getting-started/what-is-twenty", "l/ro/user-guide/getting-started/create-workspace", - "l/ro/user-guide/getting-started/getting-around-twenty", + "l/ro/user-guide/getting-started/navigate-around-twenty", "l/ro/user-guide/getting-started/configure-your-workspace", "l/ro/user-guide/getting-started/implementation-services", "l/ro/user-guide/getting-started/migrating-from-other-crms", @@ -2636,7 +2636,7 @@ "l/ru/user-guide/introduction", "l/ru/user-guide/getting-started/what-is-twenty", "l/ru/user-guide/getting-started/create-workspace", - "l/ru/user-guide/getting-started/getting-around-twenty", + "l/ru/user-guide/getting-started/navigate-around-twenty", "l/ru/user-guide/getting-started/configure-your-workspace", "l/ru/user-guide/getting-started/implementation-services", "l/ru/user-guide/getting-started/migrating-from-other-crms", @@ -2872,7 +2872,7 @@ "l/tr/user-guide/introduction", "l/tr/user-guide/getting-started/what-is-twenty", "l/tr/user-guide/getting-started/create-workspace", - "l/tr/user-guide/getting-started/getting-around-twenty", + "l/tr/user-guide/getting-started/navigate-around-twenty", "l/tr/user-guide/getting-started/configure-your-workspace", "l/tr/user-guide/getting-started/implementation-services", "l/tr/user-guide/getting-started/migrating-from-other-crms", @@ -3108,7 +3108,7 @@ "l/zh/user-guide/introduction", "l/zh/user-guide/getting-started/what-is-twenty", "l/zh/user-guide/getting-started/create-workspace", - "l/zh/user-guide/getting-started/getting-around-twenty", + "l/zh/user-guide/getting-started/navigate-around-twenty", "l/zh/user-guide/getting-started/configure-your-workspace", "l/zh/user-guide/getting-started/implementation-services", "l/zh/user-guide/getting-started/migrating-from-other-crms", @@ -3339,5 +3339,487 @@ "twitter": "https://twitter.com/twentycrm", "discord": "https://discord.gg/cx5n4Jzs57" } - } + }, + "redirects": [ + { + "source": "/developers/local-setup", + "destination": "/developers/contribute/capabilities/local-setup" + }, + { + "source": "/developers/self-hosting", + "destination": "/developers/self-host/self-host" + }, + { + "source": "/developers/self-hosting/docker-compose", + "destination": "/developers/self-host/capabilities/docker-compose" + }, + { + "source": "/developers/self-hosting/setup", + "destination": "/developers/self-host/capabilities/setup" + }, + { + "source": "/developers/self-hosting/upgrade-guide", + "destination": "/developers/self-host/capabilities/upgrade-guide" + }, + { + "source": "/developers/self-hosting/cloud-providers", + "destination": "/developers/self-host/capabilities/cloud-providers" + }, + { + "source": "/developers/self-hosting/troubleshooting", + "destination": "/developers/self-host/capabilities/troubleshooting" + }, + { + "source": "/developers/api-and-webhooks", + "destination": "/developers/extend/extend" + }, + { + "source": "/developers/api-and-webhooks/apis-overview", + "destination": "/developers/extend/capabilities/apis" + }, + { + "source": "/developers/api-and-webhooks/api", + "destination": "/developers/extend/capabilities/apis" + }, + { + "source": "/developers/api-and-webhooks/api-keys", + "destination": "/developers/extend/capabilities/apis" + }, + { + "source": "/developers/api-and-webhooks/webhooks", + "destination": "/developers/extend/capabilities/webhooks" + }, + { + "source": "/developers/api-and-webhooks/integrations", + "destination": "/developers/extend/capabilities/apis" + }, + { + "source": "/developers/bugs-and-requests", + "destination": "/developers/contribute/capabilities/bug-and-requests" + }, + { + "source": "/developers/frontend-development", + "destination": "/developers/contribute/contribute" + }, + { + "source": "/developers/frontend-development/frontend-commands", + "destination": "/developers/contribute/capabilities/frontend-development/frontend-commands" + }, + { + "source": "/developers/frontend-development/best-practices-front", + "destination": "/developers/contribute/capabilities/frontend-development/best-practices-front" + }, + { + "source": "/developers/frontend-development/folder-architecture-front", + "destination": "/developers/contribute/capabilities/frontend-development/folder-architecture-front" + }, + { + "source": "/developers/frontend-development/hotkeys", + "destination": "/developers/contribute/capabilities/frontend-development/hotkeys" + }, + { + "source": "/developers/frontend-development/storybook", + "destination": "/developers/contribute/capabilities/frontend-development/storybook" + }, + { + "source": "/developers/frontend-development/style-guide", + "destination": "/developers/contribute/capabilities/frontend-development/style-guide" + }, + { + "source": "/developers/frontend-development/work-with-figma", + "destination": "/developers/contribute/capabilities/frontend-development/work-with-figma" + }, + { + "source": "/developers/backend-development", + "destination": "/developers/contribute/contribute" + }, + { + "source": "/developers/backend-development/server-commands", + "destination": "/developers/contribute/capabilities/backend-development/server-commands" + }, + { + "source": "/developers/backend-development/best-practices-server", + "destination": "/developers/contribute/capabilities/backend-development/best-practices-server" + }, + { + "source": "/developers/backend-development/custom-objects", + "destination": "/developers/contribute/capabilities/backend-development/custom-objects" + }, + { + "source": "/developers/backend-development/feature-flags", + "destination": "/developers/contribute/capabilities/backend-development/feature-flags" + }, + { + "source": "/developers/backend-development/folder-architecture-server", + "destination": "/developers/contribute/capabilities/backend-development/folder-architecture-server" + }, + { + "source": "/developers/backend-development/queue", + "destination": "/developers/contribute/capabilities/backend-development/queue" + }, + { + "source": "/developers/backend-development/zapier", + "destination": "/developers/contribute/capabilities/backend-development/zapier" + }, + { + "source": "/user-guide/getting-started/what-is-twenty", + "destination": "/user-guide/getting-started/capabilities/what-is-twenty" + }, + { + "source": "/user-guide/getting-started/implementation-services", + "destination": "/user-guide/getting-started/capabilities/implementation-services" + }, + { + "source": "/user-guide/getting-started/glossary", + "destination": "/user-guide/getting-started/capabilities/glossary" + }, + { + "source": "/user-guide/getting-started/create-workspace", + "destination": "/user-guide/getting-started/how-tos/create-workspace" + }, + { + "source": "/user-guide/getting-started/navigate-around-twenty", + "destination": "/user-guide/getting-started/how-tos/navigate-around-twenty" + }, + { + "source": "/user-guide/getting-started/configure-your-workspace", + "destination": "/user-guide/getting-started/how-tos/configure-your-workspace" + }, + { + "source": "/user-guide/data-model/objects", + "destination": "/user-guide/data-model/capabilities/objects" + }, + { + "source": "/user-guide/data-model/fields", + "destination": "/user-guide/data-model/capabilities/fields" + }, + { + "source": "/user-guide/data-model/relation-fields", + "destination": "/user-guide/data-model/capabilities/relation-fields" + }, + { + "source": "/user-guide/data-model/create-custom-objects", + "destination": "/user-guide/data-model/how-tos/create-custom-objects" + }, + { + "source": "/user-guide/data-model/create-custom-fields", + "destination": "/user-guide/data-model/how-tos/create-custom-fields" + }, + { + "source": "/user-guide/data-model/create-relation-fields", + "destination": "/user-guide/data-model/how-tos/create-relation-fields" + }, + { + "source": "/user-guide/data-model/customize-your-data-model", + "destination": "/user-guide/data-model/how-tos/customize-your-data-model" + }, + { + "source": "/user-guide/data-model/data-model-faq", + "destination": "/user-guide/data-model/how-tos/data-model-faq" + }, + { + "source": "/user-guide/data-migration/file-formats", + "destination": "/user-guide/data-migration/capabilities/file-formats" + }, + { + "source": "/user-guide/data-migration/field-mapping", + "destination": "/user-guide/data-migration/capabilities/field-mapping" + }, + { + "source": "/user-guide/data-migration/uniqueness-constraints", + "destination": "/user-guide/data-migration/capabilities/uniqueness-constraints" + }, + { + "source": "/user-guide/data-migration/import-relations", + "destination": "/user-guide/data-migration/capabilities/import-relations" + }, + { + "source": "/user-guide/data-migration/error-handling", + "destination": "/user-guide/data-migration/capabilities/error-handling" + }, + { + "source": "/user-guide/data-migration/prepare-your-csv-files", + "destination": "/user-guide/data-migration/how-tos/prepare-your-csv-files" + }, + { + "source": "/user-guide/data-migration/import-companies-via-csv", + "destination": "/user-guide/data-migration/how-tos/import-companies-via-csv" + }, + { + "source": "/user-guide/data-migration/import-contacts-via-csv", + "destination": "/user-guide/data-migration/how-tos/import-contacts-via-csv" + }, + { + "source": "/user-guide/data-migration/import-relations-between-objects-via-csv", + "destination": "/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv" + }, + { + "source": "/user-guide/data-migration/update-existing-records-via-import", + "destination": "/user-guide/data-migration/how-tos/update-existing-records-via-import" + }, + { + "source": "/user-guide/data-migration/fix-import-errors", + "destination": "/user-guide/data-migration/how-tos/fix-import-errors" + }, + { + "source": "/user-guide/data-migration/export-your-data", + "destination": "/user-guide/data-migration/how-tos/export-your-data" + }, + { + "source": "/user-guide/data-migration/import-data-via-api", + "destination": "/user-guide/data-migration/how-tos/import-data-via-api" + }, + { + "source": "/user-guide/data-migration/migrating-from-other-crms", + "destination": "/user-guide/data-migration/how-tos/migrating-from-other-crms" + }, + { + "source": "/user-guide/data-migration/migrating-from-self-hosted-to-cloud", + "destination": "/user-guide/data-migration/how-tos/migrating-from-self-hosted-to-cloud" + }, + { + "source": "/user-guide/calendar-emails/mailbox", + "destination": "/user-guide/calendar-emails/capabilities/mailbox" + }, + { + "source": "/user-guide/calendar-emails/calendar", + "destination": "/user-guide/calendar-emails/capabilities/calendar" + }, + { + "source": "/user-guide/calendar-emails/connect-several-mailboxes-per-user", + "destination": "/user-guide/calendar-emails/how-tos/connect-several-mailboxes-per-user" + }, + { + "source": "/user-guide/calendar-emails/limit-emails-imported", + "destination": "/user-guide/calendar-emails/how-tos/limit-emails-imported" + }, + { + "source": "/user-guide/calendar-emails/can-i-track-email-activity-on-all-objects", + "destination": "/user-guide/calendar-emails/how-tos/can-i-track-email-activity-on-all-objects" + }, + { + "source": "/user-guide/calendar-emails/can-i-send-emails-from-twenty", + "destination": "/user-guide/calendar-emails/how-tos/can-i-send-emails-from-twenty" + }, + { + "source": "/user-guide/calendar-emails/can-i-book-meetings-from-twenty", + "destination": "/user-guide/calendar-emails/how-tos/can-i-book-meetings-from-twenty" + }, + { + "source": "/user-guide/calendar-emails/i-dont-see-emails-on-records", + "destination": "/user-guide/calendar-emails/how-tos/i-dont-see-emails-on-records" + }, + { + "source": "/user-guide/workflows/workflow-triggers", + "destination": "/user-guide/workflows/capabilities/workflow-triggers" + }, + { + "source": "/user-guide/workflows/workflow-actions", + "destination": "/user-guide/workflows/capabilities/workflow-actions" + }, + { + "source": "/user-guide/workflows/workflow-branches", + "destination": "/user-guide/workflows/capabilities/workflow-branches" + }, + { + "source": "/user-guide/workflows/workflow-runs", + "destination": "/user-guide/workflows/capabilities/workflow-runs" + }, + { + "source": "/user-guide/workflows/workflow-versions", + "destination": "/user-guide/workflows/capabilities/workflow-versions" + }, + { + "source": "/user-guide/workflows/workflow-credits", + "destination": "/user-guide/workflows/capabilities/workflow-credits" + }, + { + "source": "/user-guide/workflows/use-branches-in-workflows", + "destination": "/user-guide/workflows/capabilities/use-branches-in-workflows" + }, + { + "source": "/user-guide/workflows/use-iterator", + "destination": "/user-guide/workflows/capabilities/use-iterator" + }, + { + "source": "/user-guide/workflows/send-emails-from-workflows", + "destination": "/user-guide/workflows/capabilities/send-emails-from-workflows" + }, + { + "source": "/user-guide/workflows/workflow-troubleshooting", + "destination": "/user-guide/workflows/how-tos/need-more-help/workflow-troubleshooting" + }, + { + "source": "/user-guide/workflows/workflows-faq", + "destination": "/user-guide/workflows/how-tos/need-more-help/workflows-faq" + }, + { + "source": "/user-guide/workflows/professional-services", + "destination": "/user-guide/workflows/how-tos/need-more-help/professional-services" + }, + { + "source": "/user-guide/ai/ai-chatbot", + "destination": "/user-guide/ai/capabilities/ai-chatbot" + }, + { + "source": "/user-guide/ai/ai-agents", + "destination": "/user-guide/ai/capabilities/ai-agents" + }, + { + "source": "/user-guide/ai/permissions-access-control", + "destination": "/user-guide/ai/capabilities/permissions-access-control" + }, + { + "source": "/user-guide/ai/ai-faq", + "destination": "/user-guide/ai/how-tos/ai-faq" + }, + { + "source": "/user-guide/views-pipelines/table-views", + "destination": "/user-guide/views-pipelines/capabilities/table-views" + }, + { + "source": "/user-guide/views-pipelines/kanban-views", + "destination": "/user-guide/views-pipelines/capabilities/kanban-views" + }, + { + "source": "/user-guide/views-pipelines/calendar-view", + "destination": "/user-guide/views-pipelines/capabilities/calendar-view" + }, + { + "source": "/user-guide/views-pipelines/filters-and-sorting", + "destination": "/user-guide/views-pipelines/capabilities/filters-and-sorting" + }, + { + "source": "/user-guide/views-pipelines/fields-and-columns", + "destination": "/user-guide/views-pipelines/capabilities/fields-and-columns" + }, + { + "source": "/user-guide/views-pipelines/view-settings", + "destination": "/user-guide/views-pipelines/capabilities/view-settings" + }, + { + "source": "/user-guide/views-pipelines/create-a-table-view-with-grouping", + "destination": "/user-guide/views-pipelines/how-tos/create-a-table-view-with-grouping" + }, + { + "source": "/user-guide/views-pipelines/create-a-kanban-view-for-projects", + "destination": "/user-guide/views-pipelines/how-tos/create-a-kanban-view-for-projects" + }, + { + "source": "/user-guide/views-pipelines/create-a-calendar-view-for-tasks-due", + "destination": "/user-guide/views-pipelines/how-tos/create-a-calendar-view-for-tasks-due" + }, + { + "source": "/user-guide/views-pipelines/restrict-access-to-your-view", + "destination": "/user-guide/views-pipelines/how-tos/restrict-access-to-your-view" + }, + { + "source": "/user-guide/views-pipelines/set-up-a-sales-pipeline", + "destination": "/user-guide/views-pipelines/how-tos/set-up-a-sales-pipeline" + }, + { + "source": "/user-guide/views-pipelines/show-expected-amount-in-pipeline", + "destination": "/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline" + }, + { + "source": "/user-guide/views-pipelines/track-time-in-stage", + "destination": "/user-guide/views-pipelines/how-tos/track-time-in-stage" + }, + { + "source": "/user-guide/dashboards/dashboards", + "destination": "/user-guide/dashboards/capabilities/dashboards" + }, + { + "source": "/user-guide/dashboards/widgets", + "destination": "/user-guide/dashboards/capabilities/widgets" + }, + { + "source": "/user-guide/dashboards/dashboards-faq", + "destination": "/user-guide/dashboards/how-tos/dashboards-faq" + }, + { + "source": "/user-guide/permissions-access/permissions", + "destination": "/user-guide/permissions-access/capabilities/permissions" + }, + { + "source": "/user-guide/permissions-access/sso-configuration", + "destination": "/user-guide/permissions-access/capabilities/sso-configuration" + }, + { + "source": "/user-guide/permissions-access/permissions-faq", + "destination": "/user-guide/permissions-access/how-tos/permissions-faq" + }, + { + "source": "/user-guide/billing/pricing-plans", + "destination": "/user-guide/billing/capabilities/pricing-plans" + }, + { + "source": "/user-guide/billing/workflow-credits", + "destination": "/user-guide/billing/capabilities/workflow-credits" + }, + { + "source": "/user-guide/billing/billing-faq", + "destination": "/user-guide/billing/how-tos/billing-faq" + }, + { + "source": "/user-guide/settings/workspace-settings", + "destination": "/user-guide/settings/capabilities/workspace-settings" + }, + { + "source": "/user-guide/settings/member-management", + "destination": "/user-guide/settings/capabilities/member-management" + }, + { + "source": "/user-guide/settings/profile-settings", + "destination": "/user-guide/settings/capabilities/profile-settings" + }, + { + "source": "/user-guide/settings/experience-settings", + "destination": "/user-guide/settings/capabilities/experience-settings" + }, + { + "source": "/user-guide/settings/domains-settings", + "destination": "/user-guide/settings/capabilities/domains-settings" + }, + { + "source": "/user-guide/settings/releases-settings", + "destination": "/user-guide/settings/capabilities/releases-settings" + }, + { + "source": "/user-guide/settings/settings-faq", + "destination": "/user-guide/settings/how-tos/settings-faq" + }, + { + "source": "/user-guide/workflows/how-tos/send-emails-from-workflows", + "destination": "/user-guide/workflows/capabilities/send-emails-from-workflows" + }, + { + "source": "/user-guide/calendar-emails/capabilities/emails-and-calendars", + "destination": "/user-guide/calendar-emails/capabilities/mailbox" + }, + { + "source": "/user-guide/workflows/how-tos/crm-automations/update-companies-and-create-tasks-when-deal-closed", + "destination": "/user-guide/workflows/how-tos/crm-automations/closed-won-automations" + }, + { + "source": "/user-guide/workflows/how-tos/how-to-use-branches-in-workflows", + "destination": "/user-guide/workflows/capabilities/use-branches-in-workflows" + }, + { + "source": "/user-guide/workflows/getting-started/getting-started-workflows", + "destination": "/user-guide/workflows/overview" + }, + { + "source": "/user-guide/views-pipelines/how-tos/create-custom-views", + "destination": "/user-guide/views-pipelines/overview" + }, + { + "source": "/user-guide/views-pipelines/getting-started/view-management", + "destination": "/user-guide/views-pipelines/overview" + }, + { + "source": "/user-guide/billing/capabilities/billing-and-pricing-faq", + "destination": "/user-guide/billing/how-tos/billing-faq" + } + ] } diff --git a/packages/twenty-docs/getting-started/create-workspace.mdx b/packages/twenty-docs/getting-started/create-workspace.mdx deleted file mode 100644 index 003a26767c..0000000000 --- a/packages/twenty-docs/getting-started/create-workspace.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Create a Workspace -description: "Follow a step-by-step guide on how to register on Twenty, choose a subscription plan, confirm your payment and set up your account." ---- - -## 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. - -## 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. - -## Step 3: Payment Confirmation & Account Setup - -Post 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). - diff --git a/packages/twenty-docs/getting-started/what-is-twenty.mdx b/packages/twenty-docs/getting-started/what-is-twenty.mdx deleted file mode 100644 index 3edc7b2949..0000000000 --- a/packages/twenty-docs/getting-started/what-is-twenty.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: What is Twenty -description: "Discover Twenty, an open-source CRM, its features, benefits, system requirements, and how to get involved." ---- - -Twenty is the leading open-source CRM, crafted by hundreds of contributors to suit your unique 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 - -**Contact Management:** Efficiently store and manage customer data. - -**Custom Objects:** Create and customize objects to fit your business needs. - -**Custom Fields:** Tailor data fields to capture and organize information specific to your operations. - -**Deal Management:** Track and manage your sales opportunities through customizable Pipeline stages. - -**Kanban & Table Views:** Make data actionable with flexible table views. - -**Workflows:** Automate your business processes and integrate with external tools using powerful workflow automation. - -**Email Integration:** View the emails of a specific customer or company within your workspace. - -**Notes:** Create detailed notes for each record to share knowledge more effectively. - -**Tasks:** Schedule tasks to track customer interactions. - -**Permissions:** Control access and manage user roles with flexible workspace and object-level permissions. - -**API & Webhooks:** Connect to other apps and automate workflows with API and Webhooks. - -## Join now - -[Register here](https://app.twenty.com) or [become a contributor on GitHub](https://github.com/twentyhq/twenty). - diff --git a/packages/twenty-docs/images/user-guide/dashboard/dashboards.png b/packages/twenty-docs/images/user-guide/dashboard/dashboards.png new file mode 100644 index 0000000000..e9a484811f Binary files /dev/null and b/packages/twenty-docs/images/user-guide/dashboard/dashboards.png differ diff --git a/packages/twenty-docs/images/user-guide/dashboard/dashboards_v2.png b/packages/twenty-docs/images/user-guide/dashboard/dashboards_v2.png new file mode 100644 index 0000000000..888711f29f Binary files /dev/null and b/packages/twenty-docs/images/user-guide/dashboard/dashboards_v2.png differ diff --git a/packages/twenty-docs/images/user-guide/fields/all-field-types.png b/packages/twenty-docs/images/user-guide/fields/all-field-types.png new file mode 100644 index 0000000000..9d1cd11eaf Binary files /dev/null and b/packages/twenty-docs/images/user-guide/fields/all-field-types.png differ diff --git a/packages/twenty-docs/images/user-guide/fields/many-to-one-morph.png b/packages/twenty-docs/images/user-guide/fields/many-to-one-morph.png new file mode 100644 index 0000000000..a3cb879cb3 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/fields/many-to-one-morph.png differ diff --git a/packages/twenty-docs/images/user-guide/fields/one-to-many-morph.png b/packages/twenty-docs/images/user-guide/fields/one-to-many-morph.png new file mode 100644 index 0000000000..ef292327b2 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/fields/one-to-many-morph.png differ diff --git a/packages/twenty-docs/images/user-guide/home/command-menu.png b/packages/twenty-docs/images/user-guide/home/command-menu.png new file mode 100644 index 0000000000..83add11221 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/home/command-menu.png differ diff --git a/packages/twenty-docs/images/user-guide/home/main-layout.png b/packages/twenty-docs/images/user-guide/home/main-layout.png new file mode 100644 index 0000000000..481655d7fc Binary files /dev/null and b/packages/twenty-docs/images/user-guide/home/main-layout.png differ diff --git a/packages/twenty-docs/images/user-guide/home/navigation-bar.png b/packages/twenty-docs/images/user-guide/home/navigation-bar.png new file mode 100644 index 0000000000..a043c28afd Binary files /dev/null and b/packages/twenty-docs/images/user-guide/home/navigation-bar.png differ diff --git a/packages/twenty-docs/images/user-guide/home/search-bar.png b/packages/twenty-docs/images/user-guide/home/search-bar.png new file mode 100644 index 0000000000..307d34b17e Binary files /dev/null and b/packages/twenty-docs/images/user-guide/home/search-bar.png differ diff --git a/packages/twenty-docs/images/user-guide/home/side-panel.png b/packages/twenty-docs/images/user-guide/home/side-panel.png new file mode 100644 index 0000000000..f4f6b0892b Binary files /dev/null and b/packages/twenty-docs/images/user-guide/home/side-panel.png differ diff --git a/packages/twenty-docs/images/user-guide/home/view-menu.png b/packages/twenty-docs/images/user-guide/home/view-menu.png new file mode 100644 index 0000000000..f89c70390d Binary files /dev/null and b/packages/twenty-docs/images/user-guide/home/view-menu.png differ diff --git a/packages/twenty-docs/images/user-guide/reporting/pie-chart.png b/packages/twenty-docs/images/user-guide/reporting/pie-chart.png new file mode 100644 index 0000000000..0a344107d6 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/reporting/pie-chart.png differ diff --git a/packages/twenty-docs/images/user-guide/setup/pricing.png b/packages/twenty-docs/images/user-guide/setup/pricing.png index 96dde8dd9e..892add61a2 100644 Binary files a/packages/twenty-docs/images/user-guide/setup/pricing.png and b/packages/twenty-docs/images/user-guide/setup/pricing.png differ diff --git a/packages/twenty-docs/images/user-guide/table-views/table-group-by.png b/packages/twenty-docs/images/user-guide/table-views/table-group-by.png new file mode 100644 index 0000000000..7540d089e8 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/table-views/table-group-by.png differ diff --git a/packages/twenty-docs/images/user-guide/table-views/table-view.png b/packages/twenty-docs/images/user-guide/table-views/table-view.png new file mode 100644 index 0000000000..4e143bb40e Binary files /dev/null and b/packages/twenty-docs/images/user-guide/table-views/table-view.png differ diff --git a/packages/twenty-docs/images/user-guide/table-views/table_orange.png b/packages/twenty-docs/images/user-guide/table-views/table_orange.png new file mode 100644 index 0000000000..6f6ac0f64c Binary files /dev/null and b/packages/twenty-docs/images/user-guide/table-views/table_orange.png differ diff --git a/packages/twenty-docs/images/user-guide/table-views/table_pink.png b/packages/twenty-docs/images/user-guide/table-views/table_pink.png new file mode 100644 index 0000000000..ca9fd73757 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/table-views/table_pink.png differ diff --git a/packages/twenty-docs/images/user-guide/views/calendar-view-zoom.png b/packages/twenty-docs/images/user-guide/views/calendar-view-zoom.png new file mode 100644 index 0000000000..eb59f292b1 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/views/calendar-view-zoom.png differ diff --git a/packages/twenty-docs/images/user-guide/views/calendar-view.png b/packages/twenty-docs/images/user-guide/views/calendar-view.png new file mode 100644 index 0000000000..0f8ed055fd Binary files /dev/null and b/packages/twenty-docs/images/user-guide/views/calendar-view.png differ diff --git a/packages/twenty-docs/images/user-guide/what-is-twenty/gear-icon.png b/packages/twenty-docs/images/user-guide/what-is-twenty/gear-icon.png new file mode 100644 index 0000000000..7e3b4dc5bf Binary files /dev/null and b/packages/twenty-docs/images/user-guide/what-is-twenty/gear-icon.png differ diff --git a/packages/twenty-docs/images/user-guide/what-is-twenty/open-book-icon.png b/packages/twenty-docs/images/user-guide/what-is-twenty/open-book-icon.png new file mode 100644 index 0000000000..1fa88427ce Binary files /dev/null and b/packages/twenty-docs/images/user-guide/what-is-twenty/open-book-icon.png differ diff --git a/packages/twenty-docs/images/user-guide/what-is-twenty/play-icon.png b/packages/twenty-docs/images/user-guide/what-is-twenty/play-icon.png new file mode 100644 index 0000000000..ad47dffdf9 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/what-is-twenty/play-icon.png differ diff --git a/packages/twenty-docs/images/user-guide/what-is-twenty/question-mark-icon.png b/packages/twenty-docs/images/user-guide/what-is-twenty/question-mark-icon.png new file mode 100644 index 0000000000..c08f6e409c Binary files /dev/null and b/packages/twenty-docs/images/user-guide/what-is-twenty/question-mark-icon.png differ diff --git a/packages/twenty-docs/images/user-guide/what-is-twenty/tool-icon.png b/packages/twenty-docs/images/user-guide/what-is-twenty/tool-icon.png new file mode 100644 index 0000000000..4dcffbe136 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/what-is-twenty/tool-icon.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/add_to_newsletter_button.png b/packages/twenty-docs/images/user-guide/workflows/add_to_newsletter_button.png new file mode 100644 index 0000000000..d6ed09e1ff Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/add_to_newsletter_button.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/branches.png b/packages/twenty-docs/images/user-guide/workflows/branches.png new file mode 100644 index 0000000000..ade22e3cd0 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/branches.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/create_users_workflow.png b/packages/twenty-docs/images/user-guide/workflows/create_users_workflow.png new file mode 100644 index 0000000000..bb3f187f56 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/create_users_workflow.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/email_tasks_due.png b/packages/twenty-docs/images/user-guide/workflows/email_tasks_due.png new file mode 100644 index 0000000000..afbb028764 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/email_tasks_due.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/http_action.png b/packages/twenty-docs/images/user-guide/workflows/http_action.png new file mode 100644 index 0000000000..4ad71e6ac9 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/http_action.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/manual_trigger.png b/packages/twenty-docs/images/user-guide/workflows/manual_trigger.png new file mode 100644 index 0000000000..8d2fdb39d1 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/manual_trigger.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/update_record.png b/packages/twenty-docs/images/user-guide/workflows/update_record.png new file mode 100644 index 0000000000..05fdff1d08 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/update_record.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/upsert_double_identifier.png b/packages/twenty-docs/images/user-guide/workflows/upsert_double_identifier.png new file mode 100644 index 0000000000..18416d0cf1 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/upsert_double_identifier.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/upsert_simple_identifier.png b/packages/twenty-docs/images/user-guide/workflows/upsert_simple_identifier.png new file mode 100644 index 0000000000..7ed5237d65 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/upsert_simple_identifier.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/webhook_trigger.png b/packages/twenty-docs/images/user-guide/workflows/webhook_trigger.png new file mode 100644 index 0000000000..b8fc949f23 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/webhook_trigger.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/workflow_actions.png b/packages/twenty-docs/images/user-guide/workflows/workflow_actions.png new file mode 100644 index 0000000000..9b4175c108 Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/workflow_actions.png differ diff --git a/packages/twenty-docs/images/user-guide/workflows/workflow_triggers.png b/packages/twenty-docs/images/user-guide/workflows/workflow_triggers.png new file mode 100644 index 0000000000..90f8696cdc Binary files /dev/null and b/packages/twenty-docs/images/user-guide/workflows/workflow_triggers.png differ diff --git a/packages/twenty-docs/navigation/base-structure.json b/packages/twenty-docs/navigation/base-structure.json index 1e1782934f..ada4f5d490 100644 --- a/packages/twenty-docs/navigation/base-structure.json +++ b/packages/twenty-docs/navigation/base-structure.json @@ -12,7 +12,7 @@ "user-guide/introduction", "user-guide/getting-started/what-is-twenty", "user-guide/getting-started/create-workspace", - "user-guide/getting-started/getting-around-twenty", + "user-guide/getting-started/navigate-around-twenty", "user-guide/getting-started/configure-your-workspace", "user-guide/getting-started/implementation-services", "user-guide/getting-started/migrating-from-other-crms", diff --git a/packages/twenty-docs/navigation/navigation-schema.json b/packages/twenty-docs/navigation/navigation-schema.json index 1e1782934f..ada4f5d490 100644 --- a/packages/twenty-docs/navigation/navigation-schema.json +++ b/packages/twenty-docs/navigation/navigation-schema.json @@ -12,7 +12,7 @@ "user-guide/introduction", "user-guide/getting-started/what-is-twenty", "user-guide/getting-started/create-workspace", - "user-guide/getting-started/getting-around-twenty", + "user-guide/getting-started/navigate-around-twenty", "user-guide/getting-started/configure-your-workspace", "user-guide/getting-started/implementation-services", "user-guide/getting-started/migrating-from-other-crms", diff --git a/packages/twenty-docs/user-guide/ai/capabilities/ai-agents.mdx b/packages/twenty-docs/user-guide/ai/capabilities/ai-agents.mdx new file mode 100644 index 0000000000..ddb012003a --- /dev/null +++ b/packages/twenty-docs/user-guide/ai/capabilities/ai-agents.mdx @@ -0,0 +1,35 @@ +--- +title: AI Agents +description: Integrate AI capabilities directly into your automation workflows. +--- + + +This feature is in development and will be available in beta soon. + + +## 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 + diff --git a/packages/twenty-docs/user-guide/ai/capabilities/ai-chatbot.mdx b/packages/twenty-docs/user-guide/ai/capabilities/ai-chatbot.mdx new file mode 100644 index 0000000000..9c57bdf4be --- /dev/null +++ b/packages/twenty-docs/user-guide/ai/capabilities/ai-chatbot.mdx @@ -0,0 +1,39 @@ +--- +title: AI Chatbot +description: An intelligent assistant that helps you interact with your CRM data using natural language. +--- + + +This feature is in development and will be available in beta soon. + + +## Overview + +An intelligent assistant that helps you interact with your CRM data using natural language. + +## 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) + diff --git a/packages/twenty-docs/user-guide/ai/capabilities/permissions-access-control.mdx b/packages/twenty-docs/user-guide/ai/capabilities/permissions-access-control.mdx new file mode 100644 index 0000000000..afa8063e51 --- /dev/null +++ b/packages/twenty-docs/user-guide/ai/capabilities/permissions-access-control.mdx @@ -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 → 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 | + + +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. + + +## 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 + diff --git a/packages/twenty-docs/user-guide/ai/how-tos/ai-faq.mdx b/packages/twenty-docs/user-guide/ai/how-tos/ai-faq.mdx new file mode 100644 index 0000000000..e0c03e2fb9 --- /dev/null +++ b/packages/twenty-docs/user-guide/ai/how-tos/ai-faq.mdx @@ -0,0 +1,32 @@ +--- +title: AI FAQ +description: Frequently asked questions about AI features in Twenty. +--- + + + + + AI features are currently in development and will be released in beta soon. Stay tuned for updates! + + + + We're building two main AI capabilities: + + 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 + + + + AI agents will operate under the permission system. You can assign specific roles to AI agents under **Settings → Roles**, giving you full control over what data they can access and what actions they can perform. + + + + AI actions will consume workflow credits based on the complexity of the task and the AI model used. More details will be available when the features launch. + + + + Initially, Twenty will use built-in AI models. Support for custom or external AI models may be added in future releases based on user feedback. + + + + diff --git a/packages/twenty-docs/user-guide/ai/overview.mdx b/packages/twenty-docs/user-guide/ai/overview.mdx new file mode 100644 index 0000000000..918b27b28f --- /dev/null +++ b/packages/twenty-docs/user-guide/ai/overview.mdx @@ -0,0 +1,58 @@ +--- +title: AI +description: AI-powered features coming soon to Twenty. +--- + + + AI + + +## What's Coming + +Twenty is building AI capabilities to help your team work smarter. We're focusing on two major areas: + +### 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 will be managed through the existing permissions system: + +1. Go to **Settings → 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. + +## Stay Updated + +We'll update this section as AI features become available. In the meantime: + +- Follow our [GitHub](https://github.com/twentyhq/twenty) for development updates +- Join our [Discord](https://discord.gg/twenty) to share feedback and feature requests diff --git a/packages/twenty-docs/user-guide/billing/capabilities/pricing-plans.mdx b/packages/twenty-docs/user-guide/billing/capabilities/pricing-plans.mdx new file mode 100644 index 0000000000..6de015c8d4 --- /dev/null +++ b/packages/twenty-docs/user-guide/billing/capabilities/pricing-plans.mdx @@ -0,0 +1,67 @@ +--- +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 + + +Premium features (SSO and row-level permissions) are not included in the Pro plan. + + +### Organization (Cloud) +For larger teams with advanced needs: +- Everything in Pro +- **Premium features**: SSO integration and row-level permissions +- 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 and row-level permissions +- 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 + +## Switching Plans + +### Upgrade to Organization +1. Go to **Settings → Billing** +2. Click **Switch to Organization** +3. Confirm your upgrade + +### Downgrade to Pro +Contact support to downgrade your plan. + +### Switch to Yearly Billing +1. Go to **Settings → Billing** +2. Click **Switch to Yearly** +3. Save with annual billing + +### Switch to Monthly Billing +Contact support to switch back to monthly billing. + diff --git a/packages/twenty-docs/user-guide/billing/capabilities/workflow-credits.mdx b/packages/twenty-docs/user-guide/billing/capabilities/workflow-credits.mdx new file mode 100644 index 0000000000..83129ce029 --- /dev/null +++ b/packages/twenty-docs/user-guide/billing/capabilities/workflow-credits.mdx @@ -0,0 +1,48 @@ +--- +title: Workflow Credits +description: Understanding workflow credits, consumption, and how to purchase more. +--- + +## Overview + +Credits power your workflow automations in Twenty. Every workflow action consumes credits based on its complexity. + +## Credit Allocation + +Credits are based on your billing cycle, not your plan: + +| Billing Cycle | Credits | +|---------------|---------| +| Monthly | 5 million/month | +| Yearly | 50 million/year | + + +The 5 million monthly credits are designed to empower you to run automations without worrying about costs. For most workflows using standard actions, this is more than enough. You'll only need additional credits when running advanced code nodes or AI-powered features. + + +## Credit Consumption + +Different actions consume different amounts of credits: + +| Action Type | Credit Usage | +|-------------|--------------| +| **Basic operations** (search, update, create records) | Minimal | +| **Complex operations** (code nodes, external API calls) | More credits | +| **AI prompts** (coming soon) | Variable based on usage | + +Credits are deducted in real-time when workflows execute. + +## Monitoring Usage + +Track your credit consumption: +1. Go to **Settings → Billing** +2. View your current usage and remaining credits +3. Monitor trends to plan for additional credits if needed + +## Purchasing Additional Credits + +Need more credits? +1. Go to **Settings → Billing** +2. Click on the option to purchase additional credit packs +3. Select the amount you need + diff --git a/packages/twenty-docs/user-guide/pricing/billing-and-pricing-faq.mdx b/packages/twenty-docs/user-guide/billing/how-tos/billing-faq.mdx similarity index 73% rename from packages/twenty-docs/user-guide/pricing/billing-and-pricing-faq.mdx rename to packages/twenty-docs/user-guide/billing/how-tos/billing-faq.mdx index 264e9b9169..e019844ee0 100644 --- a/packages/twenty-docs/user-guide/pricing/billing-and-pricing-faq.mdx +++ b/packages/twenty-docs/user-guide/billing/how-tos/billing-faq.mdx @@ -1,20 +1,21 @@ --- -title: Billing and Pricing FAQ -info: "Everything you need to know about the pricing and billing." -image: /images/user-guide/setup/pricing.png -sectionInfo: Understand how Twenty pricing works. +title: Billing FAQ +description: Frequently asked questions about Twenty pricing and billing. --- - - Header - ## Pricing -Yes, you can use Twenty for free while self-hosting. You will get access to everything included in the (cloud) Pro subscription, except the support from our core-team. Support is accessible via our Discord community. +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 have access to the features included in the (cloud) Organization subscription, including support from our core-team, you can do so by choosing the paid Organization licences, available in self-hosting. +If you want to self-host and need the Premium features (SSO and row-level permissions), 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. + + + +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 @@ -42,7 +43,9 @@ You will find this under `Settings → Billing`. -The number of credits varies based on the plan. A workspace under **trial gets 5 million credits**, one with a **Pro plan gets 10 million credits per month** and one with an **Organization plan gets 20 million credits per month**. +The number of credits depends on your billing cycle, not your plan: +- **Monthly subscriptions**: 5 million credits per month +- **Yearly subscriptions**: 50 million credits per year @@ -78,4 +81,3 @@ You can do so under `Settings → Billing`. Then click on `View billing details` 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. - diff --git a/packages/twenty-docs/user-guide/billing/overview.mdx b/packages/twenty-docs/user-guide/billing/overview.mdx new file mode 100644 index 0000000000..902a88e89c --- /dev/null +++ b/packages/twenty-docs/user-guide/billing/overview.mdx @@ -0,0 +1,44 @@ +--- +title: Billing +description: Understand Twenty pricing and manage your subscription. +image: /images/user-guide/setup/pricing.png +--- + + + Billing + + +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 + + + + Learn about Twenty's pricing plans and what's included. + + + Frequently asked questions about pricing and billing. + + + +## At a glance + +| Plan | Key Features | +|------|--------------| +| **Free (Self-Hosted)** | All Pro features, community support | +| **Pro (Cloud)** | Everything apart from the Premium features (SSO and row-level permissions), standard support | +| **Organization (Cloud)** | All from Pro + the Premium features (SSO and row-level permissions), priority support | +| **Organization (Self-Hosted)** |All from Pro + the Premium features (SSO, row-level permissions), 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). diff --git a/packages/twenty-docs/user-guide/calendar-emails/capabilities/calendar.mdx b/packages/twenty-docs/user-guide/calendar-emails/capabilities/calendar.mdx new file mode 100644 index 0000000000..40549691f4 --- /dev/null +++ b/packages/twenty-docs/user-guide/calendar-emails/capabilities/calendar.mdx @@ -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 this 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 + diff --git a/packages/twenty-docs/user-guide/collaboration/emails-and-calendars.mdx b/packages/twenty-docs/user-guide/calendar-emails/capabilities/mailbox.mdx similarity index 69% rename from packages/twenty-docs/user-guide/collaboration/emails-and-calendars.mdx rename to packages/twenty-docs/user-guide/calendar-emails/capabilities/mailbox.mdx index 9f613184b3..4183413e0d 100644 --- a/packages/twenty-docs/user-guide/collaboration/emails-and-calendars.mdx +++ b/packages/twenty-docs/user-guide/calendar-emails/capabilities/mailbox.mdx @@ -1,20 +1,15 @@ --- -title: Emails and Calendars -info: "View and manage email conversations within your CRM records." -image: /images/user-guide/emails/emails_header.png -sectionInfo: Centralize communications and team collaboration +title: Mailbox +description: Understanding email integration features in Twenty. --- - - Header - -**Note**: To connect your email accounts and configure sync settings, visit [Email & Calendar Setup](/user-guide/settings/email-calendar-setup). +**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. -### Where to Find Emails +### Objects Where Emails Can Be Found Email conversations appear in three main objects: @@ -80,24 +75,3 @@ Control which email folders sync with Twenty: - **System Folders**: Some email folders may not be available for sync - **Aliases**: Only true mailboxes can be connected (not email aliases) - -## Calendar Integration - -### Calendar Tab -Next to the Emails tab, 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 this opportunity - -**Visibility Settings**: Calendar data follows the same visibility settings as emails, ensuring consistent privacy controls across both communication channels. - -### 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 - - - diff --git a/packages/twenty-docs/user-guide/calendar-emails/how-tos/can-i-book-meetings-from-twenty.mdx b/packages/twenty-docs/user-guide/calendar-emails/how-tos/can-i-book-meetings-from-twenty.mdx new file mode 100644 index 0000000000..fe49bdfa54 --- /dev/null +++ b/packages/twenty-docs/user-guide/calendar-emails/how-tos/can-i-book-meetings-from-twenty.mdx @@ -0,0 +1,28 @@ +--- +title: Can I Book Meetings from Twenty? +description: Information about booking meetings directly from Twenty. +--- + +## Current Status + +**No, Twenty does not currently support booking meetings directly from the platform.** + +Twenty's calendar integration is designed to **sync and display** your existing calendar events, not to create new ones. All meeting scheduling should be done through your native calendar application (Google Calendar, Microsoft Outlook, etc.). + +## What You Can Do + +- **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 + +## How to Schedule Meetings + +1. Use your native calendar app (Google Calendar, Outlook, etc.) +2. Create the meeting as you normally would +3. The meeting will automatically sync to Twenty within 5 minutes +4. View the meeting on the relevant CRM records + +## Future Plans + +Meeting creation 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. diff --git a/packages/twenty-docs/user-guide/calendar-emails/how-tos/can-i-send-emails-from-twenty.mdx b/packages/twenty-docs/user-guide/calendar-emails/how-tos/can-i-send-emails-from-twenty.mdx new file mode 100644 index 0000000000..025c786d13 --- /dev/null +++ b/packages/twenty-docs/user-guide/calendar-emails/how-tos/can-i-send-emails-from-twenty.mdx @@ -0,0 +1,43 @@ +--- +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. Emails cannot be composed or sent directly from Twenty's interface. + +When you view an email thread on a record page and click **Reply**, you'll be redirected to the original thread in your mailbox (Gmail, Outlook, etc.). This is where you compose and send your reply. + +## 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 + +While you can't send emails manually from Twenty, 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. + + +Mass emails should not be sent directly from your mailbox to protect your domain reputation. Use a dedicated tool for bulk communications. + + +→ 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. diff --git a/packages/twenty-docs/user-guide/calendar-emails/how-tos/can-i-track-email-activity-on-all-objects.mdx b/packages/twenty-docs/user-guide/calendar-emails/how-tos/can-i-track-email-activity-on-all-objects.mdx new file mode 100644 index 0000000000..b8f14ceb69 --- /dev/null +++ b/packages/twenty-docs/user-guide/calendar-emails/how-tos/can-i-track-email-activity-on-all-objects.mdx @@ -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. diff --git a/packages/twenty-docs/user-guide/calendar-emails/how-tos/connect-several-mailboxes-per-user.mdx b/packages/twenty-docs/user-guide/calendar-emails/how-tos/connect-several-mailboxes-per-user.mdx new file mode 100644 index 0000000000..c526e2d2d1 --- /dev/null +++ b/packages/twenty-docs/user-guide/calendar-emails/how-tos/connect-several-mailboxes-per-user.mdx @@ -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 your additional Google or Microsoft account +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 (Lab feature) + +## 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 + +Each email shows which mailbox it was sent from/received to, so you can track which account was used for each communication. + +## Important Notes + +Only true mailboxes can be connected. Email aliases that forward to another mailbox cannot be connected separately—they'll sync through the main mailbox. diff --git a/packages/twenty-docs/user-guide/calendar-emails/how-tos/i-dont-see-emails-on-records.mdx b/packages/twenty-docs/user-guide/calendar-emails/how-tos/i-dont-see-emails-on-records.mdx new file mode 100644 index 0000000000..5d3605473b --- /dev/null +++ b/packages/twenty-docs/user-guide/calendar-emails/how-tos/i-dont-see-emails-on-records.mdx @@ -0,0 +1,45 @@ +--- +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. +- **Calendar sync**: Completes in minutes +- **Email sync**: Can take several hours for large mailboxes + +**Solution**: Wait up to a few hours for the initial import to complete. + +### 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 diff --git a/packages/twenty-docs/user-guide/calendar-emails/how-tos/limit-emails-imported.mdx b/packages/twenty-docs/user-guide/calendar-emails/how-tos/limit-emails-imported.mdx new file mode 100644 index 0000000000..eee2ecec25 --- /dev/null +++ b/packages/twenty-docs/user-guide/calendar-emails/how-tos/limit-emails-imported.mdx @@ -0,0 +1,52 @@ +--- +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 → Releases → Lab** +2. Enable **Message Folder** +3. Return to **Settings → Accounts** +4. Select your connected email account +5. 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 | + +6. Exclude folders you don't want synced (Spam, Trash, personal folders) + +This gives you precise control over which emails appear in your CRM without syncing everything. + +## 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 + +## What's Always Excluded + +These emails are never synced, regardless of settings: + +- **Internal emails**: Messages between colleagues (same domain) +- **Group emails**: Distribution lists and group messages +- **Spam/Trash**: System folders are typically excluded + +## Important Note + +We don't provide a CC email address for selective syncing. Use the folder selection feature above to achieve the same level of control. diff --git a/packages/twenty-docs/user-guide/settings/email-calendar-setup.mdx b/packages/twenty-docs/user-guide/calendar-emails/overview.mdx similarity index 71% rename from packages/twenty-docs/user-guide/settings/email-calendar-setup.mdx rename to packages/twenty-docs/user-guide/calendar-emails/overview.mdx index 7334cc0194..3bd2528362 100644 --- a/packages/twenty-docs/user-guide/settings/email-calendar-setup.mdx +++ b/packages/twenty-docs/user-guide/calendar-emails/overview.mdx @@ -1,11 +1,11 @@ --- -title: Email & Calendar Setup -info: "Connect your email and calendar accounts." +title: Calendar & Emails +description: Connect your email and calendar accounts to Twenty. image: /images/user-guide/emails/emails_header.png -sectionInfo: Configure your Twenty workspace settings and preferences --- + - Header + Calendar & Emails ## Connection Options @@ -15,14 +15,18 @@ sectionInfo: Configure your Twenty workspace settings and preferences 2. Click **Add account** 3. Select **Continue with Google** 4. Authorize Twenty to access your Gmail and Google Calendar -5. Your emails and calendar events will start syncing automatically +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. Your emails and calendar events will start syncing automatically +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 ### SMTP/CalDAV Setup (Other Providers) For other email and calendar providers: @@ -58,6 +62,8 @@ Choose different levels of visibility for your emails: - **For messages sent only**: Create contacts only for emails you send - **Note**: Internal emails (same domain) are never synced to maintain privacy +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. + ### Control which emails get sync with Message Folder Selection (Lab Feature) Control which email folders sync with Twenty: 1. Go to **Settings → Releases → Lab** and enable **Message Folder** @@ -90,6 +96,7 @@ Choose what will be visible to other users in your workspace: - **Yes**: Automatically create contacts for meeting participants not in your CRM - **No**: Only link meetings to existing contacts +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. ### Control which events get sync - **Meeting Import**: Automatically import calendar events @@ -106,5 +113,11 @@ Choose what will be visible to other users in your workspace: **Updates every 5 minutes**: Both email and calendar data sync automatically every 5 minutes after the initial import. + +**Initial sync timing**: Calendar sync completes quickly (usually within minutes), while email sync takes longer for large mailboxes—up to a few hours depending on volume. Don't worry if you see contacts from calendar events appearing before your email contacts; this is normal behavior. + +## 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) diff --git a/packages/twenty-docs/user-guide/collaboration/notes.mdx b/packages/twenty-docs/user-guide/collaboration/notes.mdx deleted file mode 100644 index 2e5a55091f..0000000000 --- a/packages/twenty-docs/user-guide/collaboration/notes.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Notes -info: Explore how to efficiently manage notes within record pages in Twenty. -image: /images/user-guide/notes/notes_header.png -sectionInfo: Discover how to leverage Notes and Tasks to better collaborate with your team. ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -Manage your record-linked notes efficiently using the powerful **Notes** feature. This guide walks through how to create, format, comment, and delete notes seamlessly within record pages. - -## Common Use Cases - -### Meeting Documentation -- **Meeting Minutes**: Log key discussion points, decisions, and action items from client calls -- **Call Summaries**: Record important details from sales conversations or support calls -- **Follow-up Notes**: Document next steps and commitments made during meetings - -### Customer Interactions -- **Support History**: Track customer issues, solutions provided, and resolution status -- **Sales Context**: Record customer preferences, pain points, and buying signals -- **Relationship Building**: Note personal details about contacts to strengthen relationships - -### Project Management -- **Status Updates**: Document project progress and milestone achievements -- **Issue Tracking**: Log problems encountered and solutions implemented -- **Team Handoffs**: Share context when transferring accounts between team members - -### Automated Note Creation -Use [Workflows](/user-guide/workflows/getting-started-workflows) to automatically create notes: -- **Call Recorder Integration**: Auto-generate meeting summaries from recorded calls -- **Deal Handoff Notes**: Auto-create sales cycle summaries when handing off new customers to implementation teams - -## Note Features - -### Relations Field -Notes include a **Relations** field that allows you to attach a single note to multiple records across different objects. For example, you can link one meeting note to: -- The Person you met with -- The Company they represent -- The Opportunity being discussed -- Any relevant Tasks or other records - -This morph many relationship ensures important information is accessible from all relevant record pages. - -### User Tagging -**Note**: User tagging within notes is not currently available. This feature is planned for 2026, which will allow you to mention team members and trigger notifications. - -## Creating Notes - -Creating notes in the system is intuitive and dynamic. You can either: - -- Navigate to the notes view and create a new record. -- Go to a `Record page` and select the Notes tab and press the `New note` button. - - - - -### Adding Content - -Start typing directly or press `/` to add elements like headings, files, or images instantly. - -### Format Content - -You can format your notes right from the editor. Use Markdown syntax, press the `/` key or click on the `+` icon on the editor to see the different block options, such as headings, tables, and lists. You can also attach images to your note. - -Highlight the text to see more formatting options like bold, italics, and alignment options. - -You can also change the background color and text color of each block to highlight important things in your note. To do so, hover over the block you want to format and click on the `⋮` icon besides the `+` icon. Click on `Colors` to open up all color options for both the text and the background. - - - -## Viewing Notes - -The system displays all your notes linked to a specific record under the Notes section on the corresponding `Record page`. - -## Saving And Deleting - -All edits and additions to the note are automatically saved. - -To delete a note: - -1. Open the note you wish to remove by clicking on it from within the `Record page`. -2. Select the note you want to delete within the notes tab. -3. Use the `Option` button in the lower right corner to prompt additional actions including delete. -4. Complete your deletion when prompted with the confirmation modal. - -Another way to delete a note is through the notes view like you would a regular record. Please be aware that deleting a note is permanent and can't be undone. - - diff --git a/packages/twenty-docs/user-guide/collaboration/tasks.mdx b/packages/twenty-docs/user-guide/collaboration/tasks.mdx deleted file mode 100644 index 0a40094c81..0000000000 --- a/packages/twenty-docs/user-guide/collaboration/tasks.mdx +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: Tasks -info: Understand how to effectively manage tasks in Twenty. -image: /images/user-guide/tasks/tasks_header.png -sectionInfo: Discover how to leverage Notes and Tasks to better collaborate with your team. ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -Manage all tasks within your workspace using the **Tasks** feature. This guide will show you how to create and manage tasks, switch between upcoming and completed tasks, edit task details, and much more. - -## Common Use Cases - -### Sales Follow-ups -- **Meeting Next Steps**: Create tasks for action items discussed during client calls -- **Proposal Follow-ups**: Set reminders to check on pending proposals -- **Contract Reviews**: Schedule tasks for contract negotiations and approvals - -### Customer Success -- **Onboarding Tasks**: Automatically create onboarding checklists when deals close -- **Check-in Reminders**: Schedule regular customer health check calls -- **Renewal Preparation**: Set tasks to prepare for contract renewals 90 days in advance - -### Internal Project Management -Beyond sales and customer success, Tasks support broader organizational needs: -- **Product Development**: Track feature releases, bug fixes, and development milestones -- **Marketing Campaigns**: Manage campaign launches, content creation, and promotional activities -- **HR Operations**: Handle recruitment processes, employee onboarding, and performance reviews -- **Finance Tasks**: Schedule budget reviews, invoice processing, and financial reporting -- **Operations**: Coordinate facility management, vendor relationships, and process improvements - -### Automated Task Creation -Use [Workflows](/user-guide/workflows/getting-started-workflows) to automatically create tasks: -- **Deal Won Triggers**: Auto-create onboarding tasks assigned to CS team when opportunities close -- **Email Reminders**: Set up weekly email reminders for tasks due this week (sent every Monday) -- **Pipeline Automation**: Create follow-up tasks when deals stall in specific stages -- **Meeting Integration**: Auto-generate tasks from meeting recordings or calendar events - - -## Task Features - -### Relations Field -Tasks include a `Relations` field that allows you to attach a single task to multiple records across different objects. For example, you can link one follow-up task to: -- The Person you need to contact -- The Company they represent -- The Opportunity being pursued -- Any relevant Notes or other records - -This morph many relationship ensures tasks are accessible from all relevant record pages and provides complete context. - -### User Tagging -**Note**: User tagging within tasks is not currently available. This feature is planned for 2026, which will allow you to mention team members and trigger notifications when assigning or updating tasks. - -## Creating Tasks - -Creating tasks in Twenty is seamless. You can either: - -- Go to the `Tasks`tab and press the `+` button at the top right of the page. -- Use the search function by pressing `cmd/ctrl + k`, then select 'Create task' from the list of quick actions. -- Go to a `Record page` and press `+` at the top right of the page, or go to the Task tab and press the `Add Task` button. - - - -### Adding Task Content - -Once you've created a task you can enrich it with rich content, such as Titles, Bullet points or even images. To do so, press `/` and enter the desired command. - -## Viewing Tasks - -The **Tasks** page displays all your tasks across your workspace. Here you can: - -- Filter tasks assigned to a specific user by clicking the button with your name at the top right of the screen. -- Toggle between upcoming (`To do`) and completed (`Done`) tasks to see what needs attention and what you have accomplished. - -You can also see tasks for a given Record on its `Record page`. - - - -## Editing Tasks - -To edit a task, you should click on its card. This will open a side panel offering the following features: - -- **Assignee and Due date**: Update the assignee or edit the due date. -- **Comments**: Work together with your team members by adding comments on tasks to give updates or feedback. -- **Automations**: Thanks to the API and Webhooks, you can also automate task creation triggered by specific activities in your workspace. - -## Marking Tasks as Complete - -To mark a task as complete: - -1. Locate the task on your `Tasks` page or within a `Record page`. -2. Click on the circle at the left of the task card, it will change to signify completion. -3. The task status will automatically update to `Done`. - -This procedure will help keep an updated record of your accomplishments. - - - -## Delete a task - -To permanently remove a task: - -1. Open the task you want to delete by clicking on its card, either from the `Tasks` page or within a `Record page`. -2. Click the trash icon located in the top right corner of the task details panel. - -Please note, deleting a task is permanent and can't be undone. Consider marking tasks as `Done` if there is a chance you will need to refer to them again. - diff --git a/packages/twenty-docs/user-guide/crm-essentials/contact-and-account-management.mdx b/packages/twenty-docs/user-guide/crm-essentials/contact-and-account-management.mdx deleted file mode 100644 index bc5635674c..0000000000 --- a/packages/twenty-docs/user-guide/crm-essentials/contact-and-account-management.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Contact and Account Management -info: "Create and manage People and Company records to build your customer database." -image: /images/user-guide/home/contact-and-account-management.png -sectionInfo: "Essential CRM features for managing leads, sales, and customers" ---- - - Header - - -## Getting data into your CRM - -When you start using Twenty, you'll want to get your contacts and companies into the system. There are several ways to populate your CRM depending on your workflow and data sources. - -### Manual entry - -The most straightforward approach is adding records directly through the Twenty interface. Go to the `People` section and click the `+` button to add a new contact. Fill in their name, email, phone, and link them to their company. For companies, head to the `Companies` section and add the organization details: company name, domain, industry, and size. - -The domain field is particularly important for company identification, and the email field is essential for person identification. - -### CSV imports - -When you have existing data from spreadsheets or other systems, CSV import is your fastest option. You can prepare your data in Excel or Google Sheets, then upload it all at once. This is particularly useful when migrating from another CRM or when someone has been tracking contacts in spreadsheets. Our [Import/Export Data](/user-guide/getting-started/import-export-data) guide walks you through the process. - -### Automated data capture - -For ongoing lead generation, you can set up automated workflows that bring data directly into Twenty: - -**Website forms**: When someone fills out a form on your website, you can configure it to send the information to Twenty automatically. The form submission triggers a webhook that activates a workflow in Twenty, creating the new contact record without any manual work. - -**Integration with other systems**: If you use other business tools, you can connect them to Twenty using API calls and workflows. This lets you automatically sync data between systems: for example, bringing in new customers from your billing system or leads from your marketing platform. - -To learn more about setting up these automated data flows, check out our [Workflows](/user-guide/workflows/getting-started-workflows) section. - -### Email and calendar sync - -When you connect your mailbox and calendar to Twenty, the system can automatically create People and Companies records for people you email or meet with. If you send an email to someone who isn't already in your CRM, Twenty can create a new Person record for them. The same happens when you schedule meetings with new contacts through your calendar. - -This is particularly useful for sales and business development teams who are constantly meeting new people. Instead of manually adding every new contact, Twenty captures them automatically as you communicate. Learn how to set this up in our [Emails and Calendars](/user-guide/collaboration/emails-and-calendars) guide. - -### Reducing manual work - -Even when adding data manually, you can use workflows to streamline the process. For instance, you might set up automation that assigns new contacts to team members based on their location, or that automatically creates follow-up tasks when certain types of contacts are added. - -## Organizing your contacts - -### Keeping data unique and clean - -Twenty automatically enforces uniqueness to keep your data organized. Each person's email address serves as a unique identifier: you can't have two people with the same email. Similarly, company domains are unique, so you won't accidentally create duplicate companies. - -If your business needs other fields to be unique (like phone numbers, or reference codes), you can configure this in your data model. Head to our [Data Model](/user-guide/data-model/customize-your-data-model) section to learn how to set up additional uniqueness constraints for your specific needs. - -### Handling duplicates - -Sometimes you'll end up with duplicate records. Twenty has a merge feature for both People and Companies: you can combine duplicate records to keep your database clean without losing any information. - -To merge records, select 2 records, open the command menu `Cmd+K` on Mac, `Ctrl+K` on Windows and click `Merge Records`. - -### Creating company hierarchies - -If you work with large organizations that have subsidiaries or multiple divisions, you can create relationships between companies. Set up relationship fields between Company records to map out these connections. This helps you understand the full organizational structure you're dealing with. - -### Customizing your views - -Different team members might need to see different information. You can create custom views that show different columns for different purposes: maybe your sales team needs to see deal stages while your support team focuses on contact details. Learn more about this in our [View Management](/user-guide/crm-essentials/view-management) article. - -## Working with records - -### What you'll find in each record - -When you open a Person or Company record, you'll see all their information organized in tabs: - -- **Fields**: The basic information like name, email, phone, and any custom fields you've added -- **Relations**: Shows the connections between this record and records from other objects -- **Timeline**: A chronological view of all interactions and updates to this record -- **Tasks**: Any follow-up tasks related to this contact -- **Notes**: Team notes and observations about this person or company -- **Files**: Documents and attachments related to this record -- **Emails**: Email threads with this contact (when your team has connected their mailboxes) -- **Calendar**: Meetings and appointments with this contact - -The Email and Calendar tabs are particularly powerful: they automatically show all email exchanges and meetings that anyone on your team has had with this contact, as long as they've connected their mailbox to Twenty. You can learn more about setting this up in our [Emails and Calendars](/user-guide/collaboration/emails-and-calendars) guide. - -### Adding the fields you need - -The standard fields might not capture everything important for your business. If you need additional information: like customer segments, referral sources, or industry-specific data: you can add custom fields or modify existing ones. Head to our [Data Model](/user-guide/data-model/customize-your-data-model) section to learn how to customize your setup. - -## Managing deleted records - -When you delete a record in Twenty, it's not gone forever. Records are "soft deleted," which means they're hidden but can be restored if needed. - -To access deleted records, open the command menu `Cmd+K` on Mac, `Ctrl+K` on Windows, then click `See deleted records`. From there, you can either restore records or permanently delete them if you're sure you don't need them. - -This safety net means you can clean up your database without worrying about accidentally losing important information. - diff --git a/packages/twenty-docs/user-guide/crm-essentials/pipeline.mdx b/packages/twenty-docs/user-guide/crm-essentials/pipeline.mdx deleted file mode 100644 index cbbeb835c6..0000000000 --- a/packages/twenty-docs/user-guide/crm-essentials/pipeline.mdx +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Pipeline -info: "Track and manage your sales opportunities through customizable pipeline stages." -image: /images/user-guide/kanban-views/kanban.png -sectionInfo: "Essential CRM features for managing leads, sales, and customers" ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -## Understanding Pipelines - -A sales pipeline tracks opportunities from initial contact to closed deal. Each stage represents a step in your sales process, and opportunities move through these stages as they progress toward closing. - -Twenty includes standard sales stages like Prospecting, Qualification, Proposal, Negotiation, Closed. You can customize these stages to match your specific sales process. - -## Working with Kanban Views - -Kanban views visually map out your pipeline, where each column represents a stage and each card represents an opportunity. Each card shows key information like deal value, close date, and assigned owner at a glance. For complete details: including notes, tasks, meetings, and email history, click on any card to open the full opportunity record. - -### Moving opportunities through your pipeline - -You can move each opportunity between stages as it progresses through your sales process by dragging and dropping. Hold your click on a card and move it to the next stage. - - - -### Customizing your pipeline stages - -You can tailor your pipeline to suit your specific sales process. Stages represent values in a Select Field, so you can add, remove, or rename them as needed. - -#### Adding stages - -To add a stage, access the Select Field Settings by navigating to Settings → Data Model, selecting your object, and then the field your Kanban board depends on. - - - -#### Removing stages - -To remove a stage, hover the stage name or the `⋮` icon, click `Edit from settings` in the Select Field settings, and then click `Delete` next to the relevant stage. - - - -### Customizing the cards - -You can configure your Kanban board to display some fields and hide others. To hide a field, click on `Options` on the top right, then on `Fields` to bring up the list of options. Hover the field you want to hide to bring up the `-` button. Click on it to hide the field. - -You can also rearrange the order of fields by holding down the field name and dragging it to where you want it. - - - -### Compact view - -You can also hide all the fields and get an overview of all the opportunities at a glance. To do so, click on `Options` on the top right and turn on the toggle for `Compact view` after selecting layout in kanban view. - - - -## Advanced pipeline management - -### Automation with workflows - -Use [Workflows](/user-guide/workflows/getting-started-workflows) to automate your pipeline: -- **Automatic stage progression**: Move deals based on activities -- **Notifications**: Alert team members of stage changes -- **Task creation**: Generate follow-up tasks for each stage - -### Multiple pipelines - -You can create different pipelines for various business lines, market segments, or specialized sales teams by creating new views. Each view can show different opportunities with specific filters and stages tailored to your needs. Learn how to create those views in our [View Management](/user-guide/crm-essentials/view-management) guide. - - diff --git a/packages/twenty-docs/user-guide/crm-essentials/sales-use-cases.mdx b/packages/twenty-docs/user-guide/crm-essentials/sales-use-cases.mdx deleted file mode 100644 index d58ce1428e..0000000000 --- a/packages/twenty-docs/user-guide/crm-essentials/sales-use-cases.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Sales Use Cases -info: "Discover advanced sales capabilities that can be built using Twenty's workflow system." -image: /images/user-guide/workflows/sales-use-cases.png -sectionInfo: "Essential CRM features for managing leads, sales, and customers" ---- - - Header - - -## Advanced Sales Capabilities - -GTM teams often need advanced sales capabilities like lead scoring, data enrichment, round robin, territory assignment, automated reminders, and email sequences. While these aren't built-in features in Twenty, they can all be configured and tailored to your specific needs using our flexible workflow system. - -Visit our [Workflows section](/user-guide/workflows/getting-started-workflows) to learn how to build these automations step by step. For detailed examples, see our [Internal Automations](/user-guide/workflows/internal-automations) and [External Tool Integration](/user-guide/workflows/external-tool-integration) guides. - diff --git a/packages/twenty-docs/user-guide/crm-essentials/view-management.mdx b/packages/twenty-docs/user-guide/crm-essentials/view-management.mdx deleted file mode 100644 index b37871a1af..0000000000 --- a/packages/twenty-docs/user-guide/crm-essentials/view-management.mdx +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: View Management -info: "Create and customize views to organize your data with filters, sorting, and different layouts." -image: /images/user-guide/table-views/table.png -sectionInfo: "Essential CRM features for managing leads, sales, and customers" ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -## Layout Options - -You can display your data in three different layouts, each suited for different purposes. Custom layouts to customize what the page looks like for each type of record will be released in December 2025. - -### Default View -Each object comes with an unfiltered, unsorted, and undeletable view known as the Default view. It's named after the object's plural name, such as`All Companies`,`All People`, `All Opportunities`. - - -### List Layout -The standard table format that displays records in rows and columns. This is perfect for seeing detailed information at a glance and comparing records side by side. - -### List Group By Layout -Organizes your records by grouping them based on a select field. For example, you can group opportunities by stage, companies by locations, or any other select field. This helps you see patterns and organize related records together. - -### Kanban Layout -A visual board where each column represents a stage and each record appears as a card. This layout is ideal for managing pipelines and workflows where records move through different stages. For more details on using Kanban views for pipeline management, see our [Pipeline](/user-guide/crm-essentials/pipeline) article. - - - -## Creating New Views - -There are three ways to create a new view: - -### Using the Command Menu -Use `Cmd+K` on Mac (or `Ctrl+K` on Windows) to open the command menu, then click `Create a new view`. - -### Using the View Dropdown Menu -Click on the view dropdown menu (top left), then click `Add View` at the bottom. From this menu you can: -- Choose an icon and name for your view -- Select the layout type (List or Kanban) -- Choose the visibility (Workspace or Unlisted) - - -Important: You need to first select the List layout and then add a Group By. You cannot create a List Group By directly from there. - -- For Kanban views, select which select field to use as column headers - - - -### Creating Views from Existing Filters - -When you modify the sorting and filtering of an existing view, a `Save as new view` button appears. This lets you create a new view based on your current customizations. - - - -## Making Views Actionable - -The guidance below shows you how to customize the columns of your views. We do not recommend keeping all the columns: those views can be simplified and made actionable by adding sorting conditions and displaying only certain columns that are relevant to your specific use case. - -## Customizing Your Views - -All layouts support the same customization options: sorting, filtering, and field selection. You can make quick one-time changes by clicking directly on the column name, or use the `Options Menu` for more comprehensive editing. - - -### Quick Actions vs Options Menu - -**For one-time changes**: Click directly on column headers to sort, or use the ```Move Left```, ```Move Right``` buttons. - -**For multiple edits**: Use the `Options Menu` (top right corner) when you want to make several changes in a row. This menu gives you access to: -- **Layout selection** (List, List Group By, Kanban) -- **Grouping options** (for List Group By layout) -- **Fields management** (show/hide and reorder columns) - -### Filtering Your Data - -You can apply filters to show only the records that match your criteria. Click `Filter` in the toolbar, select a field, choose your condition, and set the value. You can add multiple filters for advanced filtering based on several conditions. - - - - -### Sorting Your Records - -Control the order of your records by clicking on any column header to sort by that field. Click again to reverse the sort order. You can apply multiple sorts for complex organization. - - - - -### Managing Fields and Columns - -You can choose which fields to display and reorder them. For quick changes, click on a column name directly. For multiple edits, use `Options Menu → Fields` where you can: -- Show or hide fields using the eye icon -- Reorder fields by dragging and dropping -- Make multiple changes efficiently in one place - - - -## Managing Your Views - -### View Visibility Options - -Views can have two visibility settings: - -- **Workspace views**: Shared with your entire team. These views appear in the main "Workspace" section of the view picker for all users. -- **Unlisted views**: Personal views that appear only in your "My unlisted views" section. While these views are hidden from other team members' view lists, they can still be accessed by anyone with the direct link. This is perfect for ad-hoc reports, experiments, or temporary filters that shouldn't clutter the shared view list. - -You can switch a view's visibility at any time by editing the view. When you change a Workspace view to Unlisted, it becomes a personal view and moves to your "My unlisted views" section. - -### View Dropdown Menu Features - -The view dropdown menu (top left) is your central hub for view management. From here you can: -- **Edit view names and icons**: Click the three dots next to any view -- **Change view visibility**: Switch between Workspace and Unlisted -- **Reorder views**: Drag and drop views to organize them by priority -- **Save views as favorites**: Favorites appear just under Settings for quick access - - -### Editing and Deleting Views - -To modify or remove views, open the view dropdown menu and hover over the view you want to change. Click the three dots that appear to access edit and delete options. - - - -### Favorites and Organization - -Views saved as favorites appear just under Settings in your navigation, giving you instant access to your most important views. Use the view dropdown menu to organize your views by dragging them into the order that works best for your workflow. - -For more advanced data organization, see our [Data Model section](/user-guide/data-model/customize-your-data-model) to learn about customizing fields and objects. - diff --git a/packages/twenty-docs/user-guide/dashboards/capabilities/dashboards.mdx b/packages/twenty-docs/user-guide/dashboards/capabilities/dashboards.mdx new file mode 100644 index 0000000000..2a3012d0c3 --- /dev/null +++ b/packages/twenty-docs/user-guide/dashboards/capabilities/dashboards.mdx @@ -0,0 +1,68 @@ +--- +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 navigation +2. Click **+ 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 **+ Add Tab** +2. Name your tab (e.g., "Pipeline Overview", "Team Performance") +3. Add widgets to the tab + +### Duplicating Tabs +1. Click on the tab you want to duplicate +2. Click the **Duplicate** button in the side panel + +## Dashboard Layout + +### Arranging Widgets +- Drag and drop to position +- Resize for emphasis +- Group related charts together + +### Duplicating a Dashboard +1. Exit edit mode (view mode only) +2. Open the command bar with **Cmd + K** (or **Ctrl + K** on Windows) +3. Select **Duplicate 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). + + +**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. + + + +**Coming soon**: Dashboard-level filters will allow you to apply filters across all widgets at once, making it faster to explore your data. + + diff --git a/packages/twenty-docs/user-guide/dashboards/capabilities/widgets.mdx b/packages/twenty-docs/user-guide/dashboards/capabilities/widgets.mdx new file mode 100644 index 0000000000..59066b6759 --- /dev/null +++ b/packages/twenty-docs/user-guide/dashboards/capabilities/widgets.mdx @@ -0,0 +1,112 @@ +--- +title: Widgets +description: Explore the widget types and visualization options in Twenty. +--- + +## Available Widgets + +Twenty provides various widget types to visualize your CRM data. + +### Bar Charts +Display data as horizontal or vertical bars. + +**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 + + +**Display limits**: Bar charts can show a maximum of 100 bars (horizontal) or 50 bars (vertical). 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). + + +### Pie Charts +Show proportions of a whole. + +**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 + +### Line Charts +Display trends over time. + +**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 + +### Number Metrics +Display single key values prominently. + +**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. + +### iFrames +Embed external tools and content directly in your dashboard. + +**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 + + + +**Coming soon**: Gauge charts and tables are not yet available but are on our roadmap. + + +## Configuring Widgets + +### Data Source +1. Select the object to visualize (Opportunities, People, etc.) +2. Choose the metric to display (count, sum, average) +3. Apply filters to focus on specific data + +### Grouping +Group data by: +- Fields (stage, owner, industry) +- Time periods (day, week, month, quarter) +- Custom segments + +### Styling +Customize your charts with: +- Colors and themes +- Labels and legends +- Size and positioning + +### Duplicating Widgets + +1. Click on the widget +2. Open **Options** +3. Click **Duplicate widget** + diff --git a/packages/twenty-docs/user-guide/dashboards/how-tos/dashboards-faq.mdx b/packages/twenty-docs/user-guide/dashboards/how-tos/dashboards-faq.mdx new file mode 100644 index 0000000000..ff946ffaf3 --- /dev/null +++ b/packages/twenty-docs/user-guide/dashboards/how-tos/dashboards-faq.mdx @@ -0,0 +1,59 @@ +--- +title: Dashboards FAQ +description: Frequently asked questions about dashboards in Twenty. +--- + + + + No, dashboards are currently visible to everyone with access to your Twenty workspace. Private dashboards are not yet available. + + + + 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. + + + + Exporting dashboards is not available at the moment. This feature is on our roadmap. + + + + No, sharing dashboards with users outside your Twenty workspace (non-Twenty users) is not currently supported. + + + + Open the dashboard you want to favorite, then click the star icon. Favorites are personal—they won't affect other users. + + + + - **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 + + + + Bar charts have display limits: 100 bars for horizontal charts, 50 for vertical. If your data exceeds this, add filters to narrow down the results or change the grouping (e.g., group by week instead of day). + + + + Dashboard-level filters are not available yet, but this feature is on our roadmap. Currently, you need to apply filters to each widget individually. + + + + Not yet. Gauge charts and tables are on our roadmap and will be added in a future release. + + + + 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** + + + + 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 + + + diff --git a/packages/twenty-docs/user-guide/dashboards/overview.mdx b/packages/twenty-docs/user-guide/dashboards/overview.mdx new file mode 100644 index 0000000000..9923ba7bd5 --- /dev/null +++ b/packages/twenty-docs/user-guide/dashboards/overview.mdx @@ -0,0 +1,71 @@ +--- +title: Dashboards +description: Learn the basics of reporting and dashboards in Twenty. +image: /images/user-guide/reporting/pie-chart.png +--- + + + Dashboards + + +## Understanding Dashboards + +Dashboards in Twenty provide a visual way to track your key performance metrics and gain insights from your CRM data. + +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 +- Number metrics +- iFrames + + +**Current limitations**: +- Exporting dashboards and sharing with external users (non-Twenty users) are not available at the moment. +- Gauge charts and tables are not yet available. + + +## 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) +- [Dashboards FAQ](/user-guide/dashboards/how-tos/dashboards-faq) diff --git a/packages/twenty-docs/user-guide/data-migration/capabilities/error-handling.mdx b/packages/twenty-docs/user-guide/data-migration/capabilities/error-handling.mdx new file mode 100644 index 0000000000..cde8faeb56 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/capabilities/error-handling.mdx @@ -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 + + + + +## 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 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 the size of your file to 10,000 records** per file + diff --git a/packages/twenty-docs/user-guide/data-migration/capabilities/field-mapping.mdx b/packages/twenty-docs/user-guide/data-migration/capabilities/field-mapping.mdx new file mode 100644 index 0000000000..bce4fe702f --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/capabilities/field-mapping.mdx @@ -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 + +**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. + +### 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) + +**Fields must exist before import.** The import creates records, not fields. Create custom fields under **Settings → Data Model** before importing. + +## 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. + + + +## Data Format Requirements + +**Some fields have special syntax.** We recommend downloading the sample file before preparing your import to see the expected syntax for each field type. + +### 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. + +If you provide an `id`, it must be in UUID format (e.g., `c776ee49-f608-4a77-8cc8-6fe96ae1e43f`). + + +### 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. + +New select options will not be created automatically by the import. They must be added under **Settings → Data Model** before importing. + + +**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. + + + +### 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. +New select options will not be created automatically by the import. They must be added under **Settings → Data Model** before importing. +### 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 + + + + diff --git a/packages/twenty-docs/user-guide/data-migration/capabilities/file-formats.mdx b/packages/twenty-docs/user-guide/data-migration/capabilities/file-formats.mdx new file mode 100644 index 0000000000..afb3de0a0e --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/capabilities/file-formats.mdx @@ -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 + +For very large migrations (100,000+ records), the API is significantly faster and more reliable than CSV imports. + diff --git a/packages/twenty-docs/user-guide/data-migration/capabilities/import-relations.mdx b/packages/twenty-docs/user-guide/data-migration/capabilities/import-relations.mdx new file mode 100644 index 0000000000..549cea0298 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/capabilities/import-relations.mdx @@ -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. + +**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. + +## 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, Tasks, or Activities 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. + + + +**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. + + + +**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. + + + +### 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 + +Many to Many relations are planned for H1 2026. + +## Linking Records During Import + +**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. + +### 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) + +The import will fail if a reference is made to a record that does not exist. + +### 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 | + +**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. + +We recommend using `domain` for Companies and `email` for People, as these are human-readable and easy to maintain in spreadsheets. + +**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. + +## Import Order Rule + + +**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. + diff --git a/packages/twenty-docs/user-guide/data-migration/capabilities/uniqueness-constraints.mdx b/packages/twenty-docs/user-guide/data-migration/capabilities/uniqueness-constraints.mdx new file mode 100644 index 0000000000..68e1dd18a3 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/capabilities/uniqueness-constraints.mdx @@ -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) | + +The `id` field is Twenty's internal identifier, auto-generated for each record. It uses UUID format (e.g., `c776ee49-f608-4a77-8cc8-6fe96ae1e43f`). + +## 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 + +The field name `id` is reserved for Twenty's internal ID. Use a different name like `externalId` or `legacyId` for external identifiers. + +## 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. +To **update existing records**, it is recommended to **only match one unique field**. + +### Soft-Deleted Records + + +**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. + + +## 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 + + + +## 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 + diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/export-your-data.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/export-your-data.mdx new file mode 100644 index 0000000000..6fa7fe07fe --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/export-your-data.mdx @@ -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) + +For larger exports (20,000+ records), use filters to export in batches or use the [API](/developers/extend/capabilities/apis). + +### 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 + +**Create a dedicated export view.** Save a view specifically configured for exports so you don't need to reconfigure each time. + +## 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/capabilities/apis) + +## 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 +Correct columns are visible +Filters are set correctly (or removed for full export) +You have Export permission + +## FAQ + + + + Only visible columns are exported. Add the columns you need via **Options → Fields** before exporting. + + + + Check your filters. The export only includes records matching your current view filters. Remove filters to export all records. + + + + Not in a single export. Use filters to export in batches, or use the API for larger datasets. + + + + CSV (Comma Separated Values). Opens in Excel, Google Sheets, or any spreadsheet application. + + + + 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. + + + + Not directly through the UI. Use the API to build automated export workflows. + + + +## 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/capabilities/apis) — build custom export workflows diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/fix-import-errors.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/fix-import-errors.mdx new file mode 100644 index 0000000000..7625b0fbc9 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/fix-import-errors.mdx @@ -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 + +**Fix errors in the UI.** You don't need to go back to your spreadsheet. Edit cells directly during import to save time. + +## 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 + + +**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. + + +### 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 + + +**Soft-deleted records count toward uniqueness.** + +Check Command Menu → See deleted records. Records there still enforce uniqueness. Permanently delete them or restore and update. + + +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) +``` + +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. + +#### Date +**Problem:** Unrecognized date format +**Solution:** Use consistent format throughout file + +``` +✓ 2024-03-15 (YYYY-MM-DD - recommended) +✓ 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. + +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. + +### 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 + + +**Import will fail if a reference is made to a non-existent record.** + +Always import parent objects before child objects. + + +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 + +The CSV import creates records, not fields. All fields must exist before importing. + +--- + +## 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 + + +**Users must accept invitations before importing.** + +If a user hasn't accepted their invitation, records referencing them will have empty user relations. + + +--- + +## Pre-Import Checklist + +Avoid errors by checking these before importing: + +### File Requirements +File is CSV, XLSX, or XLS format +File has fewer than 10,000 records +File uses UTF-8 encoding + +### Data Quality +No duplicate emails (for People) +No duplicate domains (for Companies) +All dates use consistent format +All domains use `https://domain.com` format + +### Field Formats +Boolean fields use `TRUE` or `FALSE` (uppercase) +Select fields use API names, not display labels +Phone fields have all required columns +Currency fields have both Amount and Currency Code + +### Relations +Parent records imported before child records +Relation columns reference existing records +Domain format matches Twenty's format exactly + +### Data Model +All custom fields exist in Settings → Data Model +Select options exist before importing + +--- + +## 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) diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/import-companies-via-csv.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/import-companies-via-csv.mdx new file mode 100644 index 0000000000..89edd6f2b2 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/import-companies-via-csv.mdx @@ -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 + +Your file is CSV, XLSX, or XLS format + + +File has fewer than 10,000 records + + +No duplicate domains in your file + + +All custom fields exist in **Settings → Data Model** + + + +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). + + +## 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 + + +**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. + + +**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 +``` + + +**Pro tip:** Click **Download sample file** during import to see the exact column names Twenty expects. + + +## 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) + + + +## 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 + + +Select options use **API names**, not display labels. Check **Settings → Data Model** → Enable **Advanced mode** to see API names. + + +## 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 + + + + Domain is a unique identifier in Twenty. This prevents duplicate companies and ensures email sync correctly links emails to the right company. + + + + You can leave the domain empty. However, we recommend adding domains when possible for better data quality and automatic email linking. + + + + Yes! You can import companies first, then import People later and link them using the company domain. + + + + If you include a unique identifier (domain or id) that matches an existing company, Twenty updates that company instead of creating a duplicate. + + + + Either remove the duplicate from your file, or include the company's `id` to update the existing record instead. + + + +## 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) diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/import-contacts-via-csv.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/import-contacts-via-csv.mdx new file mode 100644 index 0000000000..4d80e7abcf --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/import-contacts-via-csv.mdx @@ -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. **Import Companies first** if you want to link People to Companies. + +## Before You Start + +### Prerequisites Checklist + +Your file is CSV, XLSX, or XLS format + + +File has fewer than 10,000 records + + +No duplicate email addresses in your file + + +**Companies imported first** (if linking People to Companies) + + +All custom fields exist in **Settings → Data Model** + + + +**Import Companies Before People** + +If you want to link People to Companies, import Companies first. The Company must exist before you can reference it. + + +## 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` | + + +**Use Domain URL format** (`https://acme.com`), not the label. This matches how Companies are stored in Twenty. + + +### 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 +``` + + +**Pro tip:** Click **Download sample file** during import or export a few existing People to see the exact column names Twenty expects. + + +## 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 | + + + +### 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 + + +**Map only ONE unique identifier for relations.** + +Don't map both `companyId` AND `companyDomain`. Choose one—preferably domain since it's human-readable. + + +## 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 + + +Select options use **API names**, not display labels. Check **Settings → Data Model** → Enable **Advanced mode** to see API names. + + +## 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 + + + + Email is a unique identifier in Twenty. This prevents duplicate contacts and ensures email sync correctly links emails to the right person. + + + + You can leave the email empty. However, we recommend adding emails when possible for better data quality and email sync functionality. + + + + 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. + + + + Import Companies first, then import People. The Company must exist before you can reference it. + + + + 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. + + + + The Company you're referencing doesn't exist. Either import the Company first, or check that the domain/ID exactly matches an existing Company. + + + +## 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) diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/import-data-via-api.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/import-data-via-api.mdx new file mode 100644 index 0000000000..f90be44536 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/import-data-via-api.mdx @@ -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** | + +For datasets in the hundreds of thousands, the API is significantly faster and more reliable than multiple CSV imports. + +## 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 | + + +**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. + + +## 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 + + +**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. + + +### 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/capabilities/apis) | +| **REST** | Simple CRUD operations, familiar REST patterns | [API Docs](/developers/extend/capabilities/apis) | + +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 + + + + 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. + + + + Yes! Use update mutations (GraphQL) or PUT/PATCH requests (REST) with the record's `id`. + + + + Query for existing records first using unique identifiers (email, domain). Update if exists, create if not. + + + + Yes, use delete mutations (GraphQL) or DELETE requests (REST). + + + + Not currently, but both APIs work with any HTTP client in any language. + + + +## API Documentation + +For full implementation details, code examples, and schema reference: + +- [API Documentation](/developers/extend/capabilities/apis) diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv.mdx new file mode 100644 index 0000000000..26e66f7c90 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv.mdx @@ -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. + +**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. + +## 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) + + +**If the parent record doesn't exist, the import will fail.** + +Always verify that Companies are imported before importing People with company references. + + +## 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 | + +**Recommended:** Use `domain` for Companies and `email` for People. These are human-readable and easy to verify in your spreadsheet. + +### 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` | + + +**Domain format matters!** + +Use `https://domain.com` (not just `domain.com`). This matches how Twenty stores Company domains and prevents matching errors. + + +### 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 + + + + 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 + + + + Yes! Include the child record's unique identifier (e.g., `email` for People) and the new relation value. The import will update the relation. + + + + Many-to-Many relations are not yet supported for import. This is planned for H1 2026. + + + + Relations pointing to multiple object types are not yet supported for import/export. This is on our roadmap. + + + + 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 + + + + 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) + + + + +**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. + + +## 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) diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/migrating-from-other-crms.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/migrating-from-other-crms.mdx new file mode 100644 index 0000000000..5b261ff33b --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/migrating-from-other-crms.mdx @@ -0,0 +1,276 @@ +--- +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. + +Views, workflows, and permissions must be recreated manually after migration. Plan time for this configuration work. + +## 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.) + +Keep this mapping document handy during import—you'll reference it when mapping columns. + +## 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.) + + +**Fields must exist before import.** + +The CSV import creates records, not fields. Create all custom fields in Settings → Data Model before importing. + + +### Invite Your Team + + +**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. + + +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 | + + +**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. + + +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 + + +**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. + + +### 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 → 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 +All records imported (compare counts with source system) +Relations working correctly (People linked to Companies) +User assignments mapped correctly (Owner, Assignee) +Custom fields populated +No unexpected duplicates + +### Configuration +Views recreated +Workflows recreated and tested +Roles and permissions configured +Email/calendar sync connected + +### Team Readiness +Team trained on new system +Old CRM access plan decided (keep for reference? When to disable?) + +## FAQ + + + + Not currently. Workflows must be recreated manually in Twenty. + + + + 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. + + + + 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. + + + + 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. + + + +## Need Help? + +For complex migrations or large datasets: +- **Guided setup:** Book a 4-hour onboarding pack +- **Full migration service:** Our partners can handle the entire migration + +Contact [contact@twenty.com](mailto:contact@twenty.com) or explore our [Implementation Services](/user-guide/getting-started/capabilities/implementation-services). diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/migrating-from-self-hosted-to-cloud.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/migrating-from-self-hosted-to-cloud.mdx new file mode 100644 index 0000000000..4694aef5c0 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/migrating-from-self-hosted-to-cloud.mdx @@ -0,0 +1,165 @@ +--- +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. + +Views, workflows, and roles must be recreated manually after migration. Plan time for this configuration work. + +## 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.) + +Take screenshots of your self-hosted data model for reference, or keep both instances open side by side. + +## Step 3: Invite All Users + + +**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. + + +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 +``` + +Use the same email addresses that users used to accept their cloud workspace invitation. + +## 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 → 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 + +All data imported successfully +Relations between objects working correctly +User assignments (Owner, Assignee) mapped correctly +Views recreated +Workflows recreated and tested +Roles and permissions configured +Email/calendar sync reconnected +API integrations updated with new keys + +## FAQ + + + + Not currently. Workflows must be recreated manually in your cloud instance. + + + + 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. + + + + 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. + + + + Records referencing that user will fail to import or the relation will be empty. Ensure all users accept invitations before importing data. + + + +## Need Help? + +For complex migrations or large datasets, contact us at [contact@twenty.com](mailto:contact@twenty.com) or explore our [Implementation Services](/user-guide/getting-started/capabilities/implementation-services). + diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/prepare-your-csv-files.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/prepare-your-csv-files.mdx new file mode 100644 index 0000000000..146ffa1c16 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/prepare-your-csv-files.mdx @@ -0,0 +1,239 @@ +--- +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 | + +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). + +## 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 + +**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. + +## 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 + +**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. + +## 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` +- `MM/DD/YYYY`: `03/15/2024` +- `DD/MM/YYYY`: `15/03/2024` +- 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` + +Lowercase `true` or `false` will not work. + +### 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") + +New select options are not created automatically. Add them in **Settings → Data Model** before importing. + +### 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) + + +**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. + + +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: + +File is CSV, XLSX, or XLS format +File has fewer than 10,000 records +Encoding is UTF-8 +No duplicate emails (for People) or domains (for Companies) +Dates use consistent format throughout +Domains use `https://domain.com` format +Boolean fields use `TRUE` or `FALSE` (uppercase) +Select fields use API names, not display labels +All custom fields exist in Settings → Data Model +Parent records imported before child records +Relation columns reference existing records + +## 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) diff --git a/packages/twenty-docs/user-guide/data-migration/how-tos/update-existing-records-via-import.mdx b/packages/twenty-docs/user-guide/data-migration/how-tos/update-existing-records-via-import.mdx new file mode 100644 index 0000000000..f2441bebbb --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/how-tos/update-existing-records-via-import.mdx @@ -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) | + + + +**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"]` + + + +## 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 + +**Why export first?** The exported file has the correct format, includes unique identifiers, and maps automatically during import. + +### 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 +``` + + +**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. + + +## 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 | + +**Use only ONE unique identifier.** Don't map both `email` AND `id`. This can cause confusion and errors. + +### 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 + + + + 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. + + + + Yes, leave the cell empty in your CSV. The import will clear that field's value on the existing record. + + + + Fields not in your import file remain unchanged on existing records. Only fields you include are updated. + + + + Yes! Include the relation's unique identifier (e.g., `companyDomain`) and map it to the relation field. The relation will be updated. + + + + During the import review step, Twenty shows you how many records will be updated vs. created based on unique identifier matches. + + + + There's no automatic undo. We recommend exporting your data as a backup before making bulk updates. + + + +## 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) diff --git a/packages/twenty-docs/user-guide/data-migration/overview.mdx b/packages/twenty-docs/user-guide/data-migration/overview.mdx new file mode 100644 index 0000000000..e75d133428 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-migration/overview.mdx @@ -0,0 +1,84 @@ +--- +title: Data Migration +description: Import and export your CRM data via CSV files or API. +image: /images/user-guide/import-export-data/cloud.png +--- + +import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; + + + Data Migration + + +## 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 | + +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. + +## 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). + +**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**. + +### 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. + +**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. + + +**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. + + +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 + +**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. + +**Export limits**: Up to 20,000 records per export. + +## 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) diff --git a/packages/twenty-docs/user-guide/data-model/fields.mdx b/packages/twenty-docs/user-guide/data-model/capabilities/fields.mdx similarity index 65% rename from packages/twenty-docs/user-guide/data-model/fields.mdx rename to packages/twenty-docs/user-guide/data-model/capabilities/fields.mdx index 1c228ba807..00ea5e0e26 100644 --- a/packages/twenty-docs/user-guide/data-model/fields.mdx +++ b/packages/twenty-docs/user-guide/data-model/capabilities/fields.mdx @@ -1,15 +1,10 @@ --- title: Fields -info: "Understand the role of fields and how to handle them." -image: /images/user-guide/fields/field.png -sectionInfo: Flexible data model designed to support your unique business processes +description: Understand the role of fields and how to manage them. --- import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - Header - ## About Fields @@ -23,7 +18,7 @@ For example, `First Name` and `Last Name` are standard fields in the `People` ob 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. +You can also customize the options of the standard `SELECT` type fields, for example the options for the `Stage` on Opportunities. @@ -33,15 +28,40 @@ Custom fields can be added to any object. You can store text, numbers, dates, dr For instance, a custom field for SpaceX could be `Rocket Active Status`, indicating if a rocket is operational. - + + +## 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 `Add Field`. - 4. Choose a field name and type that suits your requirements. Consider adding a field description for better understanding. +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 `Add 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`. @@ -51,7 +71,7 @@ Your newly created field is now available within the application's fields. To di -## Deactivate a field +## 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. @@ -84,9 +104,8 @@ If you get an error when setting uniqueness, check for duplicate values in your ## Field Configuration Best Practices ### Naming Conventions and Limitations -- **Relation field names cannot be updated** after creation (impacts API structure) - **Singular and plural named must be distinct**: Our GraphQL API needs distinct names for mutations -- **Protected field names**: some names are reserved for system usage (e.g., ```Type```) +- **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 @@ -97,8 +116,3 @@ If you get an error when setting uniqueness, check for duplicate values in your ### 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. - -### Relation Fields -- **Connect objects together**: Relation fields link records from different objects. For detailed information on creating and managing relationships, see our [Relation Fields](/user-guide/data-model/relation-fields) article. - - diff --git a/packages/twenty-docs/user-guide/data-model/capabilities/objects.mdx b/packages/twenty-docs/user-guide/data-model/capabilities/objects.mdx new file mode 100644 index 0000000000..f5696952a5 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-model/capabilities/objects.mdx @@ -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. + + + +### 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. + +### Company + +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. + + + +### 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 disabled). + + + +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 +3. Click the toggle to deactivate it +4. 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. Look for deactivated objects (they'll be grayed out) +3. Click the toggle to reactivate it +4. 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 diff --git a/packages/twenty-docs/user-guide/data-model/capabilities/relation-fields.mdx b/packages/twenty-docs/user-guide/data-model/capabilities/relation-fields.mdx new file mode 100644 index 0000000000..accecc4658 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-model/capabilities/relation-fields.mdx @@ -0,0 +1,86 @@ +--- +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. + + + +Similarly, a Project (on the "one" side) could receive links from multiple People, multiple Companies, and multiple Notes. + + + + +**Import/Export limitation**: Relations pointing to multiple object types are not yet supported for CSV import/export. This is on our roadmap. + + +### 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 is not yet supported.** + +This relation type is planned for H1 2026. As a workaround, create an intermediate "junction" object (e.g., "Project Assignments") that has Many-to-One relations to both objects. + + +## Creating a Relation Field + +1. Go to **Settings → Data Model** +2. Select the object where you want to add the relation +3. Click **+ Add 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 diff --git a/packages/twenty-docs/user-guide/data-model/creating-records.mdx b/packages/twenty-docs/user-guide/data-model/creating-records.mdx deleted file mode 100644 index 6438242d45..0000000000 --- a/packages/twenty-docs/user-guide/data-model/creating-records.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Table Views -info: "Learn how to customize and navigate Table Views." -image: /images/user-guide/table-views/table.png -sectionInfo: Discover how to use standard and custom objects in your workspace. ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -## About Table Views - -Table views are visual representations of data structured in rows and columns. - -## Create record - -Add records as needed, without limits. To add a record, you can either click on the **+** button at the top right of the screen or at the top of the record **Name** column. - -Enter the record name then press `Enter` to save. To edit a record name, click on its name on its detail page. - - - - -## Delete record - -**Index View:** To delete a record, select the checkbox next to the record and click the delete button in the top right corner. - -**Record Page:** Tap the `⋮` icon in the top right corner, then select delete. - - - - -## Add a Custom Field - -To create a custom field, click the **+** button at the right end of the table columns and select **Customize fields**. - - - -You can also do it by navigating to **Settings** > **Data Model** > **People**. Click on **Add Field**. Choose a field name and type. The new field will be available in the app. - diff --git a/packages/twenty-docs/user-guide/data-model/customize-your-data-model.mdx b/packages/twenty-docs/user-guide/data-model/customize-your-data-model.mdx deleted file mode 100644 index 5f3d2dd17d..0000000000 --- a/packages/twenty-docs/user-guide/data-model/customize-your-data-model.mdx +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Customize your data model -info: "Learn how to design and create a data model that reflects how you operate." -image: /images/user-guide/fields/custom_data_model.png -sectionInfo: Flexible data model designed to support your unique business processes ---- - - Header - - -## What is a data model? -A data model is the structure that defines how information is organized in your CRM. It determines what objects exist (like companies, people, or opportunities), what properties they have (those are the fields), and how they relate to each other. You can think of it as the map of your customer data. - -## Why should you customize your data model? -Every business works differently. Being able to fully customize your data model means you can shape Twenty around your processes instead of forcing yours into a rigid system. -Twenty offers the flexibility you need to shape the data model that will best support your day-to-day. You can create as many custom objects and fields as you need, the price won't change. - -## Tips to design your data model -There is rarely only one way to build a data model. Below are a few tips to help you build yours. - -**1. Start with your core objects.** -Identify the main concepts you work with (e.g. Companies, People, Opportunities). Those three objects are already available as they are used very often. But think of any other you might need. -Example: Stripe would need an object ```Subscriptions```, Airbnb would need an object ```Trips```, a start-up accelerator an object ```Batches```. - -**2. Use fields for variations, not new objects.** -If something is just a characteristic of an existing object (e.g. ```Industry``` for a Company, or ```Status``` for an Opportunity), make it a field. Fields are best for categories, labels, and attributes. - -**3. Create a new object when it stands on its own.** -If the concept has its own lifecycle, properties, or relationships, it usually deserves an object. For example: -- **Projects** that have their own deadlines, owners, and tasks -- **Subscriptions** that connect companies, products, and invoices -- **Events** that involve many attendees and follow-up actions - -These go beyond a single field because they carry their own data and relationships. - -**4. Create an object when the number of related records is open-ended.** -If something can be linked multiple times and you don’t know how many, it’s better as its own object. For instance, instead of creating fields like `Product 1`, `Product 2`, etc., define a `Product` object and relate it to the original record. This way, you can support 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, repeated records, or relationships that don’t fit neatly. - - -### Special note on People, Companies and Opportunities - -- **`People`, `Companies` and `Opportunities` are the only objects from where you can access the emails and meetings synchronized from your mailbox / calendar.** We recommend using those as much as possible. If you need to create categories of `People` or `Companies`, use fields rather than new objects. - - Example: it is best to use the `People` object for both prospects and partners, adding a field called `Person Type`. Avoid creating a `Partner` object, since you wouldn’t be able to access email threads from it. Instead, create different views under `People`: one showing partners, another showing prospects. -- Given the point above, it’s fine to have fields that don’t apply to every record. For example, under `People` you might add a `Referral Link` field that is only relevant when `Person Type = Partner`. That’s okay: you can hide this field from views where it is not needed. - - -### Questions to guide your choice - -Ask yourself: -- Is this just a property of something I already have, or does it need its own properties? -- Will I ever need to track multiple of these per record, without knowing how many in advance? -- Does this concept connect to several different objects, not just one? -- Will it have its own lifecycle (e.g. stages, start/end dates)? - -If the answer is “yes” to one or more of these, it’s probably time for a new object. - - -## Want some help? -Our team can assist you designing and creating the data model you need. Discover our Onboarding Pack [here](https://twenty.com/onboarding-packages). - - - diff --git a/packages/twenty-docs/user-guide/data-model/data-model-faq.mdx b/packages/twenty-docs/user-guide/data-model/data-model-faq.mdx deleted file mode 100644 index d9d790eff1..0000000000 --- a/packages/twenty-docs/user-guide/data-model/data-model-faq.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Data Model FAQ -info: "Frequently asked questions about data model configuration, limitations, and upcoming features." -image: /images/user-guide/what-is-twenty/faq.png -sectionInfo: Flexible data model designed to support your unique business processes ---- - - Header - - -## Object Management - - - -Not yet. Object ordering in the navigation is currently fixed, but this feature is planned for a future release. - - - -All active objects appear in the navigation. You can deactivate objects you don't need under **Settings → Data Model**. - - - -You can deactivate any standard objects but you cannot hard delete them. - - - -## Field Capabilities - - - -Formula fields are coming in **Q1 2026**. In the meantime, you can use workflows to calculate and update field values automatically. - - - -Nested fields are coming in **Q1 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. - - - -Relation field names impact the API structure and cannot be changed after creation. If you need to rename a relation field, you'll need to create a new one and delete the old one. - - - -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. - - - -Certain field names like `Type` or `Application` are reserved for system use. Choose alternative names like `Category` or `Classification` instead. - - - -## Advanced Features - - - -Many-to-many relationships are coming in **Q1 2026**. Currently, create an intermediate object with two 1-to-many relationships as a workaround. - - - -Morph Many relationships allow one object to relate to multiple different object types through a single field. For example, an Opportunity can relate to either a Person or a Company. This feature is now available - learn more in our [Relation Fields](/user-guide/data-model/relation-fields#morph-many-relationships) documentation. - - - -Field reordering will be available with custom layouts in **Q4 2025**. Currently, fields appear in the alphabetical order. - - - -## Access and Permissions - - - -You can access your Data Model under **Settings → Data Model**. - - - -Reach out to your workspace administrator. Data model access is usually restricted to administrators only. - - - -You can create as many custom objects and fields as you need - the price won't change. - - - -## Need More Help? - -Check our [implementation services](/user-guide/getting-started/implementation-services) to get help with complex data model design. - - diff --git a/packages/twenty-docs/user-guide/data-model/how-tos/create-custom-fields.mdx b/packages/twenty-docs/user-guide/data-model/how-tos/create-custom-fields.mdx new file mode 100644 index 0000000000..af78fcf367 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-model/how-tos/create-custom-fields.mdx @@ -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 **+ Add 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 + + +**Use API names for imports.** Enable **Advanced mode** in Settings to see API names. See [Field Mapping](/user-guide/data-migration/capabilities/field-mapping). + + +### 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. + + +If duplicates exist (including in deleted records), you'll get an error. Clean up duplicates first. + + +### 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 diff --git a/packages/twenty-docs/user-guide/data-model/how-tos/create-custom-objects.mdx b/packages/twenty-docs/user-guide/data-model/how-tos/create-custom-objects.mdx new file mode 100644 index 0000000000..69cc221df5 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-model/how-tos/create-custom-objects.mdx @@ -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. + + +**Not sure if you need an object or a field?** See [Understanding Your Data Model](/user-guide/data-model/overview) for guidance. + + +## Steps + +1. Go to **Settings → Data Model** +2. Click **+ New 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 **+ Add 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** +2. Toggle the object off + +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 diff --git a/packages/twenty-docs/user-guide/data-model/how-tos/create-relation-fields.mdx b/packages/twenty-docs/user-guide/data-model/how-tos/create-relation-fields.mdx new file mode 100644 index 0000000000..f18a7f3989 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-model/how-tos/create-relation-fields.mdx @@ -0,0 +1,59 @@ +--- +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. + + +**Relation names cannot be changed after creation** (they affect the API). Plan your names carefully. + + +## 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 **+ Add 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. + +## Deleting a Relation + +1. Go to **Settings → Data Model** +2. Find the relation field +3. Click **⋮ → Deactivate** + +Links are preserved but hidden. Reactivate to restore. + + +**Deleting a relation doesn't delete records.** Only the link between them is removed. + + +## 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 diff --git a/packages/twenty-docs/user-guide/data-model/how-tos/customize-your-data-model.mdx b/packages/twenty-docs/user-guide/data-model/how-tos/customize-your-data-model.mdx new file mode 100644 index 0000000000..87b9eafce5 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-model/how-tos/customize-your-data-model.mdx @@ -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 diff --git a/packages/twenty-docs/user-guide/data-model/how-tos/data-model-faq.mdx b/packages/twenty-docs/user-guide/data-model/how-tos/data-model-faq.mdx new file mode 100644 index 0000000000..3d86b25556 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-model/how-tos/data-model-faq.mdx @@ -0,0 +1,154 @@ +--- +title: Data Model FAQ +description: Frequently asked questions about Twenty's data model. +--- + +## Object Management + + + +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. + + + +No, standard objects cannot be deleted. You can only deactivate them, which hides them from the interface but preserves the data. + + + +You can create as many custom objects and fields as you need — the price doesn't change. + + + +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. + + + +Yes, you can change the icon for both standard and custom objects in **Settings → Data Model**. + + + +Not yet. Object ordering in the navigation is currently fixed, but this feature is planned for a future release. + + + +All active objects appear in the navigation. You can deactivate objects you don't need under **Settings → Data Model**. + + + +## Field Capabilities + + + +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. + + + + +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. + + + +Certain field names like `Type` or `Application` are reserved for system use. Choose alternative names like `Category` or `Classification` instead. + + + +- 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 + + + +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. + + + +- **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) + + + +Formula fields are coming in **Q1 2026**. In the meantime, you can use workflows to calculate and update field values automatically. + + + +Nested fields are coming in **Q1 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. + + + +Field reordering will be available with custom layouts in **Q4 2025**. Currently, fields appear in alphabetical order. + + + +## Relations + + + +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. + + + +Many-to-many relationships are coming in **H1 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) + + + +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). + + + +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. + + + +When you delete a record, the relation link is removed from the related records. The related records themselves are not deleted. + + + +While technically possible, circular relations (A → B → C → A) should be avoided as they can cause confusion and potential performance issues. + + + +## Access and Permissions + + + +Go to **Settings → Data Model** to view and edit all your objects and fields. + + + +Reach out to your workspace administrator. Data model access is usually restricted to administrators only. + + + +## Data Management + + + +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. + + + +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). + + + +Currently, there's no built-in export for data model configuration. Contact support if you need to migrate your data model between workspaces. + + + +## Need More Help? + +Check our [Implementation Services](/user-guide/getting-started/capabilities/implementation-services) for help with complex data model design. diff --git a/packages/twenty-docs/user-guide/data-model/objects.mdx b/packages/twenty-docs/user-guide/data-model/objects.mdx deleted file mode 100644 index 3d6fb40c39..0000000000 --- a/packages/twenty-docs/user-guide/data-model/objects.mdx +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Objects -info: "Learn about standard objects and how to create custom ones for your business needs." -image: /images/user-guide/objects/objects_orange.png -sectionInfo: Flexible data model designed to support your unique business processes ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -## 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. - - - -### 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. - -### Company - -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. - -## 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. - - - -### 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 disabled). - - - - -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." - - -The singular and plural names must be different. This is required for our GraphQL API to work properly. - - - - -4. Once you create your custom object, you'll be able to manage it. You can edit the name, icon and description, view the different fields, and add more fields. - - - -**Note:** If you're not sure whether a new object or field is needed, check [this article](/user-guide/data-model/customize-your-data-model) for guidance on designing your data model. - - diff --git a/packages/twenty-docs/user-guide/data-model/overview.mdx b/packages/twenty-docs/user-guide/data-model/overview.mdx new file mode 100644 index 0000000000..06910a9684 --- /dev/null +++ b/packages/twenty-docs/user-guide/data-model/overview.mdx @@ -0,0 +1,169 @@ +--- +title: Data Model +description: Learn what a data model is and how to design one that fits your business. +image: /images/user-guide/fields/custom_data_model.png +--- + + + Data Model + + +## 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** — attached notes on 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 + + +**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. + + +**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: + +Is this just a property of something I already have, or does it need its own properties? +Will I ever need to track multiple of these per record, without knowing how many? +Does this concept connect to several different objects, not just one? +Will it have its own lifecycle (stages, start/end dates)? + +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 + + +**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. + + +## 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? + +Our team can help you design and create the data model you need. Discover our [Implementation Services](/user-guide/getting-started/capabilities/implementation-services). diff --git a/packages/twenty-docs/user-guide/data-model/relation-fields.mdx b/packages/twenty-docs/user-guide/data-model/relation-fields.mdx deleted file mode 100644 index 67fcea9554..0000000000 --- a/packages/twenty-docs/user-guide/data-model/relation-fields.mdx +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Relation Fields -info: Learn how to create relationships between objects using relation fields and configure 1-to-many relationships. -image: /images/user-guide/fields/relations_field.png -sectionInfo: Flexible data model designed to support your unique business processes ---- - - Header - - -## What are Relation Fields? - -Relation fields link records from one object to records in another object. For example: -- **People** → **Companies** (each person works for a company) -- **Opportunities** → **People** (each deal has a contact person) -- **Tasks** → **Opportunities** (each task relates to a specific deal) - -## Creating Relation Fields - -### 1. Add the Field -Go to **Settings → Data Model → [Your Object]** and click **Add Field**. - -### 2. Choose Relation Type -- **Field Type**: Select "Relation" -- **Target Object**: Choose which object to connect to -- **Relationship**: Currently supports **1-to-many** relationships only. Make sure to create the relationship in the right direction. - -### 3. Configure Field Names -You'll need to set names for both sides of the relationship: -- **Source field name**: How the field appears on your current object -- **Target field name**: How the reverse field appears on the target object - - -Field names cannot be edited once the relation is saved as it impacts the API structure. Choose carefully. - - -## Relating to Team Members - -You can create relations to any object, including **Workspace Members** (your Twenty team users). This is useful for creating ownership fields: - -- **Account Owner**: Link a Company to a team member who manages it -- **Deal Owner**: Assign an Opportunity to a specific salesperson - -When you create a relation to`Workspace Members`, you'll see your team members' names in dropdown selections, making it easy to assign ownership and responsibilities. - -## Morph Many Relationships - -Morph Many relationships allow a single field to connect to multiple different object types, providing flexible data modeling for complex business scenarios. - -### What are Morph Many Relationships? - -With Morph Many relationships, one object can relate to different types of objects through a single field. For example: -- An **Opportunity** can relate to either a **Person** or a **Company** -- A **Task** can be associated with any type of record (Person, Company, Deal, etc.) -- An **Attachment** can be linked to multiple different object types - -### Creating Morph Many Relationships - -1. Go to **Settings → Data Model → [Your Object]** -2. Click **Add Field** and select **Relation** -3. Choose **Morph Many** as the relationship type -4. Select the target object types you want to connect to -5. Configure the field names for each side of the relationship - -This feature gives you the flexibility to create versatile relationships that adapt to your unique business processes without creating multiple separate fields. - -## Best Practices - -- **Plan your relationships** before creating them -- **Use clear, descriptive names** for both field names -- **Test relationships** with sample data before full implementation -- **Consider Morph Many** when a field needs to connect to multiple object types - -## Upcoming Features -- **Many-to-many relationships** (Coming Q1 2026) - - diff --git a/packages/twenty-docs/user-guide/resources/glossary.mdx b/packages/twenty-docs/user-guide/getting-started/capabilities/glossary.mdx similarity index 72% rename from packages/twenty-docs/user-guide/resources/glossary.mdx rename to packages/twenty-docs/user-guide/getting-started/capabilities/glossary.mdx index 3390be4e5e..8e5107ced7 100644 --- a/packages/twenty-docs/user-guide/resources/glossary.mdx +++ b/packages/twenty-docs/user-guide/getting-started/capabilities/glossary.mdx @@ -1,16 +1,17 @@ --- title: Glossary -info: "Get familiar with essential terminology used in Twenty." -image: /images/user-guide/glossary/glossary.png -sectionInfo: Terminology resources and community information +description: Get familiar with essential terminology used in Twenty. --- - - Header - ## 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 serverless 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. @@ -28,11 +29,14 @@ A Data Model is the structure that defines how information is organized in your ## Favorites Favorites are records you've marked for quick access, appearing in your sidebar for instant navigation to important data. -## Field +## Field A field refers to a specific area where particular data is stored for an entity. -## Integration -Integration are built-in tools that allow to link Twenty with other software or systems. +## Integration +Integrations are built-in tools that allow you to link Twenty with other software or systems. + +## 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. @@ -40,10 +44,10 @@ A `Kanban` is a visual way to track your business processes using cards and colu ## 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 Opportunities in Twenty CRM are potential deals or sales with accounts or contacts. -## Record +## Record A Record indicates an instance of an object, like a specific account or contact. ## Relation Fields @@ -52,12 +56,18 @@ Relation Fields create connections between different objects, allowing you to li ## Standard Fields Standard Fields are pre-built data fields that come with objects by default and provide common functionality across all workspaces. -## Tasks +## Tasks Tasks in Twenty CRM are assigned activities relating to contacts, accounts, or opportunities. -## Views +## 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. @@ -65,10 +75,9 @@ Webhooks are automated messages sent from Twenty to other applications when spec 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. +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. - diff --git a/packages/twenty-docs/user-guide/getting-started/capabilities/implementation-services.mdx b/packages/twenty-docs/user-guide/getting-started/capabilities/implementation-services.mdx new file mode 100644 index 0000000000..2125713cee --- /dev/null +++ b/packages/twenty-docs/user-guide/getting-started/capabilities/implementation-services.mdx @@ -0,0 +1,16 @@ +--- +title: Implementation Services +description: Whether you need help getting started or creating advanced customizations, we have a solution. +--- + +## Onboarding Packs + +Get help from our core team to set up your Twenty workspace with our 4-hour Onboarding packs: + +- **Data Model Design**: Design and create your custom data model with objects, fields, and relationships +- **Data Migration**: Migrate your existing data from your current CRM to Twenty +- **Workflow Creation**: Create custom workflows to support your business processes + +## Implementation Partners + +Work with certified Twenty partners for more advanced customizations and integrations. Reach out to our team via [contact@twenty.com](mailto:contact@twenty.com) to be matched with our partners. diff --git a/packages/twenty-docs/user-guide/getting-started/capabilities/what-is-twenty.mdx b/packages/twenty-docs/user-guide/getting-started/capabilities/what-is-twenty.mdx new file mode 100644 index 0000000000..9af3d6b41e --- /dev/null +++ b/packages/twenty-docs/user-guide/getting-started/capabilities/what-is-twenty.mdx @@ -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/capabilities/apis). + + +## Join now + +[Register here](https://app.twenty.com) or [become a contributor on GitHub](https://github.com/twentyhq/twenty). diff --git a/packages/twenty-docs/user-guide/getting-started/configure-your-workspace.mdx b/packages/twenty-docs/user-guide/getting-started/how-tos/configure-your-workspace.mdx similarity index 64% rename from packages/twenty-docs/user-guide/getting-started/configure-your-workspace.mdx rename to packages/twenty-docs/user-guide/getting-started/how-tos/configure-your-workspace.mdx index 94ccb175fc..f4a80b75ff 100644 --- a/packages/twenty-docs/user-guide/getting-started/configure-your-workspace.mdx +++ b/packages/twenty-docs/user-guide/getting-started/how-tos/configure-your-workspace.mdx @@ -1,31 +1,23 @@ --- -title: Configure your Workspace -info: "Start configuring your workspace with these three steps." -image: /images/user-guide/what-is-twenty/getting_started.png -sectionInfo: Discover Twenty, an open-source CRM. +title: Configure Your Workspace +description: "Every business works differently. Start with these 3 steps to shape Twenty around your needs." --- - - Header - -Every business works differently. That's why Twenty lets you shape the CRM around your needs, not force your processes into ours. -**Start with these three steps to set it up your way.** - -**Quick Win**: Start with connecting your mailbox and customizing your data model with a few key fields. This gives you immediate value and helps your team see Twenty in action with real data. You can do so under Settings → Accounts. +**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. ## 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 nor 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/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. +- **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](https://docs.twenty.com/user-guide/data-model/customize-your-data-model) to learn how to design your data model. +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. @@ -48,7 +40,7 @@ Use the Command menu (```Cmd + K``` or ```Ctrl + K```) to import People, Compani - Remove duplicate emails for People or duplicate domains for Companies - Review and fix errors (highlighted in yellow) before importing -Read [this article](/user-guide/getting-started/import-export-data) to learn more about data import. +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 make the data actionable for your team. @@ -71,7 +63,5 @@ Here is how to proceed: - **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](https://docs.twenty.com/user-guide/workflows/getting-started-workflows). - +Start creating automations using [workflows](/user-guide/workflows/overview). diff --git a/packages/twenty-docs/user-guide/getting-started/create-workspace.mdx b/packages/twenty-docs/user-guide/getting-started/how-tos/create-workspace.mdx similarity index 71% rename from packages/twenty-docs/user-guide/getting-started/create-workspace.mdx rename to packages/twenty-docs/user-guide/getting-started/how-tos/create-workspace.mdx index d62774888d..6d9793dda4 100644 --- a/packages/twenty-docs/user-guide/getting-started/create-workspace.mdx +++ b/packages/twenty-docs/user-guide/getting-started/how-tos/create-workspace.mdx @@ -1,16 +1,10 @@ --- title: Create a Workspace -info: "Follow a step-by-step guide on how to register on Twenty, choose a subscription plan, confirm your payment and set up your account, with additional advice on seeking assistance if needed." -image: /images/user-guide/create-workspace/workspace-cover.png -sectionInfo: Discover Twenty, an open-source CRM. +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'; - - Header - - ## Step 1: Registration 1. Navigate to [Twenty Sign Up](https://app.twenty.com). 2. Select your preferred sign-up method: @@ -19,14 +13,15 @@ import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - Or, **Continue With Email** for email registration. + ## Step 2: Choosing a Trial Period Choose between two trial periods: -### 30 days +### 30 days With credit card -### 7 days +### 7 days Without credit card Both trials include: @@ -44,6 +39,5 @@ You can click on "Change plan" to choose a different plan or billing interval. Post 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) - +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). diff --git a/packages/twenty-docs/user-guide/getting-started/getting-around-twenty.mdx b/packages/twenty-docs/user-guide/getting-started/how-tos/navigate-around-twenty.mdx similarity index 54% rename from packages/twenty-docs/user-guide/getting-started/getting-around-twenty.mdx rename to packages/twenty-docs/user-guide/getting-started/how-tos/navigate-around-twenty.mdx index c5e561b9b4..2bd11f2d25 100644 --- a/packages/twenty-docs/user-guide/getting-started/getting-around-twenty.mdx +++ b/packages/twenty-docs/user-guide/getting-started/how-tos/navigate-around-twenty.mdx @@ -1,43 +1,32 @@ --- -title: Getting around Twenty -info: "Get a quick overview of how to navigate through the platform and where to take different types of actions." -image: /images/user-guide/what-is-twenty/getting_around.png -sectionInfo: Discover Twenty, an open-source CRM. +title: Navigate Around Twenty +description: Get a quick overview of how to navigate through the platform and where to take different types of actions. --- - - Header - - -When you log into Twenty for the first time, the layout should feel intuitive. It’s designed to help you move fast and stay organized, without getting in your way. ## The Main Layout -The center of the screen is **where your records live**: people, companies, opportunities, tasks, notes, workflows and any other object you created. This is where the day-to-day work happens. +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, delete records** from there as well as **creating new views**. + + + ## The Navigation Bar -On the left side, from the top to the bottom, you’ll be able to: +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 -- Choose between the light and dark modes - Use the **search bar** (press `/` to focus on it instantly) - Open the **Settings** section - - -Please note that our API documentation is accessible under the Settings section and not the User Guide. - - - Have direct access to your **Favourites views**. Favourites are unique for each user. - Switch between different objects - **Create automations** using workflows - Reach out to Support and open our User Guide. -## Command Menu & Quick Search + -The command menu gives you **quick access to actions and search** in Twenty. You can access it in two ways: +## 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 - -You'll also see a search bar at the top of your sidebar for quick record searches, or press `/` to focus on it instantly. - From there, you can: - Create new records - **Import and export data via csv** @@ -45,6 +34,20 @@ From there, you can: - Access deleted records (Twenty supports soft and hard deletes) - See the keyboard shortcuts to quickly access objects in your workspace + + +## The Search Bar +The search bar is accesible via the Command Menu, at the top of your navigation bar, or by pressing `/` to focus on it instantly. Search works across all object. + + + +## 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, clicking on the Open button. + + + + + ## Views Every object (like Opportunities or People) supports multiple views. You're not limited in the number of views per object. @@ -55,7 +58,9 @@ Use the dropdown menu at the top left of the main layout to switch between the d - Save filtered views to reuse them later - Favourite views for fast access -If you're new to Views, read our [View Management](/user-guide/crm-essentials/view-management) article to learn how to create and customize them. + + +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: @@ -68,6 +73,5 @@ Open your Settings from the top left to: - Configure billing and monitor workflow credits usage - Discover the latest releases and upcoming features (under Releases → Lab tab) -If you do not see all those sections under Settings, reach out to your workspace administrator - some of them have a restricted access. - +If you do not see all those sections under Settings, reach out to your workspace administrator - some of them have restricted access. diff --git a/packages/twenty-docs/user-guide/getting-started/implementation-services.mdx b/packages/twenty-docs/user-guide/getting-started/implementation-services.mdx deleted file mode 100644 index 97dc79f4c2..0000000000 --- a/packages/twenty-docs/user-guide/getting-started/implementation-services.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Implementation Services -info: "From quick start to full migration, we've got you covered." -image: /images/user-guide/what-is-twenty/implementation_services.png -sectionInfo: Discover Twenty, an open-source CRM. ---- - - Header - - -## Implementation Services -Whether you need help getting started or creating advanced customizations, we have a solution. - -### Onboarding Packs -Get help from our core team to set up your Twenty workspace with our 4-hour [Onboarding packs](https://twenty.com/onboarding-packages): - -- **Data Model Design**: Design and create your custom data model with objects, fields, and relationships -- **Data Migration**: Migrate your existing data from your current CRM to Twenty -- **Workflow Creation**: Create custom workflows to support your business processes - -### Implementation Partners -Work with certified Twenty partners for more advanced customizations and integrations. Reach out to our team via contact@twenty.com to be matched with our [partners](https://twenty.com/implementation-services). - - - diff --git a/packages/twenty-docs/user-guide/getting-started/import-export-data.mdx b/packages/twenty-docs/user-guide/getting-started/import-export-data.mdx deleted file mode 100644 index eaacfb6209..0000000000 --- a/packages/twenty-docs/user-guide/getting-started/import-export-data.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Import/Export Data -info: "Learn how to import and export data." -image: /images/user-guide/import-export-data/cloud.png -sectionInfo: Discover Twenty, an open-source CRM. ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -## Import Data -- You can import data for any object using a .csv, .xlsx, or .xls file. -- Each of the files you upload needs to contain **only one type of object** (for example, only People records). -- You can use the Import to **create or update records**. - -### Download a sample file to match the expected formatting -1. Go to a view with the object you're about to import. -2. Click on the `⋮` icon on the top right and then select `Import records`. -3. Click on `Download sample file`. - -### Prepare your csv -Below are a few items to check before uploading your file. -- Limit the number of records to **10,000 per file**. -- **Remove duplicates** from your file. - - The unicity on `People` is set by default by the `id` and the `email`. You also have the ability to define custom fields from `People` as unique when configuring your data model. - - The unicity on `Companies` is set by default by the `id` and the `domain`. You also have the ability to define custom fields from `Companies` as unique when configuring your data model. - - For any other object, including custom objects, you have the ability to define some field(s) as unique. Make sure to not include duplicates when preparing your files. -- We recommend using the syntax ```https://domain.com``` when uploading your domains, as this is the one used by our connector with your mailbox and calendar. -- You can **import the relations between objects** by providing one of the unique fields of the associated record. - - Example: You want to attach a person to a company. Add a column in the file containing all the `People` records that contains the `id` of the company -- or its `domain`. You will be able to map this field during the upload. - -**Important note:** -- Relations between objects in Twenty are "One to Many". This means each record of object A can be attached to several records of object B. But each record of object B can belong to only one record of object A. -*For example, one company can be attached to several people. And one person can belong to only one company.* - -- To upload relations via the Import function, you need to provide the `id` (or any other unique field) of the attached object in the file containing the records on the "Many side" of the relationship. -*For example, you provide the `id` or `domain` of the company when uploading people records. You do not provide the people's `id` (or `email`) when uploading the file with companies.* - - - -### Upload your file -1. Go to a view with the object you're about to import. -2. Click on the `⋮` icon on the top right and then select `Import records`. -3. Click on `Select file`. -4. Validate the mapping of the fields. - - You don't have to import all of them, you can choose the "Do not map" option. - - For relationships, it is recommended to only map one of the unique fields. - - You might need to also map the values of your select type and multi-select type fields. -5. Click on `Next Steps` and `Review the rows with errors`. Cells with an issue are highlighted. **You can either remove the row or update the cell directly from there**. -6. Once you're done, click on `Confirm` - - - - -### Import FAQ - -
-I see duplicates issues when uploading my file, what should I do? - -Please refer to the section **Prepare your csv** above in this article, it contains guideline about what will be considered a duplicate. - -
- -
-Can I import relations between objects? - -Yes, please refer to the section **Prepare your csv** above in this article, it contains a section about the import of relations. - -
- -
-Can I update existing records using the Import function? - -Yes you can update existing records using the Import function. Make sure to provide the id (or any other unique field) when re-uploading your records. - -
- -
-Can I migrate the `id` from my other tool(s)? - -Yes. You need to create a field that you define as unique in your data model that will contain the `id` from your other tool(s). Please note that the name `id` is protected as it is used for the Twenty id. -If you want to create relations between objects using this field, refer to the section **Prepare your csv** above in this article. It contains a section about the import of relations. - -
- - -## Export Data - -You can download data from most of your objects and up to 20,000 records per export. -To export data from an object: - -1. Visit the object index. -2. Choose the view for data export. Configure the columns you want to download by hiding or adding columns and find the records you need by filtering your view. -3. Access the side panel through the `⋮` icon on the top right. -4. Click on `Export view`. -5. Select the save location for the CSV data. Note that exporting may take time with a large record count. - - - - diff --git a/packages/twenty-docs/user-guide/getting-started/migrating-from-other-crms.mdx b/packages/twenty-docs/user-guide/getting-started/migrating-from-other-crms.mdx deleted file mode 100644 index 3f941cf214..0000000000 --- a/packages/twenty-docs/user-guide/getting-started/migrating-from-other-crms.mdx +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Migrating from Other CRMs -info: Step-by-step guide for migrating data and processes from other CRM systems to Twenty. -image: /images/user-guide/what-is-twenty/migrating_crm.png -sectionInfo: A brief guide to grasp the basics of Twenty ---- - - Header - - -## Before You Start - -### 1. Audit Your Current Data -- **Select the few objects and fields to migrate**: this migration is the opportunity for a fresh start -- **Export this data** from your current CRM -- **Remove duplicates** and outdated records -- **List active workflows** and automations - -### 2. Create Your New Data Model -Follow our [data model guide](/user-guide/data-model/customize-your-data-model) to: -- **Design the data model** you need -- **Map existing fields** to Twenty's standard objects / fields -- **Identify the custom objects / fields** that you will need -- **Create them** under Settings → Data model - -## Migration Process - -### 1. Import Your Data -**Recommended order:** -1. **Companies** first (as base records) -2. **People** second (linked to companies) -3. **Opportunities** third (linked to people/companies) - -Use the CSV import via the Command Menu `Cmd + K` (Mac) or `Ctrl + K` (Windows). See our [data import guide](/user-guide/getting-started/import-export-data) for detailed instructions. - -### 2. Recreate Workflows -- **Start simple** - recreate your most critical automations first -- **Use Twenty's workflow builder** to replace existing automations - -## Common Challenges - -### Data Formatting Issues -- **Email addresses** - remove duplicates (People object requirement) -- **Domain** - remove duplicates (Companies object requirement) - - -Please note that domain URLs created by the synchronization with your mailbox and calendar have the following format ```https://domain.com``` - - -- **Date formats** - ensure consistent formatting (YYYY-MM-DD) or edit this format under Settings → Experience -- **Phone numbers** - use international format (+1234567890) - -### Relationship Mapping -To import relations between records using the csv import function, you can use the following fields -- **Use Twenty IDs** for complex relationships -- **Use email addresses** to link People records -- **Use domain names** to link Company records -- **Use any other field you set as unique**, which can be done in the Data Model section. -Read our [import-export data guide](/user-guide/getting-started/import-export-data) for detailed instructions on creating relationships during CSV import. - -## Professional Help -### Our Services -- **4-hour onboarding packs** for guided migration -- **Implementation partners** for more advanced projects - -Discover our [implementation services](/user-guide/getting-started/implementation-services). - -## Migrating from Self-Hosted to Cloud - -If you're moving from Twenty self-hosted to Twenty Cloud: -1. **Export your data** from your self-hosted instance -2. **Follow the standard migration process** above -3. **We can provide migration assistance**, reach out to our team - -## Post-Migration Checklist - - All data imported successfully - Custom fields working correctly - User permissions configured - Email/calendar sync connected - Critical workflows recreated and tested - Team trained on new system - - diff --git a/packages/twenty-docs/user-guide/getting-started/what-is-twenty.mdx b/packages/twenty-docs/user-guide/getting-started/what-is-twenty.mdx deleted file mode 100644 index 184d005c1b..0000000000 --- a/packages/twenty-docs/user-guide/getting-started/what-is-twenty.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: What is Twenty -info: "Discover Twenty, an open-source CRM, its features, benefits, system requirements, and how to get involved." -image: /images/user-guide/what-is-twenty/20.png -sectionInfo: Discover Twenty, an open-source CRM. ---- - - Header - - -Twenty is the leading open-source CRM, crafted by hundreds of contributors to suit your unique 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 - -**Contact Management:** Efficiently store and manage customer data. [Learn more](/user-guide/crm-essentials/contact-and-account-management). - -**Custom Objects:** Create and customize objects to fit your business needs. [Details](/user-guide/data-model/objects). - -**Custom Fields:** Tailor data fields to capture and organize information specific to your operations. [Understand more](/user-guide/data-model/fields). - -**Deal Management:** Track and manage your sales opportunities through customizable [Pipeline stages](/user-guide/crm-essentials/pipeline). - -**Kanban & Table Views:** Make data actionable with [flexible table views](/user-guide/crm-essentials/view-management). - -**Workflows:** Automate your business processes and integrate with external tools using powerful workflow automation. [Get started](/user-guide/workflows/getting-started-workflows). - -**Email Integration:** View the emails of a specific customer or company within your workspace. [Synchronize your mailbox](/user-guide/collaboration/emails-and-calendars). - -**Notes:** Create detailed notes for each record to share knowledge more effectively. [Add notes](/user-guide/collaboration/notes). - -**Tasks:** Schedule tasks to track customer interactions. [See how](/user-guide/collaboration/tasks). - -**Permissions:** Control access and manage user roles with flexible workspace and object-level permissions. [Configure permissions](/user-guide/settings/permissions). - -**API & Webhooks:** Connect to other apps and automate workflows with API and Webhooks. [Start integrating](/user-guide/integrations-api/api-webhooks). - - -## Join now - -[Register here](https://app.twenty.com) or [become a contributor on GitHub](https://github.com/twentyhq/twenty). - - diff --git a/packages/twenty-docs/user-guide/integrations-api/api-webhooks.mdx b/packages/twenty-docs/user-guide/integrations-api/api-webhooks.mdx deleted file mode 100644 index 745bbc7834..0000000000 --- a/packages/twenty-docs/user-guide/integrations-api/api-webhooks.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: API Keys & Webhooks -info: "Create and manage API keys for authentication and set up webhooks for real-time notifications." -image: /images/user-guide/api/api.png -sectionInfo: Learn how to connect Twenty to your other tools. ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -## API Keys - -API keys allow automated access to your CRM data, synchronize data with other systems, and create custom integrations or solutions. - -### Create an API Key - -1. Go to **Settings → APIs & Webhooks** -2. Click **+ Create key** at the top right -3. Configure your API key: - - **Name**: Give your API key a descriptive name - - **Expiration Date**: Set when the key should expire -4. Click **Save** to generate your API key -5. **Important**: Copy and store your API key immediately, it's only shown once - -Once created, your API key provides access to your custom API documentation and playground where you can test endpoints with your actual data model. - - -Since your API key gives access to sensitive information, you shouldn't share it with services you don't fully trust. If leaked, someone can use it maliciously. If your API key's security is compromised, immediately disable it and generate a new one. - - - - -### Manage API Keys - -**Regenerate an API Key:** -1. Go to **Settings → APIs & Webhooks** -2. Click on the API key you want to regenerate -3. Click the **Regenerate** button -4. Copy and store the new API key immediately - -**Delete an API Key:** -1. Find the API key in your list -2. Click on the key to open its details -3. Click **Delete** to remove it permanently - -## Webhooks - -Webhooks allow for immediate updates to your specified URL about changes or events related to your customer data. - -For example, when an Opportunity moves to "Closed Won", a webhook can automatically trigger invoice creation in your accounting system. Note that this type of automation can also be achieved using Twenty's in-app [Workflows feature](/user-guide/workflows/getting-started-workflows), which offers triggers based on field updates for internal automation. - -Webhooks are ideal for integrating with external systems, while Workflows support both internal automation and external tool connections via webhook triggers, code nodes, and HTTP nodes. - -### Create a Webhook - -1. Go to **Settings → APIs & Webhooks → Webhooks** -2. Click **+ Create webhook** -3. Enter your webhook URL (where you want to receive notifications) -4. Click **Save** - -Your webhook will immediately start receiving real-time notifications about changes to your CRM data. - - - -### Manage Webhooks - -**Delete a Webhook:** -1. Go to **Settings → APIs & Webhooks → Webhooks** -2. Find the webhook you want to remove -3. Click on the webhook -4. Click **Delete** and confirm in the popup - -**Edit a Webhook:** -1. Click on the webhook you want to modify -2. Update the URL or other settings -3. Click **Save** to apply changes - - diff --git a/packages/twenty-docs/user-guide/integrations-api/apis-overview.mdx b/packages/twenty-docs/user-guide/integrations-api/apis-overview.mdx deleted file mode 100644 index ebfdad1b3e..0000000000 --- a/packages/twenty-docs/user-guide/integrations-api/apis-overview.mdx +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: APIs Overview -info: Understand the four different APIs and when to use each one. -image: /images/user-guide/api/api-overview.png -sectionInfo: Learn how to connect Twenty to your other tools. ---- - - Header - - -Twenty was built to be developer-friendly, offering powerful APIs that adapt to your custom data model. We provide four distinct API types to meet different integration needs. - -## Developer-First Approach - -Twenty generates APIs specifically for your data model, meaning: -- **No long IDs required**: Use your object and field names directly in endpoints -- **Standard and custom objects treated equally**: Your custom objects get the same API treatment as built-in ones -- **Dedicated endpoints**: Each object and field gets its own API endpoint -- **Custom documentation**: Generated specifically for your workspace's data model - - -Your custom API generates personalized documentation accessible via Settings → API & Webhooks after creating an API key. This documentation reflects your exact data model and field configurations. - - -## The Four API Types - -Twenty offers APIs in both **REST** and **GraphQL** formats: - -### REST APIs - -#### 1. REST Metadata API -- **Purpose**: Manage your workspace and data model structure -- **Use cases**: - - Create, modify, or delete objects and fields - - Configure workspace settings - - Manage data model relationships -- **Access**: Available through REST endpoints - -#### 2. REST Core API -- **Purpose**: Manage your actual data records -- **Use cases**: - - Create, read, update, delete records - - Query specific data - - Manage record relationships -- **Access**: Available through REST endpoints - -### GraphQL APIs - -#### 3. GraphQL Metadata API -- **Purpose**: Same as REST Metadata API but with GraphQL benefits -- **Use cases**: Same workspace and data model management -- **Additional benefits**: - - Query multiple metadata types in one request - - Precise field selection - - Better performance for complex queries - -#### 4. GraphQL Core API -- **Purpose**: Same as REST Core API but with GraphQL advantages -- **Use cases**: Same data record management -- **Additional benefits**: - - **Batch operations**: Available for all operations - - **Upsert operations**: Create or update records in one call - - Query relationships in single requests - - Precise data fetching - -## Batch Operations - -### REST and GraphQL Batch Support -Both REST and GraphQL APIs support batch operations for most actions: -- **Batch size**: Up to 60 records per request -- **Available operations**: Create, update, delete multiple records -- **Performance**: Significantly faster than individual API calls - -### GraphQL-Only Features -- **Batch Upsert**: Only available in GraphQL APIs -- **Usage**: Use plural object names (e.g., `CreateCompanies` instead of `CreateCompany`) -- **Requirement**: This is why singular and plural object names must be distinct - -## API Documentation Access - -1. Go to **Settings → API & Webhooks** -2. Create an API key (required for documentation access) -3. Access your custom documentation and playground -4. Test APIs with your actual data model - -Your documentation is unique to your workspace because it reflects your custom objects, fields, and relationships. - -## When to Use Each API - -### Use Metadata APIs when: -- Setting up your data model -- Creating custom objects or fields -- Configuring workspace settings - -### Use Core APIs when: -- Managing day-to-day data (People, Companies, Opportunities) -- Integrating with external systems -- Building custom applications -- Automating data workflows - -### Choose GraphQL when: -- You need batch operations -- You want to minimize API calls -- You need upsert functionality -- You're building complex integrations - -### Choose REST when: -- You prefer simpler API structure -- You're building basic integrations -- Your team is more familiar with REST -- You need straightforward CRUD operations - -## Next Steps - -- **[API & Webhooks Setup](/user-guide/integrations-api/api-webhooks)**: Learn how to create API keys and webhooks -- **Custom Documentation**: Access your personalized API docs via Settings → API & Webhooks - - diff --git a/packages/twenty-docs/user-guide/integrations-api/integrations.mdx b/packages/twenty-docs/user-guide/integrations-api/integrations.mdx deleted file mode 100644 index f45ad6eb1a..0000000000 --- a/packages/twenty-docs/user-guide/integrations-api/integrations.mdx +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Integrations -info: "Connect Twenty to your existing tools and build custom automations." -image: /images/user-guide/integrations/plug.png -sectionInfo: Connect Twenty to your existing tools and workflows ---- - - Header - - -## Current Integration Options - -### Native Integrations -Twenty currently offers native integration with: -- **Email & Calendar**: Connect Gmail, Outlook, or SMTP/CalDAV providers -- **API Access**: Use our REST and GraphQL APIs to build custom integrations - -For email and calendar setup, visit [Email & Calendar Setup](/user-guide/settings/email-calendar-setup). - -### Workflows (Recommended) -The primary way to connect Twenty to other tools is through our in-app **Workflows** feature: -- **HTTP Nodes**: Make API calls to external services -- **Code Nodes**: Write custom logic for complex integrations -- **Webhook Triggers**: Receive data from external systems -- **Field Update Triggers**: Automate actions based on CRM changes - -Learn more in our [Workflows section](/user-guide/workflows/getting-started-workflows). - -### Zapier Integration (Legacy) -We maintain a Zapier integration for users who prefer no-code automation: - -1. Visit [Twenty on Zapier](https://zapier.com/apps/twenty/integrations) -2. Create a new Zap with Twenty as trigger or action -3. Generate an API key in Settings → API & Webhooks -4. Connect your Twenty workspace to Zapier - -## Future Vision: Community-Built Connectors (2026) - -### Extensibility Platform -We're building an extensibility platform that will allow developers to create apps as code. This will enable: -- **Custom Connectors**: Build integrations with your favorite software -- **Community Contributions**: Share and discover connectors built by others -- **Flexible Architecture**: Extend Twenty's capabilities beyond core features - -### AI-Assisted Workflow Building -Coming in 2026, AI assistance will help users: -- **Auto-Generate Workflows**: Describe your integration needs in plain language -- **Smart Suggestions**: Get recommendations for connecting your specific tools -- **Template Library**: Access pre-built workflows for common use cases - -The future of Twenty integrations is community-driven, AI-assisted, and infinitely extensible. - - diff --git a/packages/twenty-docs/user-guide/introduction.mdx b/packages/twenty-docs/user-guide/introduction.mdx index f31cb08276..6ef19c29f9 100644 --- a/packages/twenty-docs/user-guide/introduction.mdx +++ b/packages/twenty-docs/user-guide/introduction.mdx @@ -1,58 +1,64 @@ --- -title: Overview -description: Your complete guide to Twenty CRM features and best practices. +title: Discover Twenty +description: Welcome to Twenty User Guide, your resources for advanced configurations and best practices. --- import { CardTitle } from "/snippets/card-title.mdx" - - - Getting Started - Start your Twenty journey with these essential guides. + + + Discover Twenty + Learn what Twenty is and how it can help your business. - + Data Model - Customize your data model to fit your unique business processes. + Customize your data model to fit your business processes. - - CRM Essentials - Essential CRM features for managing leads, sales, and customers. + + Data Migration + Import and export your data via CSV or API. - + + Calendar & Emails + Centralize your team's meetings and emails. + + + Workflows Automate processes and integrate with external tools. - - Collaboration - Centralize communications and team collaboration. + + AI + Enhance your team with AI agents. - - Integrations API - Learn how to connect Twenty to your other tools. + + Views & Pipelines + Organize your data with actionable views and pipelines. - - Reporting - Track performance with custom reports and dashboards. Coming Q4 2025 + + Dashboards + Real-time insights to track performance. - + + Permissions & Access + Manage roles and access to Twenty. + + + + Billing + Understand how Twenty pricing and billing works. + + + Settings - Configure your Twenty workspace settings and preferences. + Configure your workspace preferences. - - Pricing - Understand how Twenty pricing works. - - - - Resources - Terminology definitions and community links. - diff --git a/packages/twenty-docs/user-guide/permissions-access/capabilities/permissions.mdx b/packages/twenty-docs/user-guide/permissions-access/capabilities/permissions.mdx new file mode 100644 index 0000000000..000b837154 --- /dev/null +++ b/packages/twenty-docs/user-guide/permissions-access/capabilities/permissions.mdx @@ -0,0 +1,194 @@ +--- +title: Permissions +description: Control access to objects, fields, and settings with role-based permissions. +image: /images/user-guide/permissions/permissions.png +--- + + +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 → 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 → 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 + + +If a role is deleted, any workspace member assigned to it will be automatically reassigned to the default role. All except the **Admin** role can be deleted. There must always be at least one member assigned to the **Admin** role. + + +## Assign Roles to Members + +### View Current Assignments +- Go to **Settings → 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 → 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 → 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 + + +You can only assign roles to existing workspace members. To invite new members, use [Member Management](/user-guide/settings/capabilities/member-management). + + +## 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. + + +**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. + + +#### 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) | + +### 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) + + +**Current limitation**: Access to workflow management is currently required to manually trigger workflows. This behavior may change in future releases. + + +### 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** + +## Assigning 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 → 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. + + +API keys without an assigned role use default permissions. For tighter security, always assign a specific role to production API keys. + + +### Assign a Role to an AI Agent + +1. Go to **Settings → 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. + + +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. + diff --git a/packages/twenty-docs/user-guide/permissions-access/capabilities/sso-configuration.mdx b/packages/twenty-docs/user-guide/permissions-access/capabilities/sso-configuration.mdx new file mode 100644 index 0000000000..a91f63fb88 --- /dev/null +++ b/packages/twenty-docs/user-guide/permissions-access/capabilities/sso-configuration.mdx @@ -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 Twenty workspace + + +**For self-hosting users willing to set up SSO**, reach out to contact@twenty.com + + +### 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 +- Assigned 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 + +## 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 certificate hasn't expired +- **URL mismatches**: Verify 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) diff --git a/packages/twenty-docs/user-guide/permissions-access/how-tos/permissions-faq.mdx b/packages/twenty-docs/user-guide/permissions-access/how-tos/permissions-faq.mdx new file mode 100644 index 0000000000..ff9a3e55a7 --- /dev/null +++ b/packages/twenty-docs/user-guide/permissions-access/how-tos/permissions-faq.mdx @@ -0,0 +1,121 @@ +--- +title: Permissions FAQ +description: Frequently asked questions about roles and permissions. +--- + +## Roles + + + +Twenty comes with an **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). + + + +No, the Admin role cannot be deleted. There must always be at least one member assigned to the Admin role. + + + +Any workspace member assigned to that role will be automatically reassigned to the default role. + + + +Go to **Settings → Roles**, find the **Default Role** option, and select which role new members should automatically receive when they join. + + + +No, each user can only have one role at a time. Create a custom role if you need a combination of permissions. + + + +## 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. + + + +Permissions cascade from global 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. + + + +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 + + + +Row-level permissions will be available on the **Organization** plan by Q1 2026. This allows you to restrict access to specific records based on criteria (e.g., only see your own opportunities). + + + +1. Go to **Settings → Roles** +2. Select the role +3. Navigate to the object containing the field +4. Set the field permission to **See Field** (without Edit Field) + + + +## Settings & Actions + + + +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. + + + +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. + + + +## SSO + + + +No, SSO is a Premium feature available on the **Organization** plan only. + + + +Twenty supports: +- **SAML 2.0** (works with most enterprise identity providers) +- **Google Workspace** +- **Microsoft Entra ID** (formerly Azure AD) + + + +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. + + + +Yes, once SSO is configured, you can disable password login for SSO users to enforce authentication through your identity provider. + + + diff --git a/packages/twenty-docs/user-guide/permissions-access/overview.mdx b/packages/twenty-docs/user-guide/permissions-access/overview.mdx new file mode 100644 index 0000000000..9991aa0c75 --- /dev/null +++ b/packages/twenty-docs/user-guide/permissions-access/overview.mdx @@ -0,0 +1,38 @@ +--- +title: Permissions & Access +description: Manage roles, permissions, and access control in your workspace. +--- + + + Permissions & Access + + +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 + + + + Create roles and configure object, field, and settings permissions. + + + Set up Single Sign-On with your identity provider. + + + Common questions about roles, permissions, and SSO. + + + +## 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) diff --git a/packages/twenty-docs/user-guide/reporting/reporting-overview.mdx b/packages/twenty-docs/user-guide/reporting/reporting-overview.mdx deleted file mode 100644 index ded7d6a352..0000000000 --- a/packages/twenty-docs/user-guide/reporting/reporting-overview.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Reporting Overview -info: Learn about Twenty's upcoming reporting and analytics capabilities coming Q4 2025. -image: /images/user-guide/reporting/reporting.png -sectionInfo: Track performance with custom reports and dashboards ---- - - Header - - -## What's Coming - -### Custom Reports -Create tailored reports to track the metrics that matter most to your business. - -### Sales Dashboards -Visualize your sales pipeline performance with interactive dashboards. - -### Performance Analytics -Monitor team performance and identify trends in your customer data. - - -## Stay Updated - -Follow our [GitHub repository](https://github.com/twentyhq/twenty) or check the **Settings → Releases** section in your workspace to get notified when reporting features become available. - - diff --git a/packages/twenty-docs/user-guide/resources/github.mdx b/packages/twenty-docs/user-guide/resources/github.mdx deleted file mode 100644 index 51bec4f68a..0000000000 --- a/packages/twenty-docs/user-guide/resources/github.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: GitHub -info: "Learn about the Twenty GitHub repository and the variety of resources it hosts including source code, documentation, and discussions." -image: /images/user-guide/github/github-header.png -sectionInfo: Terminology resources and community information ---- - - Header - - -## About - -The Twenty GitHub repository hosts a vast array of resources like source code, documentation, discussions, and issue tracking. This is where you will be able to access the full code behind Twenty. - -[Visit Twenty on GitHub](https://github.com/twentyhq/twenty) - -## Contributing - -Contributing to the Twenty project on GitHub is a rewarding way to help improve the software you use. Whether you're fixing bugs, suggesting features, or improving documentation, your contributions are welcome. - -### Reporting Issues - -Encounter an issue? [Create an issue](https://github.com/twentyhq/twenty/issues/new) on GitHub, providing as much detail as possible. - - - -### Suggesting Features - -What improvements would you like to see on Twenty? No matter your technical know-how, you can join [the conversation here](https://github.com/twentyhq/twenty/discussions). - - - -### Coding a feature - -Start your journey by finding beginner-friendly tasks: - -1. Navigate to the **[Issues](https://github.com/twentyhq/twenty/issues)** tab on the Twenty repository. -2. Filter by **[Good First Issue](https://github.com/twentyhq/twenty/labels/good%20first%20issue)** label to find tasks suited for newcomers. -3. Pick an issue, fork the repository, and start contributing. - - - -Ensure you're assigned to the issue to avoid overlapping work with other contributors. - -### Code of Conduct - -Remember to adhere to Twenty's [Code of Conduct](https://github.com/twentyhq/twenty/blob/main/.github/CODE_OF_CONDUCT.md) throughout your contribution process. - -## Discord - -If you have any question, for example on how to contribute, join the community on [Discord](https://discord.gg/cx5n4Jzs57) - - - -
-
-Thank you for contributing to Twenty ❤️ - diff --git a/packages/twenty-docs/user-guide/settings/capabilities/domains-settings.mdx b/packages/twenty-docs/user-guide/settings/capabilities/domains-settings.mdx new file mode 100644 index 0000000000..3909033033 --- /dev/null +++ b/packages/twenty-docs/user-guide/settings/capabilities/domains-settings.mdx @@ -0,0 +1,44 @@ +--- +title: Domain Settings +description: Configure workspace domain, approved access domains, and public domains. +--- + +Configure domain settings under **Settings → Domains**. + +## Workspace Domain + +Edit your subdomain name or set a custom domain for your workspace. + +### Customize Domain +1. Click **Customize Domain** +2. Edit your subdomain (e.g., `yourcompany.twenty.com`) +3. Or 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 + +Anyone with an email address at these domains is allowed to 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. + + +This is useful for allowing your entire team to self-register while keeping the workspace restricted to your organization. + + +## Public Domains + +Provision a complete and secure hosting environment on these domains. + +### Add Public Domain +1. Click **Add Public Domain** +2. Enter the domain you want to use +3. Configure DNS settings as instructed +4. Verify the domain + +SSL certificates are automatically provisioned for public domains. diff --git a/packages/twenty-docs/user-guide/settings/capabilities/experience-settings.mdx b/packages/twenty-docs/user-guide/settings/capabilities/experience-settings.mdx new file mode 100644 index 0000000000..c1509c2311 --- /dev/null +++ b/packages/twenty-docs/user-guide/settings/capabilities/experience-settings.mdx @@ -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, timezone, and calendar start day. + +| Setting | Description | +|---------|-------------| +| **Time zone** | Your local timezone 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 diff --git a/packages/twenty-docs/user-guide/settings/capabilities/member-management.mdx b/packages/twenty-docs/user-guide/settings/capabilities/member-management.mdx new file mode 100644 index 0000000000..ade88d72e0 --- /dev/null +++ b/packages/twenty-docs/user-guide/settings/capabilities/member-management.mdx @@ -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** +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** +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** to see: +- All active members +- 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** to remove them from the workspace + + +Removed members lose access immediately. Their data (records, notes, tasks) remains in the workspace. + + + +**Email sync is also removed.** If the deleted user was the only one who synced certain emails, those emails will be permanently removed from the workspace. + + +## 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 → Domains** +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 +- [Domains Settings](/user-guide/settings/capabilities/domains-settings) — configure approved domains + diff --git a/packages/twenty-docs/user-guide/settings/profile-settings.mdx b/packages/twenty-docs/user-guide/settings/capabilities/profile-settings.mdx similarity index 82% rename from packages/twenty-docs/user-guide/settings/profile-settings.mdx rename to packages/twenty-docs/user-guide/settings/capabilities/profile-settings.mdx index 02fac72370..d6ef4ef030 100644 --- a/packages/twenty-docs/user-guide/settings/profile-settings.mdx +++ b/packages/twenty-docs/user-guide/settings/capabilities/profile-settings.mdx @@ -1,12 +1,8 @@ --- title: Profile Settings -info: "Manage your personal profile and security settings." -image: /images/user-guide/setup/profile.png -sectionInfo: Configure your Twenty workspace settings and preferences +description: Manage your personal profile and security settings. --- - - Header - + ## Personal Information @@ -41,5 +37,3 @@ To delete your account: 2. Scroll to **Danger Zone** 3. Click **Delete Account** 4. Confirm by typing your email address - - diff --git a/packages/twenty-docs/user-guide/settings/capabilities/releases-settings.mdx b/packages/twenty-docs/user-guide/settings/capabilities/releases-settings.mdx new file mode 100644 index 0000000000..96a8dd0e80 --- /dev/null +++ b/packages/twenty-docs/user-guide/settings/capabilities/releases-settings.mdx @@ -0,0 +1,30 @@ +--- +title: Releases Settings +description: Enable experimental features in Twenty. +--- + +## About Releases Settings + +The Releases section allows you to enable experimental features before they're generally available. + +## Lab Features + +Lab features are experimental capabilities that are still being developed. They may change or be removed without notice. + +### How to Enable Lab Features +1. Go to **Settings → Releases** +2. Find the feature you want to enable +3. Toggle it on +4. The feature will be available immediately + + +Lab features are experimental and may not work as expected. Use them with caution in production environments. + + +## Feature Feedback + +Your feedback helps improve Twenty: +- Report issues with experimental features +- Share how you're using new features +- Suggest improvements via the community Discord + diff --git a/packages/twenty-docs/user-guide/settings/workspace-settings.mdx b/packages/twenty-docs/user-guide/settings/capabilities/workspace-settings.mdx similarity index 73% rename from packages/twenty-docs/user-guide/settings/workspace-settings.mdx rename to packages/twenty-docs/user-guide/settings/capabilities/workspace-settings.mdx index 9b6a106cf6..f27ea85cdc 100644 --- a/packages/twenty-docs/user-guide/settings/workspace-settings.mdx +++ b/packages/twenty-docs/user-guide/settings/capabilities/workspace-settings.mdx @@ -1,13 +1,8 @@ --- title: Workspace Settings -info: "Customize your workspace name and branding." -image: /images/user-guide/setup/settings.png -sectionInfo: Configure your Twenty workspace settings and preferences +description: Customize your workspace name and branding. --- - - Header - - +Those are accessible under **Settings → General**. ## Workspace Picture - **Upload Logo**: Add a custom workspace logo - **Supported formats**: PNG, JPEG, and GIF files under 10MB @@ -27,4 +22,3 @@ To delete your workspace: 2. Confirm the deletion when prompted **Note**: Only workspace administrators can delete workspaces. - diff --git a/packages/twenty-docs/user-guide/settings/domains-settings.mdx b/packages/twenty-docs/user-guide/settings/domains-settings.mdx deleted file mode 100644 index 0d1b322c13..0000000000 --- a/packages/twenty-docs/user-guide/settings/domains-settings.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Domains Settings -info: "Configure workspace domains and approved access settings for automatic user sign up." -image: /images/user-guide/setup/domains-settings.png -sectionInfo: Configure your Twenty workspace settings and preferences ---- - - Header - - -## Custom Workspace Domain - -Set a personalized web address for your workspace: -- Choose your preferred subdomain (e.g., yourcompany.twenty.com) -- Configure custom domains for professional branding - -## Approved Access Domains - -Allow automatic workspace access for specific email domains. - -### How It Works -- Add your company's email domains (e.g., @yourcompany.com) -- Anyone with an email from these domains can automatically join your workspace -- No manual invites needed for team members - -### Benefits -- **Faster Onboarding**: New team members join automatically -- **Better Security**: Only verified company emails can access -- **Less Admin Work**: No need to manually invite each team member - -## Setup Instructions - -1. Go to **Settings → Domains** -2. Add your custom domain or approved email domains -3. Verify domain ownership if required - -**Note**: Domain changes may take time to take effect and might require verification. - - diff --git a/packages/twenty-docs/user-guide/settings/experience-settings.mdx b/packages/twenty-docs/user-guide/settings/experience-settings.mdx deleted file mode 100644 index 2058262c48..0000000000 --- a/packages/twenty-docs/user-guide/settings/experience-settings.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Experience Settings -info: "Customize your interface theme and regional preferences." -image: /images/user-guide/setup/experience.png -sectionInfo: Configure your Twenty workspace settings and preferences ---- - - Header - - -## Appearance - -### Theme Selection -Choose between light and dark modes: -- **Light Mode**: Clean, bright interface ideal for well-lit environments -- **Dark Mode**: Easier on the eyes in low-light conditions -- **System**: Automatically matches your device's theme setting - -## Regional Settings - -### Language -Select your preferred language for the Twenty interface: -- English (default) -- Additional languages available based on community translations - -### Time Zone -Set your local time zone for accurate scheduling and timestamps: -- Affects meeting times, task deadlines, and activity logs -- Automatically adjusts for daylight saving time - -### Date Format -Choose how dates appear throughout Twenty: -- **MM/DD/YYYY** (US format) -- **DD/MM/YYYY** (European format) -- **YYYY-MM-DD** (ISO format) - -### Number Format -Configure how numbers and currencies display: -- **Decimal Separator**: Comma (,) or period (.) -- **Thousands Separator**: Space, comma, or period -- **Currency Symbol**: Based on your region or custom - -### Calendar Format -Set your preferred calendar layout: -- **First Day of Week**: Sunday or Monday -- **Week Numbers**: Show or hide ISO week numbers -- **Time Format**: 12-hour (AM/PM) or 24-hour format - -## How to Update Settings - -1. Go to **Settings → Experience** from the sidebar -2. Adjust your preferences in each section -3. Changes are saved automatically -4. Refresh your browser to see all changes take effect - - diff --git a/packages/twenty-docs/user-guide/settings/how-tos/settings-faq.mdx b/packages/twenty-docs/user-guide/settings/how-tos/settings-faq.mdx new file mode 100644 index 0000000000..8b4abb8106 --- /dev/null +++ b/packages/twenty-docs/user-guide/settings/how-tos/settings-faq.mdx @@ -0,0 +1,171 @@ +--- +title: Settings FAQ +description: Frequently asked questions about Twenty settings. +image: /images/user-guide/setup/settings.png +--- + +## Workspace Settings + + + +1. Go to **Settings → General** +2. Find the Workspace Name field +3. Enter your new name +4. Changes save automatically + + + +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 + + + +Yes, you can create and be a member of multiple workspaces. Each workspace has its own data, settings, and subscription. + + + +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. + + + +Delete the workspaces you no longer need under **Settings → General → Delete workspace**. + + +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. + + + + +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. + + + +## Profile Settings + + + +1. Go to **Settings → Profile** +2. Find the Password section +3. Enter your current password +4. Enter your new password +5. Save changes + + + +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 + + + +To change your email address, please reach out to [contact@twenty.com](mailto:contact@twenty.com). + + + +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. + + + +## Experience Settings + + + +1. Go to **Settings → Experience** +2. Find the Theme section +3. Select Light, Dark, or System + + + +1. Go to **Settings → Experience** +2. Find Date Format +3. Select your preferred format +4. Changes apply immediately + + + +1. Go to **Settings → Experience** +2. Find Time Zone +3. Select your local time zone +4. All timestamps will adjust + + + +1. Go to **Settings → Experience** +2. Find Language +3. Select from available languages +4. The interface updates to your selection + + + +## Account Settings + + + +1. Go to **Settings → Accounts** +2. Click **Add account** +3. Choose Google or Microsoft +4. Authorize access +5. Configure sync settings + + + +Yes, you can connect multiple email accounts. Go to **Settings → Accounts** and add additional accounts as needed. + + + +1. Go to **Settings → Accounts** +2. Find the account to remove +3. Click **Disconnect** +4. Confirm the action + + + +## Domains + + + +Yes! Go to **Settings → Domains** 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. + + + +You can configure approved access domains so team members with company email addresses can automatically join your workspace. Go to **Settings → Domains** and add your company domain (e.g., `yourcompany.com`). + + + +## Lab Features + + + +Lab features are experimental capabilities being tested before general release. They may change or be removed without notice. + + + +Lab features are functional but may have bugs or unexpected behavior. Use them cautiously in production environments. + + + +1. Go to **Settings → Releases → Lab** +2. Find the feature you want +3. Toggle it on +4. The feature becomes available immediately + + diff --git a/packages/twenty-docs/user-guide/settings/member-management.mdx b/packages/twenty-docs/user-guide/settings/member-management.mdx deleted file mode 100644 index 4a52fee7d0..0000000000 --- a/packages/twenty-docs/user-guide/settings/member-management.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Member Management -info: "Invite team members and control workspace access for your Twenty workspace." -image: /images/user-guide/setup/members.png -sectionInfo: Configure your Twenty workspace settings and preferences ---- - - Header - - -## Invite New Members - -### Using the Invite Link -1. Go to **Settings → Members** -2. Copy the workspace invite link -3. Share the link with new team members -4. They'll receive access once they sign up - -### Direct Email Invitation -1. Go to **Settings → Members** -2. Enter the person's email address -3. Click **Invite** -4. They'll receive an email invitation - -## Remove Members - -### Delete a Member -1. Go to **Settings → Members** -2. Find the member you want to remove -3. Click the delete/remove button next to their name -4. Confirm the removal - -**Note**: Removed members lose access immediately but can be re-invited later. - -## Need Help? - -For role and permission management, check the [Permissions article](/user-guide/settings/permissions). - - diff --git a/packages/twenty-docs/user-guide/settings/overview.mdx b/packages/twenty-docs/user-guide/settings/overview.mdx new file mode 100644 index 0000000000..c2723af5b1 --- /dev/null +++ b/packages/twenty-docs/user-guide/settings/overview.mdx @@ -0,0 +1,62 @@ +--- +title: Settings +description: Set up your Twenty workspace with essential configurations. +image: /images/user-guide/setup/settings.png +--- + + + Settings + + +## 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 + + +Before inviting your team, check the default role under **Settings → Roles**. New members are automatically assigned this role when they join. + + +## 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) diff --git a/packages/twenty-docs/user-guide/settings/permissions.mdx b/packages/twenty-docs/user-guide/settings/permissions.mdx deleted file mode 100644 index 23cfa840d6..0000000000 --- a/packages/twenty-docs/user-guide/settings/permissions.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: Permissions -info: "Learn how to control access: assign roles and set permissions." -image: /images/user-guide/permissions/permissions.png -sectionInfo: Configure your Twenty workspace settings and preferences ---- - - Header - - -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 → Roles** -2. Under **All Roles**, click on **+ Create Role** -3. Enter a role name -4. In the default **Permissions** tab, configure permissions -5. Click **Save** to finish - -## Delete a Role - -To delete a role: - -1. Go to **Settings → 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 except the **Admin** role can be deleted. There must always be at least one member assigned to the **Admin** role. - -## Assign Roles to Members - -### View Current Assignments -- Go to **Settings → 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 → 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 → 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/member-management). - -## Customize Permissions - -Permissions determine what each role can access or modify within your workspace, including workspace objects records, settings, and actions. - -### Object and Field Permissions - -Control access to records and individual fields: - -#### Object-Level Permissions -- Under **All Objects**, apply permissions like **See Record**, **Edit Records**, **Delete Records**, or **Destroy Records** to all objects -- Under **Object-Level Permissions**, configure exceptions for individual objects. These override the settings from **All Objects** - -#### Field-Level Permissions -- Configure permissions for individual fields within each object -- Control who can **See Field**, **Edit Field**, or have **No Access** to specific fields -- Field permissions work the same way as object permissions with inheritance and overrides - -#### Managing Permission Overrides -To override parent permissions and apply stricter rules: - -- Click **X** to remove the inherited rule -- Select the specific permissions for the selected object or field -- 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) - -### 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** - diff --git a/packages/twenty-docs/user-guide/settings/releases-settings.mdx b/packages/twenty-docs/user-guide/settings/releases-settings.mdx deleted file mode 100644 index aa4d91bf91..0000000000 --- a/packages/twenty-docs/user-guide/settings/releases-settings.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Releases Settings -info: "Learn about the latest releases and enable beta features in the Lab." -image: /images/user-guide/setup/releases.png -sectionInfo: Configure your Twenty workspace settings and preferences ---- - - Header - - -## Latest Releases - -Track Twenty's development progress: -- **Release Notes**: See what's new in each version -- **Feature Updates**: Discover new capabilities and improvements - -## Lab Features - -Access experimental features before they're officially released: -- **Beta Testing**: Try new features while they're in development -- **Feature Flags**: Enable or disable specific experimental functionality - -## How to Access - -1. Go to **Settings → Releases** -2. View release notes and access the **Lab** tab for beta features - - -For more community resources, check our [Resources section](/user-guide/resources/glossary). - - - diff --git a/packages/twenty-docs/user-guide/settings/settings-faq.mdx b/packages/twenty-docs/user-guide/settings/settings-faq.mdx deleted file mode 100644 index e4475b030a..0000000000 --- a/packages/twenty-docs/user-guide/settings/settings-faq.mdx +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Settings FAQ -info: "Understand how to best manage your workspace." -image: /images/user-guide/what-is-twenty/faq.png -sectionInfo: Configure your Twenty workspace settings and preferences ---- - - Header - - -## Settings FAQ - - - -Absolutely. You can create a new workspace by clicking on the dropdown menu on the very top left of the screen (the one that contains the name of your workspace), on the three dots and then on `Create Workspace`. - - - -Just delete the workspaces you no longer need, you can do so under `Settings → Workspace Settings`. - - -Do not delete your account (accessible under Settings → Profile Settings): your account is shared among the different workspaces. - - - - -If you just want to disable your workspace (not delete it), go to `Settings → Billing` and click on `Cancel Plan`. - - - -You can do so under `Settings → Workspace Settings`. We hope we'll see you around soon, thank you for giving Twenty a try! - - - -Yes! You can control email syncing in several ways: -- **Message Folders**: Enable this lab feature under `Settings → Releases → Lab`, then configure which folders to sync under `Settings → Accounts` -- **Contact Auto-Creation**: Choose whether to create contacts for all emails or only specific types -- **Sharing Levels**: Control how much email content is visible to your team (metadata only, subject + metadata, or full content) - - - -Twenty offers flexible options to control email imports: -- **Folder Selection**: Use the Message Folder lab feature to sync only specific folders (Inbox, Sent, custom folders) -- **External Only**: Only emails with external contacts are synced (internal company emails remain private) -- **Retroactive Control**: You can enable/disable folder syncing at any time to control future imports - - - -No, we don't provide a CC email address for selective syncing. Instead, we offer the Message Folder feature which gives you the same level of control. You can choose exactly which folders sync with Twenty, giving you precise control over which emails appear in your CRM without needing to remember to CC a special address. - - - -Yes! You can connect unlimited email accounts per user. Go to `Settings → Accounts` to add Google, Microsoft, or SMTP/CalDAV accounts. Each account can have different sync settings and folder configurations. - - - -Use the permissions system under `Settings → Roles`. You can create custom roles and control access to: -- **Objects and Fields**: Who can view, edit, or delete specific records and fields -- **Settings**: Access to workspace configuration and admin functions -- **Actions**: General workspace actions like importing data or sending emails - - - -Yes! Go to `Settings → Domains` to set up a custom workspace domain (e.g., yourcompany.twenty.com) and configure approved access domains so team members with company email addresses can automatically join your workspace. - - - -Lab features are experimental capabilities you can test before they're officially released. Access them under `Settings → Releases → Lab`. Features like Message Folder selection are stable and useful, but remember that lab features may change or be removed in future releases. - - - -Go to `Settings → Experience` to customize: -- **Theme**: Light, dark, or system-based -- **Regional Settings**: Language, timezone, date/number formats -- **Calendar Format**: First day of week, time format (12/24 hour) - - - - diff --git a/packages/twenty-docs/user-guide/views-pipelines/capabilities/calendar-view.mdx b/packages/twenty-docs/user-guide/views-pipelines/capabilities/calendar-view.mdx new file mode 100644 index 0000000000..96878610a4 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/capabilities/calendar-view.mdx @@ -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. + + +## 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 +5. 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 diff --git a/packages/twenty-docs/user-guide/views-pipelines/capabilities/fields-and-columns.mdx b/packages/twenty-docs/user-guide/views-pipelines/capabilities/fields-and-columns.mdx new file mode 100644 index 0000000000..6a3ba730c4 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/capabilities/fields-and-columns.mdx @@ -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 clutters 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 + diff --git a/packages/twenty-docs/user-guide/views-pipelines/capabilities/filters-and-sorting.mdx b/packages/twenty-docs/user-guide/views-pipelines/capabilities/filters-and-sorting.mdx new file mode 100644 index 0000000000..ae66bdd20f --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/capabilities/filters-and-sorting.mdx @@ -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, Between, Is empty | +| Date | Equals, Before, After, Between, 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 + diff --git a/packages/twenty-docs/user-guide/views-pipelines/capabilities/kanban-views.mdx b/packages/twenty-docs/user-guide/views-pipelines/capabilities/kanban-views.mdx new file mode 100644 index 0000000000..ae93dbac73 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/capabilities/kanban-views.mdx @@ -0,0 +1,94 @@ +--- +title: Kanban Board Views +description: Learn how to use Kanban views to visualize and manage your workflows. +image: /images/user-guide/kanban-views/kanban.png +--- + +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 dragging and dropping. To proceed, hold your click on a card and move it to the next stage. + + + +## Add and Delete Stages + +You can tailor your workflow to suit your needs using stages, which represent 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 the field your Kanban board depends on. + + + +### Remove Stages + +To remove a stage, hover 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 hide a field, click on **Options** on the top right, then on **Fields** to bring up the list of options. Look for the field needed in the Hidden Fields section and click on the eye button to display the field. + +You can also rearrange the order of fields by holding down the field name and dragging it to where you want it. + + + +## 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** + + + +## 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 diff --git a/packages/twenty-docs/user-guide/views-pipelines/capabilities/table-views.mdx b/packages/twenty-docs/user-guide/views-pipelines/capabilities/table-views.mdx new file mode 100644 index 0000000000..483f789ac5 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/capabilities/table-views.mdx @@ -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. + + +## 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. + + +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 Company by Type +- Group Opportunities by Stage +- Group Tasks by Status + + +**For best performance, limit to 10-15 visible groups per view.** If you need more groups, consider using a Dashboard instead. + + +### 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 + diff --git a/packages/twenty-docs/user-guide/views-pipelines/capabilities/view-settings.mdx b/packages/twenty-docs/user-guide/views-pipelines/capabilities/view-settings.mdx new file mode 100644 index 0000000000..b8a6abbee2 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/capabilities/view-settings.mdx @@ -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** + + +The default "All [Object Name]" views cannot have their visibility changed. + + +## 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 + +## 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** + +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 + + +Deleted views cannot be recovered. + + +## 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 + diff --git a/packages/twenty-docs/user-guide/views-pipelines/how-tos/create-a-calendar-view-for-tasks-due.mdx b/packages/twenty-docs/user-guide/views-pipelines/how-tos/create-a-calendar-view-for-tasks-due.mdx new file mode 100644 index 0000000000..23b26bdaa2 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/how-tos/create-a-calendar-view-for-tasks-due.mdx @@ -0,0 +1,59 @@ +--- +title: Create a Calendar View for Tasks Due +description: Visualize your tasks and deadlines on a calendar. +--- + + + +## 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 + diff --git a/packages/twenty-docs/user-guide/views-pipelines/how-tos/create-a-kanban-view-for-projects.mdx b/packages/twenty-docs/user-guide/views-pipelines/how-tos/create-a-kanban-view-for-projects.mdx new file mode 100644 index 0000000000..007474519b --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/how-tos/create-a-kanban-view-for-projects.mdx @@ -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. + + +## 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 + +### Enable Compact View +For a high-level overview: +1. Click **Options** +2. Turn on **Compact view** + +Cards show only the record name. + + +### 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. + + + +## 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 + diff --git a/packages/twenty-docs/user-guide/views-pipelines/how-tos/create-a-table-view-with-grouping.mdx b/packages/twenty-docs/user-guide/views-pipelines/how-tos/create-a-table-view-with-grouping.mdx new file mode 100644 index 0000000000..6782a52148 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/how-tos/create-a-table-view-with-grouping.mdx @@ -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. + + +## 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. + + +**For best performance, limit to 10-15 visible groups.** If you need more, consider using a Dashboard instead. + + +## 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 + diff --git a/packages/twenty-docs/user-guide/views-pipelines/how-tos/restrict-access-to-your-view.mdx b/packages/twenty-docs/user-guide/views-pipelines/how-tos/restrict-access-to-your-view.mdx new file mode 100644 index 0000000000..c2407b3c89 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/how-tos/restrict-access-to-your-view.mdx @@ -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 diff --git a/packages/twenty-docs/user-guide/views-pipelines/how-tos/set-up-a-sales-pipeline.mdx b/packages/twenty-docs/user-guide/views-pipelines/how-tos/set-up-a-sales-pipeline.mdx new file mode 100644 index 0000000000..173475c173 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/how-tos/set-up-a-sales-pipeline.mdx @@ -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 + + + +### 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 | + + +**5-7 stages is optimal.** Too many stages makes the pipeline hard to scan; too few loses visibility into deal progress. + + +## 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 Amount 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. + + + +## 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 diff --git a/packages/twenty-docs/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline.mdx b/packages/twenty-docs/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline.mdx new file mode 100644 index 0000000000..0d4aaf49a2 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline.mdx @@ -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. + + +This is an example of creating [Formula Fields](/user-guide/workflows/how-tos/crm-automations/formula-fields) using workflows. + + +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 → 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% | + + +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. + + +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 diff --git a/packages/twenty-docs/user-guide/views-pipelines/how-tos/track-time-in-stage.mdx b/packages/twenty-docs/user-guide/views-pipelines/how-tos/track-time-in-stage.mdx new file mode 100644 index 0000000000..dc685fd2d8 --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/how-tos/track-time-in-stage.mdx @@ -0,0 +1,226 @@ +--- +title: Track How Long Opportunities Stay in Each Stage +description: Monitor deal velocity by tracking when opportunities enter each stage. +--- + + +This is an example of creating [Formula Fields](/user-guide/workflows/how-tos/crm-automations/formula-fields) using workflows — specifically date calculations. + + +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 + + +You don't need "Days in" fields for Closed Won and Closed Lost since those are final stages. + + +### Optional: Make Fields Read-Only + +If you don't want users manually editing these calculated fields: + +1. Go to **Settings → 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 + + +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. + + +--- + +**Branch 1: Stage = New (first stage)** + +Since this is the first stage, we only record the entry timestamp—no previous stage to calculate. + +1. Add a **Filter** node: Stage = New +2. Add a **Code** action: + +```javascript +export const main = async (): Promise => { + 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 => { + 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 => { + 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 diff --git a/packages/twenty-docs/user-guide/views-pipelines/overview.mdx b/packages/twenty-docs/user-guide/views-pipelines/overview.mdx new file mode 100644 index 0000000000..f58cf91cbf --- /dev/null +++ b/packages/twenty-docs/user-guide/views-pipelines/overview.mdx @@ -0,0 +1,120 @@ +--- +title: Views & Pipelines +description: Learn how to create and manage views in Twenty. +image: /images/user-guide/table-views/table.png +--- + +import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; + + + Views & Pipelines + + +## 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 +Display records with date fields on a calendar. 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** + + + +### Start by editting an existing view +1. Navigate to any object (People, Companies, etc.) +2. Choose a layout (Table, Kanban, or Calendar) under **Options** or 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 + + + +## 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 + + +Deleted views cannot be recovered. Make sure you want to remove it before confirming. + + +## 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 + + +The default "All [Object Name]" views cannot have their visibility changed. + + +## 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) diff --git a/packages/twenty-docs/user-guide/views/kanban-views.mdx b/packages/twenty-docs/user-guide/views/kanban-views.mdx deleted file mode 100644 index 619170a11c..0000000000 --- a/packages/twenty-docs/user-guide/views/kanban-views.mdx +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Kanban Views -info: "Learn how to customize and navigate Kanban Views." -image: /images/user-guide/kanban-views/kanban.png -sectionInfo: Discover how to use standard and custom objects in your workspace. ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -## 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 dragging and dropping. To proceed, hold your click on a card and move it to the next stage. - - - -## Add and delete stages - -You can tailor your workflow to suit your needs using stages, which represent 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 the field your Kanban board depends on. - - - -### Remove Stages - -To remove a stage, hover 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 hide a field, click on Options on the top right, then on Fields to bring up the list of options. Hover the field you want to hide to bring up the `-` button. Click on it to hide the field. - -You can also rearrange the order of fields by holding down the field name and dragging it to where you want it. - - - -## Compact View - -You can also hide all the fields and get an overview of all the opportunities at a glance. To do so, click on Options on the top right and turn on the toggle for Compact view after selecting layout in Kanban view. - - - diff --git a/packages/twenty-docs/user-guide/views/views-sort-filter.mdx b/packages/twenty-docs/user-guide/views/views-sort-filter.mdx deleted file mode 100644 index 1e47985971..0000000000 --- a/packages/twenty-docs/user-guide/views/views-sort-filter.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Views, Sort and Filter -info: "Find out how to create, manage and delete Object Views." -image: /images/user-guide/views/filter.png -sectionInfo: Discover how to use standard and custom objects in your workspace. ---- - -import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; - - - Header - - -## About Views - -You can see your records in different ways by creating views. In a view, you can apply filters and sorts to organize your content efficiently. For instance, on the `People` object, you can create a view to isolate US contacts by filtering those with a US phone number. - -### Default View - -Each object comes with an unfiltered, unsorted, and undeletable view known as the Default view. It's named after the object's plural name, such as "All Companies", "All People", "All Opportunities". - - - -## Creating, Editing and Deleting Views - -You can create several custom views and share them with your team. - -### View Visibility - -When creating or editing a view, you can choose between two visibility options: - -- **Workspace views**: Shared with your entire team. These views appear in the main "Workspace" section of the view picker for all users. -- **Unlisted views**: Personal views that appear only in your "My unlisted views" section. While these views are hidden from other team members' view lists, they can still be accessed by anyone with the direct link. This is perfect for ad-hoc reports, experiments, or temporary filters that shouldn't clutter the shared view list. - -### Creating a View - -There are two ways to create a new view. Either directly from the `View Switcher`, or by filtering and sorting an existing view. - -#### From View Switcher - -1. Open the View Switcher -2. Click the `Add View` button at the bottom of the view switcher menu. -3. Choose an Icon and name for your View. -4. Choose a "View type" between Table and Kanban. -5. (Kanban Views only) For your Kanban view, select the Select field you wish to use as the column header. The system prompts you to create one from the Settings before enabling Kanban view creation, if your object lacks a `Select` type field. -6. Click "Create" to generate your new view. - -The newly created view opens automatically. - - - -#### From Sorting and Filtering - -When you change the `Sorting` and `Filtering` of an existing view, a `Save as new view` button will appear at the right edge of the `View Bar`. This will open the New View menu mentioned above, allowing you to create a new view out of an existing one. - - - -### Editing and Deleting a View - -To Edit or Delete a view: -1. Open the View Switcher. -2. Hover the View you wish to edit. -3. Click on the three dots that appear upon hover to edit and delete views. - -Upon clicking on edit, you can: -- Change the icon and name of the view -- Switch between Workspace and Unlisted visibility -- Delete the view completely - - -When you change a Workspace view to Unlisted, it becomes a personal view and moves to your "My unlisted views" section. - - - - -## Navigating Between Views - -To switch between views, simply open the view switcher and click the view you wish to open. - -## Customizing Views - -Each view can be customized to streamline your business processes. Views help segment your data. You can customize views using filters, sorts, and field display. - -### Filtering a View - -To filter a view: - -- Click **Filter** > select a field (for example: Name, Company in the People Object). -- Choose a condition, select a value, and apply the filter. -- Add more filters with `+ Add filter` or remove them with **X**. - - - - -### Sorting a View - -Order your fields data in ascending or descending order: -- Select **Sort**, choose a field, and define the sort order you desire. -- You can apply and arrange several sorts as needed. - - - -### Field display - -You can customize which fields to display within a view. To hide a field, click **Options** > **Fields** and select the hide icon upon hover or click on the field column header and select **hide**. - -You can rearrange fields by clicking their field column header and then press **Move Right** or **Move Left**. - -### Opening Record - -To open a record, click on the name in the first column. This action will open the corresponding Record page as a side panel. - - diff --git a/packages/twenty-docs/user-guide/workflows/capabilities/send-emails-from-workflows.mdx b/packages/twenty-docs/user-guide/workflows/capabilities/send-emails-from-workflows.mdx new file mode 100644 index 0000000000..5183c55e48 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/capabilities/send-emails-from-workflows.mdx @@ -0,0 +1,145 @@ +--- +title: Send Emails from Workflows +description: Send personalized emails automatically using workflow actions. +image: /images/user-guide/workflows/workflow.png +--- + +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 + +## 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 + + +**Coming soon**: Email attachments will be available in Q1 2026. + + +## Related + +- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers) +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) diff --git a/packages/twenty-docs/user-guide/workflows/capabilities/use-branches-in-workflows.mdx b/packages/twenty-docs/user-guide/workflows/capabilities/use-branches-in-workflows.mdx new file mode 100644 index 0000000000..7097a9d2bf --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/capabilities/use-branches-in-workflows.mdx @@ -0,0 +1,91 @@ +--- +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 + + +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. + + +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 sends 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 + diff --git a/packages/twenty-docs/user-guide/workflows/capabilities/use-iterator.mdx b/packages/twenty-docs/user-guide/workflows/capabilities/use-iterator.mdx new file mode 100644 index 0000000000..0c75432256 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/capabilities/use-iterator.mdx @@ -0,0 +1,177 @@ +--- +title: Use Iterator +description: Loop through arrays of records to perform actions on each item. +image: /images/user-guide/workflows/workflow.png +--- + +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. + + +Iterator is currently in beta. Activate it under **Settings → Releases → Lab**. + + +## 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 + +## 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) | + +## 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) + diff --git a/packages/twenty-docs/user-guide/workflows/capabilities/workflow-actions.mdx b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-actions.mdx new file mode 100644 index 0000000000..a4e41a9ef8 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-actions.mdx @@ -0,0 +1,265 @@ +--- +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. + + +- 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 + + +## Record Actions + + +### Create a 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. + + +**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. + + +**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. + + +**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. + + + +**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. + +**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. + + +- 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) +- Define the actions to perform on each record in the loop. + +- 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. + + +- 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. + + + + +### 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 + +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`. + + +### 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 + + +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. + + +**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. +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 + +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. + + +For all the following steps, you can reference variables from previous steps for personalization. + +- Enter recipient email address. + +Only one recipient is possible at the moment. + +- Set subject line. +- Compose message body. You can format links, create numbered list, bullet point lists, add attachments. + +Adding HTML signatures is not possible at the moment. + + +### 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. + +**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 notifications center will be released in 2026 to properly support forms in automated workflows. + +**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. Select fields from all objects are available. + - 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`. + +The fields cannot be made mandatory. + + + + + + +## Integration Actions + +### Code +Runs custom JavaScript within your workflow. + +**Configuration**: +- Access variables from previous steps. You can edit the variables names dynamically. + +- Write JavaScript code in the editor +- Return variables for use in subsequent steps +- Test code directly in the step + + +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 serverless function. + + + +**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. + + + +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. + + +### HTTP Request +Sends a request to an external API as part of your workflow. + + + +**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. + + +AI Agent actions consume workflow credits based on the AI model used. See [Workflow Credits](/user-guide/workflows/capabilities/workflow-credits) for details. + + + +AI agents respect role-based permissions. You can assign specific roles to agents under **Settings → Roles** to control what data they can access. See [Permissions](/user-guide/permissions-access/capabilities/permissions) for details. + diff --git a/packages/twenty-docs/user-guide/workflows/capabilities/workflow-branches.mdx b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-branches.mdx new file mode 100644 index 0000000000..0aae418e8a --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-branches.mdx @@ -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. + + +## 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 + + +Each branch is independent. Adding a branch doesn't affect other existing paths from that node. + + +### 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. + + +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." + + + +## 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 + diff --git a/packages/twenty-docs/user-guide/workflows/capabilities/workflow-credits.mdx b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-credits.mdx new file mode 100644 index 0000000000..7e85cd1269 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-credits.mdx @@ -0,0 +1,74 @@ +--- +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 million credits per month | +| **Yearly subscription** | 50 million credits per year | + + +5 million 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. + + +## 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 +- **Manual Trigger Optimization**: For manual triggers, choose `Bulk` availability to process multiple records in a single workflow run +- Optimize Code actions for efficiency +- Batch operations to reduce individual action calls + diff --git a/packages/twenty-docs/user-guide/workflows/capabilities/workflow-runs.mdx b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-runs.mdx new file mode 100644 index 0000000000..48f2b653c8 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-runs.mdx @@ -0,0 +1,84 @@ +--- +title: Workflow Runs +description: Monitor and manage workflow executions. +image: /images/user-guide/workflows/workflow.png +--- + +## 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 +4. 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) diff --git a/packages/twenty-docs/user-guide/workflows/capabilities/workflow-triggers.mdx b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-triggers.mdx new file mode 100644 index 0000000000..82616eb3a4 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-triggers.mdx @@ -0,0 +1,123 @@ +--- +title: Workflow Triggers +description: Learn about the different triggers that start your workflows. +--- + +## About Triggers + +Workflows always start with a single trigger that defines when the automation should run. + + + + +**Advanced objects are supported!** Beyond standard CRM objects (People, Companies, Opportunities), you can also trigger workflows and perform actions on: +- Workspace Members +- Calendar Events +- Messages (Emails) +- Tasks, Notes, and many other system objects + +This opens up powerful automations like notifying team members when calendar events are created, or processing incoming emails automatically. + + +## Record is Created +Starts the workflow when a new record is created in a selected object (People, Companies, Opportunities, or any custom object). + +**Configuration**: Select the object type to monitor for new records. + + +- This trigger is great for records created by csv, mailbox and calendar synchronization, API. +- **It is not recommended for records created manually**: with this trigger, workflows start as soon as the record is created. Since Twenty UI offers auto-save on the fly (there is not an edit mode and then a validation to save records), the workflow will be triggered before the user inputs all the fields. +To trigger this workflow on records created manually, it is recommended to use the trigger `Record is created or updated` instead. + + +## Record is Updated +Starts the workflow when changes are made to an existing record. + +**Configuration**: +- Select the object type +- Optionally specify which fields to monitor for changes + +## Record is Updated or Created +Starts the workflow when a record is either created or updated in a selected object. + +**Why This Matters**: This trigger is particularly helpful because records created via different methods behave differently: +- **API/CSV imports**: Records are created with all fields populated immediately +- **Manual creation**: Records are created first, then fields are added in subsequent updates + +**Configuration**: +- Select the object type to monitor +- Optionally specify which fields to monitor for changes +- The workflow will trigger both on initial creation and any subsequent updates + +## Record is Deleted +Starts the workflow when a record is removed from an object. + +**Configuration**: Select the object type to monitor for deletions. + +## Manual Trigger +Starts the workflow when triggered by a user action. This trigger can be accessed through the `Cmd+K` menu or via a custom button that will be displayed in the top navbar after selecting record(s). + + + +**Availability Configuration**: +Choose how the workflow should handle record selection: + +- **Global**: No record is required to trigger this workflow. The workflow is triggered from the command menu `Cmd + K` anywhere (from any object) and does not use record(s) as input. + +- **Single**: The selected record(s) will be passed to your workflow. This is configured for a given object. Several records can be selected before triggering the workflow. The workflow will run from beginning to end as many times as there are records selected. + + + **Soft limit: 100 runs/minute**. Beyond this, workflows remain in "Not Started" status and are processed gradually—either by a background job or when another workflow enters the queue. This means you can select more than 100 records with a Single trigger; execution will just be slower. + + +- **Bulk**: The selected record(s) will be passed to your workflow. This is configured for a given object. Several records can be selected before triggering the workflow. The workflow will run once, providing the entire list of records as input. This means the workflow needs to contain an [Iterator action](/user-guide/workflows/capabilities/workflow-actions#iterator). + +This is more advanced, and best for people who want to optimize the number of workflow runs. + + + + + +**Additional Configuration**: +- Select the target object (for Single and Bulk availability) +- Choose a command icon for the workflow trigger +- Configure navbar placement (Pinned or Not Pinned) + +**Access Methods**: +- `Cmd+K` menu to find and launch manual workflows +- Custom button in the top navbar (if configured) + +## Time-Based Trigger: On a Schedule + +Starts the workflow on a recurring basis you define. + +**Configuration**: +- Select time unit (minutes, hours, days) +- Enter a value or use custom cron expressions for advanced scheduling + + +**Timezone**: Scheduled workflows run in **UTC**. When setting hours for daily schedules, convert your local time to UTC. + + +## External Trigger: Webhook + +Starts the workflow when a GET or POST request is received from an external service. + + + +**Configuration**: +- The workflow provides a unique webhook URL—copy this and add it to your external system as the endpoint to call. +- For POST requests, define the expected body structure so Twenty knows what data to expect. Add here the fields you will receive that will be needed below in your workflow. +- Configure authentication (coming soon). + +## Choosing the Right Trigger + +| Use Case | Recommended Trigger | +|----------|---------------------| +| New leads need processing | Record is Created | +| Data changes need sync | Record is Updated | +| Import/manual data handling | Record is Updated or Created | +| Cleanup after deletion | Record is Deleted | +| User-initiated action | Launch Manually | +| Recurring reports | On a Schedule | +| External integration | Webhook or On a Schedule| diff --git a/packages/twenty-docs/user-guide/workflows/capabilities/workflow-versions.mdx b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-versions.mdx new file mode 100644 index 0000000000..274debfe0d --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/capabilities/workflow-versions.mdx @@ -0,0 +1,77 @@ +--- +title: Workflow Versions +description: Manage workflow versions and drafts. +image: /images/user-guide/workflows/workflow.png +--- + +## About Versions + +Every time you activate a workflow, a new version is created. This allows you to track changes over time and revert to previous configurations if needed. + +## Version Statuses + +| Status | Description | +|--------|-------------| +| **Draft** | Being edited, not yet published | +| **Active** | Live version responding to triggers | +| **Deactivated** | Previously active but manually stopped | +| **Archived** | Past versions kept for history | + +## Working with Drafts + +When you edit an active workflow, your changes are saved as a **draft**. The active version continues to run while you work on updates. + +Once you're done editing, you can: +- **Activate**: Publish the draft as the new active version (the previous version is archived) +- **Discard**: Delete the draft and keep the current active version + +## Version History + +### Viewing Past Versions +1. Open the workflow +2. Click the **Versions** tab +3. See all previous versions with timestamps + +### Restoring a Version +1. Find the version you want to restore +2. Click **Use as draft** +3. The version is copied to a new draft +4. Make any necessary updates +5. Activate when ready + +## Best Practices + +### Version Management +- Activate only when ready for production +- Keep meaningful changes between versions +- Document major changes in workflow names or descriptions +- Test in draft mode before activating + +### Reverting Changes +- If a new version causes issues, restore the previous version +- Use the version history to track what changed +- Always test restored versions before activating + +## Common Workflows + +### Quick Edit +1. Make minor changes to an active workflow +2. Test in draft mode +3. Activate the new version + +### Major Revision +1. Use the previous version as a starting point +2. Make significant changes in draft +3. Thoroughly test all scenarios +4. Activate when confident + +### Rollback +1. Identify the issue with the current version +2. Find the last working version in history +3. Click **Use as draft** +4. Activate to restore the old behavior + +## Related + +- [Getting Started with Workflows](/user-guide/workflows/overview) +- [Workflow Runs](/user-guide/workflows/capabilities/workflow-runs) diff --git a/packages/twenty-docs/user-guide/workflows/external-tool-integration.mdx b/packages/twenty-docs/user-guide/workflows/external-tool-integration.mdx deleted file mode 100644 index dc132d7d3d..0000000000 --- a/packages/twenty-docs/user-guide/workflows/external-tool-integration.mdx +++ /dev/null @@ -1,197 +0,0 @@ ---- -title: External Tool Integration -info: These workflows focus on bringing data in and out of Twenty through API calls and webhooks. -image: /images/user-guide/integrations/plug.png -sectionInfo: Automate processes and integrate with external tools ---- - - Header - - -Below are workflow examples you could roll out to connect Twenty with the rest of your stack. - - -## Data Ingestion Use Cases - -### Webform Submissions -**Problem**: You need to capture leads from website forms, landing pages, or contact forms directly into Twenty. - -**Solution**: Use webhook triggers to automatically create records from form submissions. - -**Setup**: -- Create a workflow with a Webhook trigger -- Configure the webhook to expect form data (name, email, company, etc.) -- Set the webhook method to POST -- Define the expected body structure in the trigger - -**Trigger**: Webhook (POST request from your form) - -**Actions**: -- Search Records to check if person/company already exists -- Branch: If exists → Update Record, If not → Create Record -- Create Record for follow-up task assigned to sales rep -- Send Email notification to sales team - -### Product Data Synchronization -**Problem**: Your sales team needs visibility into product usage, billing, or feature adoption data stored in your data warehouse. - -**Solution**: Regularly sync product data into Twenty to give sellers context about their accounts. - -**Trigger**: On a Schedule (daily or weekly) - -**Actions**: -- HTTP Request to your data warehouse API -- Code action to process and format the data -- Use the Iterator function for the following steps -- Search Records to find matching company records -- Update Record to add product usage metrics -- Create Record for tasks when usage drops below threshold - -### Meeting Notes from Call Recorders -**Problem**: Important insights from sales calls get lost or aren't properly documented in the CRM. - -**Solution**: Automatically create notes and action items from call recording systems. - -**Trigger**: Webhook (from call recording platform) - -**Actions**: -- Code action to extract meeting summary and action items -- Search Records to find the related opportunity or contact -- Create Record for a note with meeting summary -- Create Record for follow-up tasks based on action items -- Send Email to attendees with summary and next steps - -### Data Enrichment -**Problem**: Your contact and company records lack important demographic and firmographic information. - -**Solution**: Automatically enrich records using external data providers. - -**Trigger**: Record is Created (People or Companies object) - -**Actions**: -- HTTP Request to enrichment API -- Code action to process enrichment response -- Use the Iterator function for the following steps -- Update Record with additional company/contact information -- Create Record for sales task if high-value prospect identified -- Send Email alert if enrichment reveals key buying signals - -## Data Distribution Use Cases - -### Newsletter Subscriber Management -**Problem**: You want to send marketing emails to specific segments of your CRM data using specialized email tools. - -**Solution**: Export subscriber lists to your email marketing platform when needed. - -**Setup**: Create a view in Twenty with all newsletter recipients - -**Trigger**: Launch Manually (when no record is selected) - -**Actions**: -- Search Records using the newsletter view criteria -- Code action to format email addresses for your email platform -- HTTP Request to add subscribers to your email marketing tool -- Create Record for campaign tracking -- Send Email confirmation to marketing team - -### Email Sequence Triggers -**Problem**: You want to trigger sophisticated email sequences based on CRM events using dedicated email automation tools. - -**Solution**: Send new leads or customers to your email automation platform when specific events occur. - -**Trigger**: Record is Created (People object with specific criteria) - -**Actions**: -- Code action to determine appropriate email sequence -- HTTP Request to add contact to email automation platform -- Update Record to track sequence enrollment -- Create Record for follow-up task to monitor engagement - -### Lead Scoring Integration -**Problem**: You need sophisticated lead scoring that combines CRM data with external signals. - -**Solution**: Send lead data to external scoring tools or implement scoring logic within workflows. - -**Option 1 - External Tool**: - -**Trigger**: Record is Updated (People object) - -**Actions**: -- HTTP Request to send lead data to scoring platform -- Code action to process score response -- Update Record with lead score -- Create Record for sales task if score exceeds threshold - -**Option 2 - Internal Logic**: - -**Trigger**: Record is Updated (People object) - -**Actions**: -- Code action with scoring algorithm (company size, industry, behavior) -- Update Record with calculated score -- Send Email alert to sales rep for high-scoring leads - -### Invoice Generation -**Problem**: When deals close, your billing system needs to be updated with customer and deal information. - -**Solution**: Automatically send deal data to your invoicing system when opportunities are won. - -**Trigger**: Record is Updated (Opportunities object, Stage = "Closed Won") - -**Actions**: -- Search Records to get complete customer information -- Code action to format data for billing system -- HTTP Request to create customer in billing platform -- HTTP Request to generate invoice -- Update Record to store invoice reference -- Send Email to finance team with invoice details - -## Advanced Integration Patterns - -### Bi-directional Sync -**Problem**: You need to keep data synchronized between Twenty and another system in both directions. - -**Solution**: Combine scheduled workflows with webhook triggers for real-time sync. - -**From Twenty to External System**: - -**Trigger**: Record is Updated (any relevant object) - -**Actions**: -- HTTP Request to update external system -- Update Record to track sync status and timestamp - -**From External System to Twenty**: - -**Trigger**: Webhook (from external system) - -**Actions**: -- Search Records to find matching record -- Update Record with new data from external system -- Create Record for conflict resolution task if needed - -### Multi-step Data Processing -**Problem**: Data from external sources needs complex processing before it can be used in Twenty. - -**Solution**: Use Code actions for data transformation and validation. - -**Trigger**: Webhook or On a Schedule - -**Actions**: -- Code action to validate incoming data format -- Code action to transform data structure -- Code action to apply business rules and calculations -- Search Records to check for duplicates -- Create or Update Record with processed data -- Send Email alert if data quality issues detected - -## Implementation Tips -- Store API keys securely in Settings → API & Webhooks -- Use HTTPS for all external API calls -- Be mindful of API rate limits - use scheduled workflows when possible -- Consider batch updates "On a Schedule" when real-time processing isn't required -- Remember the 100 concurrent workflow limit per workspace - use "Bulk" availability for manual triggers when processing multiple records (see [Workflow Features](/user-guide/workflows/workflow-features) for details) -- Test with sample data before activating workflows - -For troubleshooting integration issues, see our [Workflow Troubleshooting](/user-guide/workflows/workflow-troubleshooting) guide. For help implementing complex integrations, consider our [Professional Services](/user-guide/workflows/professional-services). - diff --git a/packages/twenty-docs/user-guide/workflows/getting-started-workflows.mdx b/packages/twenty-docs/user-guide/workflows/getting-started-workflows.mdx deleted file mode 100644 index 6554280593..0000000000 --- a/packages/twenty-docs/user-guide/workflows/getting-started-workflows.mdx +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Getting Started With Workflows -info: "Learn how to add automations and ideas to get started." -image: /images/user-guide/workflows/workflow.png -sectionInfo: Automate processes and integrate with external tools ---- - - Header - - -## Why Workflows Matter - -Twenty was built to bring maximum flexibility to its users. Rather than forcing you to adapt your business processes to rigid, pre-built features, workflows enable you to build automations that create the CRM that best supports your unique business use cases. - -Workflows are Twenty's in-app feature for building these automations. They give you the building blocks to create exactly what your business needs, when it needs it. - -## What can I do with workflows? - -We recommend building automations for two main purposes: - -1. **Internal automations to facilitate your team's day-to-day**: Reduce the amount of manual entries and repetitive tasks that slow down your team. -2. **Bring data in and out of Twenty**: Connect Twenty via API calls and webhooks to your database and other tools. - -Let's explore examples of what's possible before diving into the how. - -## 1. Internal Automations - -Your CRM is only helpful if the data is up to date, but no one likes updating it. Use workflows to automate low-value, repeatable tasks and keep your team focused on what matters. - -Examples of what you can automate internally: -- **Data management**: Auto-flag personal emails, lead assignment, data validation -- **Sales processes**: Stage-based updates, churn management, stale opportunity alerts -- **Productivity**: Weekly task reminders, meeting follow-ups, cross-object field synchronization - -For detailed examples and step-by-step guidance, see our [Internal Automations](/user-guide/workflows/internal-automations) guide. - - -## 2. External Integrations - -Connect Twenty with your other tools and data sources to create a unified business system. You can bring data into Twenty from webforms, product databases, call recorders, and enrichment services. You can also send data out to email marketing tools, billing systems, and other business applications. - -Examples of what you can integrate: -- **Data ingestion**: Webform submissions, product data sync, meeting notes, data enrichment -- **Data distribution**: Newsletter management, email sequences, lead scoring, invoice generation - -For detailed integration patterns and implementation guidance, see our [External Tool Integration](/user-guide/workflows/external-tool-integration) guide. - -### What if I don't want to build those connections? -We offer [Professional Services](/user-guide/workflows/professional-services) to help you create the automations you need. -Depending on the scope of your project, we will suggest an [Onboarding pack](https://twenty.com/onboarding-packages) or we will put you in contact with our certified implementation partners. They can create your data model, migrate your data, build your workflows. - -### I'm not sure the connection I need is feasible -Send us a message and we will help you assess the feasibility. - -## Workflow Best Practices - -As you start building workflows, keep these tips in mind: - -- **Edit step names**: Rename your workflow steps to clearly describe what each one does. This helps with maintenance and makes it easier to hand off to coworkers -- **Leverage previous step data**: You can use fields from records returned by any previous step in your workflow -- **Start simple**: Begin with basic workflows and add complexity over time as you become more comfortable with the system -- **Plan before building**: Map out your workflow logic before you start building to avoid getting stuck halfway through -- **Use branches wisely**: After a `Search Records` step, create branches to handle both "update existing record" and "create new record" scenarios, then merge the paths back together - - -## What we're working on -Here are the main items we're working on to improve workflows: -- Loops (Iterator is currently in beta, activate it under Settings → Releases → Lab) -- If / Else step -- AI agent to build workflows on your behalf - - - diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions.mdx new file mode 100644 index 0000000000..cc285a9762 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions.mdx @@ -0,0 +1,80 @@ +--- +title: Handle Arrays in Code Actions +description: Learn how to properly handle array inputs in workflow Code actions. +--- + +When working with arrays in Code actions, you may encounter two common challenges: +1. **Arrays passed as strings** — data from external systems or previous steps arrives as a string instead of an actual array +2. **Can't select individual items** — you can only select the entire array, not specific fields within it + +Both can be solved with a Code node. + +## Parsing Arrays from Strings + +Arrays are often passed between workflow steps as strings or JSON rather than native arrays. This happens when: +- Receiving data from external APIs via HTTP Request +- Processing webhook payloads +- Passing data between workflow steps + +**Solution**: Add this pattern at the start of your Code action: + +```javascript +export const main = async (params: { + users: any; +}): Promise => { + const { users } = params; + + // Handle input that may come as a string or an array + const usersFormatted = typeof users === "string" ? JSON.parse(users) : users; + + // Now you can safely work with usersFormatted as an array + return { + users: usersFormatted.map((user) => ({ + ...user, + activityStatus: String(user.activityStatus).toUpperCase(), + })), + }; +}; +``` + +The key line `typeof users === "string" ? JSON.parse(users) : users` checks if the input is a string, parses it if needed, or uses it directly if it's already an array. + +## Extracting Individual Fields from Arrays + +A webhook might return an array like `answers: [...]`, but in subsequent workflow steps you can only select the **entire array** — not individual items within it. + +**Solution**: Add a Code node to extract specific fields and return them as a structured object: + +```javascript +export const main = async (params: { + answers: any; +}): Promise => { + const { answers } = params; + + // Handle input that may come as a string or an array + const answersFormatted = typeof answers === "string" + ? JSON.parse(answers) + : answers; + + // Extract specific fields from the array + const firstname = answersFormatted[0]?.text || ""; + const name = answersFormatted[1]?.text || ""; + + return { + answer: { + firstname, + name + } + }; +}; +``` + +The Code node returns a structured object instead of an array. In subsequent steps, you can now select individual fields like `answer.firstname` and `answer.name` from the variable picker. + + +We're actively working on making array handling easier in future updates. + + + +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. + diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty.mdx new file mode 100644 index 0000000000..3f3cc9be09 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/bring-product-data-in-twenty.mdx @@ -0,0 +1,182 @@ +--- +title: Bring Product Data into Twenty +description: Sync product catalog data from a data warehouse into your CRM on a schedule. +--- + +Use this pattern to keep Twenty in sync with product data from your data warehouse (e.g., Snowflake, BigQuery, PostgreSQL). + +## Workflow Structure + +1. **Trigger**: On a Schedule +2. **Code**: Query your data warehouse +3. **Code** (optional): Format data as array +4. **Iterator**: Loop through each product +5. **Upsert Record**: Create or update in Twenty + + + + +## Step 1: Schedule the Trigger + +Set the workflow to run at a frequency matching your data freshness needs: +- Every 5 minutes for near real-time sync +- Every hour for less critical data +- Daily for batch updates + +## Step 2: Query Your Data Warehouse + +Add a **Code** action to fetch recent data: + +```javascript +export const main = async () => { + const intervalMinutes = 10; // Match your schedule frequency + const cutoffTime = new Date(Date.now() - intervalMinutes * 60 * 1000).toISOString(); + + // Replace with your actual data warehouse connection + const response = await fetch("https://your-warehouse-api.com/query", { + method: "POST", + headers: { + "Authorization": "Bearer YOUR_API_KEY", + "Content-Type": "application/json" + }, + body: JSON.stringify({ + query: ` + SELECT id, name, sku, price, stock_quantity, updated_at + FROM products + WHERE updated_at >= '${cutoffTime}' + ` + }) + }); + + const data = await response.json(); + return { products: data.results }; +}; +``` + + +Filter by `updated_at >= last X minutes` to retrieve only recently changed records. This keeps the sync efficient. + + +## Step 3: Format Data (Optional) + +If your warehouse returns data in a format that needs transformation, add another **Code** action. Common transformations include type conversions, field renaming, and data cleanup. + +### Example: User Data with Boolean and Status Fields + +```javascript +export const main = async (params: { + users: any; +}): Promise => { + const { users } = params; + const usersFormatted = typeof users === "string" ? JSON.parse(users) : users; + + // Convert string "true"/"false" to actual booleans + const toBool = (v: any) => v === true || v === "true"; + + return { + users: usersFormatted.map((user) => ({ + ...user, + activityStatus: String(user.activityStatus).toUpperCase(), + isActiveLast30d: toBool(user.isActiveLast30d), + isActiveLast7d: toBool(user.isActiveLast7d), + isActiveLast24h: toBool(user.isActiveLast24h), + isTwenty: toBool(user.isTwenty), + })), + }; +}; +``` + +### Example: Product Data with Type Conversions + +```javascript +export const main = async (params: { products: any }) => { + const products = typeof params.products === "string" + ? JSON.parse(params.products) + : params.products; + + return { + products: products.map(product => ({ + externalId: product.id, + name: product.name, + sku: product.sku, + price: parseFloat(product.price), // String → Number + stockQuantity: parseInt(product.stock_quantity), + isActive: product.status === "active" // String → Boolean + })) + }; +}; +``` + +### Example: Date and Currency Formatting + +```javascript +export const main = async (params: { deals: any }) => { + const deals = typeof params.deals === "string" + ? JSON.parse(params.deals) + : params.deals; + + return { + deals: deals.map(deal => ({ + ...deal, + // Convert Unix timestamp to ISO date + closedAt: deal.closed_timestamp + ? new Date(deal.closed_timestamp * 1000).toISOString() + : null, + // Ensure amount is a number (remove currency symbols) + amount: parseFloat(String(deal.amount).replace(/[^0-9.-]/g, "")), + // Normalize stage names + stage: deal.stage?.toLowerCase().replace(/_/g, " ") + })) + }; +}; +``` + +### Common Transformations + +| Source Format | Target Format | Code | +|---------------|---------------|------| +| `"true"` / `"false"` | `true` / `false` | `v === true \|\| v === "true"` | +| `"123.45"` | `123.45` | `parseFloat(value)` | +| `"active"` | `"ACTIVE"` | `value.toUpperCase()` | +| `1704067200` (Unix) | ISO date | `new Date(v * 1000).toISOString()` | +| `"$1,234.56"` | `1234.56` | `parseFloat(v.replace(/[^0-9.-]/g, ""))` | +| `null` / `undefined` | `""` | `value \|\| ""` | + +## Step 4: Iterate Through Products + +Add an **Iterator** action: +- Input: `{{code.products}}` + +This loops through each product in the array. + +## Step 5: Upsert Each Record + +Inside the iterator, add an **Upsert Record** action: + +| Setting | Value | +|---------|-------| +| **Object** | Your custom Product object | +| **Match by** | External ID or SKU (unique identifier) | +| **Name** | `{{iterator.item.name}}` | +| **SKU** | `{{iterator.item.sku}}` | +| **Price** | `{{iterator.item.price}}` | + + +Use **Upsert** (update or create) instead of building separate branches for create vs. update. It's faster to build and easier to debug. + + +## Example Use Cases + +| Source | Data | +|--------|------| +| **ERP system** | Product catalog, pricing, inventory | +| **E-commerce platform** | Orders, customers, product updates | +| **Data warehouse** | Aggregated metrics, enriched data | +| **Inventory system** | Stock levels, reorder alerts | + +## Related + +- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers) +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) +- [Handle Arrays in Code Actions](/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions) + diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty.mdx new file mode 100644 index 0000000000..9e34574c53 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/bring-typeform-submissions-in-twenty.mdx @@ -0,0 +1,130 @@ +--- +title: Bring Typeform Submissions into Twenty +description: Handle Typeform's webhook payload to create leads from form submissions. +--- + +For standard webhook setup, see [Set Up a Webhook Trigger](/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger). This article covers the specific handling required for Typeform's custom payload structure. + +### Step 1: Create a Webhook Workflow + +1. Go to **Settings → Workflows** +2. Click **+ New Workflow** +3. Select **Webhook** as the trigger +4. Copy the webhook URL + +### Step 2: Configure Typeform + +1. In Typeform, open your form +2. Go to **Connect → Webhooks** +3. Paste your Twenty webhook URL +4. Save + +### Step 3: Understand the Typeform Payload + +Typeform sends a nested JSON structure. Here's a simplified example: + +```json +{ + "event_type": "form_response", + "form_response": { + "form_id": "abc123", + "submitted_at": "2025-01-15T10:30:00Z", + "answers": [ + { + "text": "Jane", + "type": "text", + "field": { "id": "field1", "type": "short_text", "title": "First Name" } + }, + { + "text": "Smith", + "type": "text", + "field": { "id": "field2", "type": "short_text", "title": "Last Name" } + }, + { + "text": "Acme Corp", + "type": "text", + "field": { "id": "field3", "type": "short_text", "title": "Company" } + }, + { + "email": "jane@acme.com", + "type": "email", + "field": { "id": "field4", "type": "email", "title": "Email" } + }, + { + "type": "choice", + "field": { "id": "field5", "type": "dropdown", "title": "Team Size" }, + "choice": { "label": "10-50" } + } + ] + } +} +``` + +Key things to note: +- Form data is nested under `form_response` +- **Answers are returned as an array**, not as named fields +- Each answer includes the field type and title for reference + +### Step 4: Extract Fields from the Answers Array + +Since `answers` is an array, you can only select the entire array in subsequent steps — not individual fields. Add a **Code** action to extract the fields you need: + +```javascript +export const main = async (params: { + answers: any; +}): Promise => { + const { answers } = params; + + // Handle input that may come as a string or an array + const answersFormatted = typeof answers === "string" + ? JSON.parse(answers) + : answers; + + // Extract fields by position or by finding the field type + const firstName = answersFormatted[0]?.text || ""; + const lastName = answersFormatted[1]?.text || ""; + const company = answersFormatted[2]?.text || ""; + const email = answersFormatted.find(a => a.type === "email")?.email || ""; + const teamSize = answersFormatted.find(a => a.type === "choice")?.choice?.label || ""; + + return { + contact: { + firstName, + lastName, + company, + email, + teamSize + } + }; +}; +``` + +Now in subsequent steps, you can select `contact.firstName`, `contact.email`, etc. from the variable picker. + + +For more details on handling arrays in Code actions, see [Handle Arrays in Code Actions](/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions). + + +### Step 5: Create the Record + +Add a **Create Record** action: + +| Field | Value | +|-------|-------| +| **Object** | People | +| **First Name** | `{{code.contact.firstName}}` | +| **Last Name** | `{{code.contact.lastName}}` | +| **Email** | `{{code.contact.email}}` | +| **Company** | Search or create based on `{{code.contact.company}}` | + +### Step 6: Test and Activate + +1. Submit a test response in Typeform +2. Check the workflow run to verify data was captured +3. Activate the workflow + +## Related + +- [Set Up a Webhook Trigger](/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger) +- [Handle Arrays in Code Actions](/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions) + diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty.mdx new file mode 100644 index 0000000000..c6f433d258 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/generate-quote-or-invoice-from-twenty.mdx @@ -0,0 +1,144 @@ +--- +title: Generate a Quote or Invoice from Twenty +description: Automatically create invoices in external tools when deals close. +--- + +Automatically send deal data to your invoicing system (Stripe, QuickBooks, Xero, etc.) when an opportunity is won. + +## Workflow Structure + +1. **Trigger**: Record is Updated (Opportunity) +2. **Filter**: Stage = Closed Won +3. **Search Record**: Get Company details +4. **Code** (optional): Format payload +5. **HTTP Request**: Send to invoicing system + +## Step 1: Set Up the Trigger + +1. Create a new workflow +2. Select **Record is Updated** trigger +3. Choose **Opportunity** as the object + +## Step 2: Filter for Closed Won + +Add a **Filter** action to only continue when the deal is won: + +| Setting | Value | +|---------|-------| +| **Field** | Stage | +| **Condition** | Equals | +| **Value** | `CLOSED_WON` (or your stage name) | + + +The trigger fires on any Opportunity update. The Filter ensures the workflow only continues when the stage changes to Closed Won. + + +## Step 3: Get Company Details + +The Opportunity record may not include all Company fields you need for the invoice. Add a **Search Record** action: + +| Setting | Value | +|---------|-------| +| **Object** | Company | +| **Match by** | ID equals `{{trigger.object.companyId}}` | + +This retrieves the full Company record with billing address, tax ID, etc. + +## Step 4: Format the Payload (Optional) + +If your invoicing system expects a specific format, add a **Code** action: + +```javascript +export const main = async (params: { + opportunity: any; + company: any; +}): Promise => { + const { opportunity, company } = params; + + return { + invoice: { + // Customer info from Company + customer_name: company.name, + customer_email: company.email || "", + billing_address: { + line1: company.address?.street || "", + city: company.address?.city || "", + postal_code: company.address?.postalCode || "", + country: company.address?.country || "" + }, + tax_id: company.taxId || null, + + // Invoice details from Opportunity + amount: opportunity.amount, + currency: opportunity.currency || "USD", + description: `Invoice for ${opportunity.name}`, + due_days: 30, + + // Reference back to Twenty + metadata: { + opportunity_id: opportunity.id, + company_id: company.id + } + } + }; +}; +``` + +## Step 5: Send to Invoicing System + +Add an **HTTP Request** action: + +| Setting | Value | +|---------|-------| +| **Method** | POST | +| **URL** | Your invoicing API endpoint | +| **Headers** | `Authorization: Bearer YOUR_API_KEY` | +| **Body** | `{{code.invoice}}` or map fields directly | + +### Example: Stripe Invoice + +``` +POST https://api.stripe.com/v1/invoices +Headers: + Authorization: Bearer sk_live_xxx + Content-Type: application/x-www-form-urlencoded + +Body: + customer: {{company.stripeCustomerId}} + collection_method: send_invoice + days_until_due: 30 +``` + +### Example: QuickBooks Invoice + +``` +POST https://quickbooks.api.intuit.com/v3/company/{realmId}/invoice +Headers: + Authorization: Bearer YOUR_ACCESS_TOKEN + Content-Type: application/json + +Body: {{code.invoice}} +``` + +## Complete Workflow Summary + +| Step | Action | Purpose | +|------|--------|---------| +| 1 | Trigger: Record Updated | Fires when any Opportunity changes | +| 2 | Filter | Only proceed if Stage = Closed Won | +| 3 | Search Record | Get full Company details for billing | +| 4 | Code | Format data for invoicing API | +| 5 | HTTP Request | Create invoice in external system | + +## Tips + +- **Store external IDs**: Save the invoice ID returned by the API back to the Opportunity using an **Update Record** action +- **Error handling**: Add a branch to send a notification if the HTTP request fails +- **Test first**: Use your invoicing system's sandbox/test mode before going live + +## Related + +- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers) +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) +- [Closed Won Automations](/user-guide/workflows/how-tos/crm-automations/closed-won-automations) + diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger.mdx new file mode 100644 index 0000000000..3e80a76488 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger.mdx @@ -0,0 +1,169 @@ +--- +title: Set Up a Webhook Trigger +description: Receive data from external services to trigger workflows. +image: /images/user-guide/workflows/workflow.png +--- + +Webhook triggers allow external services to start your workflows by sending data to a unique URL. Use them to connect forms, third-party apps, and custom integrations. + +## When to Use Webhooks + +| Use Case | Example | +|----------|---------| +| **Web forms** | Contact form submissions create leads | +| **Third-party apps** | Stripe payment → create customer record | +| **Custom integrations** | Your app → Twenty automation | +| **No-code tools** | Zapier, Make, n8n connections | + +## Step-by-Step Setup + +### Step 1: Create the Workflow + +1. Go to **Settings → Workflows** +2. Click **+ New Workflow** +3. Name it (e.g., "Website Form Submission") + +### Step 2: Configure the Webhook Trigger + +1. Click on the trigger block +2. Select **Webhook** +3. You'll receive a unique webhook URL like: + ``` + https://api.twenty.com/webhooks/workflow/abc123... + ``` +4. Copy this URL—you'll need it for your external service + +### Step 3: Define Expected Data Structure + +For **POST** requests, define the expected body structure: + +1. Click **Define expected body** +2. Enter a sample JSON that matches what your service will send: + +```json +{ + "firstName": "John", + "lastName": "Doe", + "email": "john@example.com", + "company": "Acme Inc", + "message": "Interested in your product" +} +``` + +3. Click **Save**—this creates variables you can use in subsequent steps + +### Step 4: Add Actions + +Now add actions that use the webhook data: + +**Example: Create a Person record** + +1. Add **Create Record** action +2. Select **People** object +3. Map fields: + +| Field | Value | +|-------|-------| +| First Name | `{{trigger.body.firstName}}` | +| Last Name | `{{trigger.body.lastName}}` | +| Email | `{{trigger.body.email}}` | +| Company | Search or create based on `{{trigger.body.company}}` | + +### Step 5: Test the Webhook + +Before activating, test your webhook: + +**Using cURL**: +```bash +curl -X POST https://api.twenty.com/webhooks/workflow/abc123... \ + -H "Content-Type: application/json" \ + -d '{"firstName":"Test","lastName":"User","email":"test@example.com"}' +``` + +**Using Postman or similar**: +1. Create a POST request to your webhook URL +2. Set Content-Type header to `application/json` +3. Add your test JSON body +4. Send and check workflow runs + +### Step 6: Activate + +Once tested, click **Activate** to make the workflow live. + +## Handling Different Data Structures + +### Nested Data + +If your webhook sends nested data: +```json +{ + "contact": { + "name": "John Doe", + "email": "john@example.com" + }, + "source": "website" +} +``` + +Reference with: `{{trigger.body.contact.email}}` + +### Arrays + +If data includes arrays: +```json +{ + "items": [ + {"name": "Product A", "qty": 2}, + {"name": "Product B", "qty": 1} + ] +} +``` + +How you handle arrays depends on your use case: + +**Unknown number of items → Use Iterator** + +If you need to process each item in the array (e.g., create a record for each), add a **Code** action to parse the array, then use **Iterator**: + +```javascript +export const main = async (params: { items: any }) => { + const items = typeof params.items === "string" + ? JSON.parse(params.items) + : params.items; + return { items }; +}; +``` + +Then use Iterator to loop through: `{{code.items}}` + +**Known/specific fields → Extract to named fields** + +If the array contains specific fields you want to access individually (e.g., form answers where position 0 is always "first name", position 1 is always "last name"), add a **Code** action to extract them: + +```javascript +export const main = async (params: { items: any }) => { + const items = typeof params.items === "string" + ? JSON.parse(params.items) + : params.items; + + return { + product: { + name: items[0]?.name || "", + qty: items[0]?.qty || 0 + } + }; +}; +``` + +Now you can select `product.name` and `product.qty` individually in subsequent steps. + + +For more details on handling arrays, see [Handle Arrays in Code Actions](/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions). + + + +## Related + +- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers) +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) + diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/closed-won-automations.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/closed-won-automations.mdx new file mode 100644 index 0000000000..550a20ef6d --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/closed-won-automations.mdx @@ -0,0 +1,170 @@ +--- +title: Closed Won Automations +description: Automate post-win activities when opportunities close. +--- + +When a deal closes, multiple things need to happen: update company status, notify team members, create onboarding tasks. Automate all of this with a single workflow. + +## The Problem + +When an opportunity moves to "Closed Won": +- Company type needs to change from "Prospect" to "Customer" +- Onboarding tasks need to be created +- Customer success team needs to be notified +- Sales rep needs confirmation + +Doing this manually is time-consuming and error-prone. + +## The Solution + +Create a workflow that handles all post-win activities automatically. + +## Complete Workflow Setup + +### Step 1: Create the Workflow + +1. Go to **Settings → Workflows** +2. Click **+ New Workflow** +3. Name it "Deal Won - Post-Win Automation" + +### Step 2: Configure the Trigger + +1. Select **Record is Updated** +2. Choose **Opportunities** +3. Under "Fields to monitor", select **Stage** + +### Step 3: Add Stage Filter + +1. Add **Filter** action +2. Condition: `{{trigger.object.stage}}` equals "Closed Won" + +### Step 4: Update Company Type + +1. Add **Update Record** action +2. Configure: + +| Field | Value | +|-------|-------| +| **Object** | Companies | +| **Record** | `{{trigger.object.company.id}}` | +| **Type** | Customer | +| **First Deal Date** | `{{trigger.object.closedAt}}` | +| **Account Owner** | `{{trigger.object.owner.id}}` | + +### Step 5: Create Onboarding Task + +1. Add **Create Record** action +2. Configure: + +| Field | Value | +|-------|-------| +| **Object** | Tasks | +| **Title** | `Onboarding: {{trigger.object.name}}` | +| **Assignee** | Customer Success team member | +| **Due Date** | 3 days from now | +| **Priority** | High | +| **Related Company** | `{{trigger.object.company.id}}` | +| **Related Opportunity** | `{{trigger.object.id}}` | +| **Description** | `New customer onboarding for {{trigger.object.company.name}}. Deal value: {{trigger.object.amount}}` | + +### Step 6: Notify Customer Success + +1. Add **Send Email** action +2. Configure: + +| Field | Value | +|-------|-------| +| **To** | customer-success@yourcompany.com | +| **Subject** | `🎉 New Customer: {{trigger.object.company.name}}` | +| **Body** | See example below | + +**Email body example**: +``` +Hi CS Team, + +We have a new customer! + +Company: {{trigger.object.company.name}} +Deal: {{trigger.object.name}} +Value: {{trigger.object.amount}} +Sales Rep: {{trigger.object.owner.name}} +Close Date: {{trigger.object.closedAt}} + +An onboarding task has been created automatically. + +Let's give them a great start! +``` + +### Step 7: Confirm to Sales Rep + +1. Add another **Send Email** action +2. Configure: + +| Field | Value | +|-------|-------| +| **To** | `{{trigger.object.owner.email}}` | +| **Subject** | `✅ Deal Closed: {{trigger.object.name}}` | +| **Body** | Congratulations! Your deal has been processed. The customer success team has been notified and onboarding has begun. | + +### Step 8: Test and Activate + +1. Test by moving a test opportunity to "Closed Won" +2. Verify: + - Company type changed to "Customer" + - Onboarding task created + - CS team received email + - Sales rep received confirmation +3. Activate when ready + +## Handling Closed Lost + +Create a similar workflow for lost deals: + +### Trigger +- Record is Updated (Opportunities, Stage = "Closed Lost") + +### Actions +1. **Create Record**: Task for "Lost Deal Analysis" +2. **Update Record**: Add lost reason to company record +3. **Send Email**: Notify manager of lost deal + +## Advanced: Multi-Step Onboarding + +For complex onboarding, create multiple tasks: + +```javascript +export const main = async (params) => { + const tasks = [ + { title: "Welcome call", daysFromNow: 1, assignee: "CS" }, + { title: "Send onboarding materials", daysFromNow: 2, assignee: "CS" }, + { title: "Technical setup", daysFromNow: 5, assignee: "Support" }, + { title: "30-day check-in", daysFromNow: 30, assignee: "CS" } + ]; + + return { tasks }; +}; +``` + +Use **Iterator** to create each task from the array. + +## Customization Ideas + +### Keep your other tools up-to-date +- Create customer in billing system with an **HTTP Request** + +### Conditional Actions +Use **Filter** actions to: +- Different onboarding for enterprise vs SMB +- Different assignees based on region +- Skip notifications for small deals + +### Include Deal Details +Use **Code** action to format: +- Deal summary documents +- Handoff notes for CS team +- Custom onboarding checklists + +## Related + +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) +- [Send Emails from Workflows](/user-guide/workflows/capabilities/send-emails-from-workflows) diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/detect-stale-opportunities.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/detect-stale-opportunities.mdx new file mode 100644 index 0000000000..2ddb9fbf47 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/detect-stale-opportunities.mdx @@ -0,0 +1,133 @@ +--- +title: Detect Stale Opportunities +description: Automatically notify managers when opportunities haven't been updated. +--- + +Keep your pipeline healthy by alerting managers when opportunities go stale. This workflow checks for opportunities that haven't been updated in a specified number of days. + +## The Problem + +Opportunities sitting without updates lead to: +- Deals going cold +- Unreliable forecasts +- Lost revenue + +## The Solution + +Create a scheduled workflow that finds stale opportunities and emails their managers. + +## Step-by-Step Setup + +### Step 1: Create the Workflow + +1. Go to **Settings → Workflows** +2. Click **+ New Workflow** +3. Name it "Stale Opportunity Alert" + +### Step 2: Configure the Trigger + +1. Select **On a Schedule** +2. Set to run daily (e.g., every day at 8 AM) + +### Step 3: Search for Stale Opportunities + +1. Add **Search Records** action +2. Configure: + +| Field | Value | +|-------|-------| +| **Object** | Opportunities | +| **Filter** | Updated At is before (today - 7 days) | +| **Filter** | Stage is not "Closed Won" AND not "Closed Lost" | +| **Limit** | 100 | + +### Step 4: Check If Any Found + +1. Add **Filter** action +2. Condition: `{{searchRecords.length}}` is greater than 0 +3. If no stale opportunities, the workflow stops here + +### Step 5: Format the Alert (Code Action) + +Add a **Code** action to format the email: + +```javascript +export const main = async (params) => { + const opportunities = params.opportunities; + + // Group opportunities by owner + const byOwner = {}; + opportunities.forEach(opp => { + const ownerEmail = opp.owner?.email || 'unassigned'; + if (!byOwner[ownerEmail]) { + byOwner[ownerEmail] = []; + } + byOwner[ownerEmail].push({ + name: opp.name, + amount: opp.amount, + lastUpdated: opp.updatedAt, + stage: opp.stage + }); + }); + + // Format summary for manager + let summary = "Stale Opportunities Report\n\n"; + Object.entries(byOwner).forEach(([owner, opps]) => { + summary += `${owner}: ${opps.length} stale opportunities\n`; + opps.forEach(opp => { + summary += ` - ${opp.name} (${opp.stage})\n`; + }); + summary += "\n"; + }); + + return { + summary, + totalCount: opportunities.length + }; +}; +``` + +### Step 6: Send Alert Email + +Add **Send Email** action: + +| Field | Value | +|-------|-------| +| **To** | sales-manager@yourcompany.com | +| **Subject** | `🚨 {{code.totalCount}} Stale Opportunities Need Attention` | +| **Body** | `{{code.summary}}` | + +### Step 7: Test and Activate + +1. Click **Test** to run the workflow +2. Check that the email contains the right data +3. Activate when ready + +## Customization Options + +### Change Staleness Threshold + +Modify the Search Records filter to change from 7 days to your preferred period: +- 3 days for high-velocity sales +- 14 days for enterprise deals +- 30 days for long sales cycles + +### Alert Individual Reps + +Instead of one manager email, use **Iterator** to send personalized emails to each rep about their own stale deals. + +### Add Escalation + +Create multiple workflows with increasing severity: +1. Day 7: Email to rep +2. Day 14: Email to rep + manager +3. Day 21: Create task for manager to intervene + +### Include in Slack + +Use **HTTP Request** to post to a Slack webhook instead of or in addition to email. + +## Related + +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) +- [Send Emails from Workflows](/user-guide/workflows/capabilities/send-emails-from-workflows) diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/display-related-record-data.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/display-related-record-data.mdx new file mode 100644 index 0000000000..c240c40e34 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/display-related-record-data.mdx @@ -0,0 +1,165 @@ +--- +title: Display Related Record Data +description: Show data from related records (e.g., Company info on Opportunities) using workflows. +--- + +Display data from related records directly on your records — for example, show the employee count from a Company on its Opportunities. This workflow workaround is useful until nested fields are natively available. + +## Common Use Cases + +| Source | Destination | Fields to Copy | +|--------|-------------|----------------| +| Company | Opportunity | Industry, Company Size, ARR | +| Person | Opportunity | Email, Phone, Title | +| Opportunity | Company | Last Deal Amount, Last Won Date | + +## Basic Field Copy + +### Example: Copy Contact Email to Opportunity + +**Goal**: When setting a Point of Contact on an opportunity, copy their email to the opportunity for easy access. + +### Prerequisite + +Create the destination fields in **Settings → Data Model → Opportunities** before building the workflow: +- Contact Email (type: Email) +- Contact Phone (type: Phone) + +### Setup + +1. **Trigger**: Record is Updated (Opportunities, Point of Contact field) + +2. **Filter**: Check that Point of Contact is not empty + +3. **Search Records**: Find the linked person + - Object: People + - Filter: ID equals `{{trigger.object.pointOfContact.id}}` + +4. **Update Record**: + - Object: Opportunities + - Record: `{{trigger.object.id}}` + - Contact Email: `{{searchRecords[0].email}}` + - Contact Phone: `{{searchRecords[0].phone}}` + +## Copy Multiple Fields + +### Example: Sync Company Info to All Related Opportunities + +**Goal**: When company details change, update all related opportunities. + +### Setup + +1. **Trigger**: Record is Updated (Companies) + - Fields: Industry, Company Size, Annual Revenue + +2. **Search Records**: Find all opportunities for this company + - Object: Opportunities + - Filter: Company ID equals `{{trigger.object.id}}` + +3. **Iterator**: Loop through each opportunity + +4. **Update Record** (inside iterator): + - Object: Opportunities + - Record: `{{iterator.currentItem.id}}` + - Company Industry: `{{trigger.object.industry}}` + - Company Size: `{{trigger.object.companySize}}` + - Company ARR: `{{trigger.object.annualRevenue}}` + +## Copy on Record Creation + +### Example: Pre-fill Opportunity with Company Data + +**Goal**: When creating an opportunity linked to a company, automatically copy key company info. + +### Prerequisite + +Create the destination fields in **Settings → Data Model → Opportunities**: +- Company Industry (type: Text) +- Company Size (type: Number) + +### Setup + +1. **Trigger**: Record is Created (Opportunities) + - Filter: Company is not empty + +2. **Search Records**: Get the linked company's details + - Object: Companies + - Filter: ID equals `{{trigger.object.company.id}}` + +3. **Update Record**: + - Object: Opportunities + - Record: `{{trigger.object.id}}` + - Company Industry: `{{searchRecords[0].industry}}` + - Company Size: `{{searchRecords[0].employees}}` + + +**Tasks and Notes limitation**: Relations on Tasks and Notes are hardcoded as many-to-many and are not yet available in workflow triggers or actions. To access these relations, use the [API](/developers/extend/capabilities/apis) instead. + + +## Bidirectional Sync + +### Example: Keep Primary Contact in Sync + +**Goal**: When a company's primary contact changes, update the contact. When a person becomes primary, update the company. + +### Workflow 1: Company → Person + +1. **Trigger**: Record is Updated (Companies, Primary Contact field) +2. **Update Record**: Set person's "Is Primary Contact" to true +3. **Search Records**: Find previous primary contact +4. **Update Record**: Set previous contact's "Is Primary Contact" to false + +### Workflow 2: Person → Company + +1. **Trigger**: Record is Updated (People, Is Primary Contact = true) +2. **Update Record**: Set company's Primary Contact to this person + + +Be careful with bidirectional syncs to avoid infinite loops. Use filters to check if the value actually changed before updating. + + +## Using Code for Complex Mapping + +### Example: Transform Data During Copy + +**Goal**: Copy and format phone number from person to opportunity. + +```javascript +export const main = async (params) => { + const { phone } = params; + + if (!phone) return { formattedPhone: null }; + + // Remove non-numeric characters + const digits = phone.replace(/\D/g, ''); + + // Format as (XXX) XXX-XXXX + const formatted = digits.length === 10 + ? `(${digits.slice(0,3)}) ${digits.slice(3,6)}-${digits.slice(6)}` + : phone; + + return { formattedPhone: formatted }; +}; +``` + +## Best Practices + +### Avoid Loops +- Don't create workflows that trigger each other endlessly +- Use specific field conditions +- Add checks to see if value actually changed + +### Handle Missing Data +- Always check if source record exists before copying +- Provide default values for optional fields +- Use filters to skip when source field is empty + +### Performance +- Batch updates when copying to many records +- Use scheduled workflows for bulk sync operations +- Consider using Iterator for multiple record updates + +## Related + +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) +- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers) diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/formula-fields.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/formula-fields.mdx new file mode 100644 index 0000000000..c26b6581c0 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/formula-fields.mdx @@ -0,0 +1,199 @@ +--- +title: Formula Fields +description: Create formula fields using workflows until native support is available. +--- + +Twenty doesn't yet support native formula fields yet (coming in 2026), but you can achieve the same result using workflows. This workaround lets you automatically calculate and populate field values—from simple concatenations to complex business logic. + +## Common Use Cases + +| Use Case | Formula Example | +|----------|-----------------| +| **Full name** | First Name + " " + Last Name | +| **Expected amount** | Amount × Probability | +| **Days until due** | Due Date - Today | +| **Days in stage** | Today - Stage Entry Date | +| **Lead score** | Points based on multiple criteria | + + +For a complete example of tracking time in pipeline stages, see [Track How Long Opportunities Stay in Each Stage](/user-guide/views-pipelines/how-tos/track-time-in-stage). + + +## Basic Formula: Concatenation + +### Example: Auto-Fill Full Name + +**Goal**: Automatically combine first and last name into a full name field. + +### Setup + +1. **Trigger**: Record is Updated or Created (People) + +2. **Filter**: Check that first name or last name changed + +3. **Code action**: + +```javascript +export const main = async (params) => { + const { firstName, lastName } = params; + + const fullName = [firstName, lastName] + .filter(Boolean) + .join(' '); + + return { fullName }; +}; +``` + +4. **Update Record**: Set Full Name to `{{code.fullName}}` + +## Numeric Formula: Expected Amount + +### Example: Calculate Expected Revenue + +**Goal**: Multiply opportunity amount by probability to get expected amount. + +See [How to Show Expected Amount in Pipeline](/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline) for the complete workflow. + +### Quick Setup + +1. **Trigger**: Record is Updated (Opportunities, Amount OR Probability field) + +2. **Code action**: + +```javascript +export const main = async (params) => { + const { amount, probability } = params; + + const expectedAmount = (amount || 0) * (probability || 0) / 100; + + return { expectedAmount }; +}; +``` + +3. **Update Record**: Set Expected Amount to `{{code.expectedAmount}}` + +## Date Formula: Days Calculation + +### Example: Days Until Task Due + +**Goal**: Calculate how many days remain until a task's due date. + +### Setup + +1. **Trigger**: Record is Updated or Created (Tasks, Due Date field) + +2. **Code action**: + +```javascript +export const main = async (params) => { + const { dueDate } = params; + + if (!dueDate) { + return { daysUntilDue: null }; + } + + const due = new Date(dueDate); + const today = new Date(); + const diffTime = due - today; + const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); + + return { daysUntilDue: diffDays }; +}; +``` + +3. **Update Record**: Set Days Until Due to `{{code.daysUntilDue}}` + + +Negative values indicate overdue tasks. You can use this field to filter or sort tasks by urgency. + + +## Conditional Formula: Lead Score + +### Example: Calculate Lead Score Based on Criteria + +**Goal**: Score leads based on company size, industry, and engagement. + +### Setup + +1. **Trigger**: Record is Updated (People or Companies) + +2. **Code action**: + +```javascript +export const main = async (params) => { + const { companySize, industry, hasEmail, hasPhone, source } = params; + + let score = 0; + + // Company size scoring + if (companySize === 'Enterprise') score += 30; + else if (companySize === 'Mid-Market') score += 20; + else if (companySize === 'SMB') score += 10; + + // Industry scoring + const targetIndustries = ['Technology', 'Finance', 'Healthcare']; + if (targetIndustries.includes(industry)) score += 25; + + // Contact info scoring + if (hasEmail) score += 10; + if (hasPhone) score += 15; + + // Source scoring + if (source === 'Referral') score += 20; + else if (source === 'Website') score += 10; + + return { leadScore: score }; +}; +``` + +3. **Update Record**: Set Lead Score to `{{code.leadScore}}` + +## Text Formula: Domain Extraction + +### Example: Extract Domain from Email + +**Goal**: Automatically extract and store the email domain. + +### Setup + +1. **Trigger**: Record is Updated (People, Email field) + +2. **Code action**: + +```javascript +export const main = async (params) => { + const { email } = params; + + if (!email) return { domain: null }; + + const domain = email.split('@')[1]?.toLowerCase(); + + return { domain }; +}; +``` + +3. **Update Record**: Set Domain field to `{{code.domain}}` + +## Best Practices + +### Performance +- Only trigger on relevant field changes +- Use filters to skip records that don't need calculation +- Avoid complex calculations in high-volume workflows + +### Error Handling +- Check for null/undefined values before calculations +- Use default values when data is missing +- Return clear error messages when calculations fail + +### Testing +- Test with edge cases (empty fields, zero values) +- Verify calculations manually before activating +- Monitor workflow runs for unexpected results + +## Related + +- [How to Show Expected Amount in Pipeline](/user-guide/views-pipelines/how-tos/show-expected-amount-in-pipeline) +- [How to Track Time in Stage](/user-guide/views-pipelines/how-tos/track-time-in-stage) +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/send-email-alerts-with-tasks-due.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/send-email-alerts-with-tasks-due.mdx new file mode 100644 index 0000000000..8287633208 --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/crm-automations/send-email-alerts-with-tasks-due.mdx @@ -0,0 +1,105 @@ +--- +title: Send Email Alerts with Tasks Due +description: Automatically notify team members about their upcoming or overdue tasks. +--- +import { VimeoEmbed } from '/snippets/vimeo-embed.mdx'; + + + +Send daily email reminders to each team member about their tasks due today. + +## Overview + +This workflow runs on a schedule and: +1. Fetches all workspace members +2. Loops through each member +3. Finds their tasks due today +4. Formats and sends a personalized email + +## Step-by-Step Setup + + + +### Step 1: Configure the Trigger + +1. Go to **Settings → Workflows** and create a new workflow +2. Select **On a Schedule** as the trigger +3. Use a cron expression for daily at 8:00 AM: `0 8 * * *` + + +### Step 2: Search for All Workspace Members + +1. Add a **Search Records** action +2. Select **Workspace Members** (under advanced objects) +3. No filters needed — this returns all members + +### Step 3: Add an Iterator + +1. Add an **Iterator** action +2. Set the input array to the workspace members from the previous step +3. All actions inside the iterator will run once per member + +### Step 4: Search for Tasks Due Today (Inside Iterator) + +1. Inside the iterator, add a **Search Records** action +2. Select **Tasks** as the object +3. Add filters: + - **Assignee** = current workspace member (from the iterator) + - **Due Date** = today + +### Step 5: Format Tasks into Email Body (Inside Iterator) + +Add a **Code** action to format the tasks into a readable list with links: + +```javascript +export const main = async (params: { + tasksDue?: Array<{ id: string; title: string }> | null | string; +}) => { + const tasksDue = + typeof params.tasksDue === "string" + ? JSON.parse(params.tasksDue) + : params.tasksDue; + + if (!Array.isArray(tasksDue) || tasksDue.length === 0) { + return { + formattedTasks: "No tasks due today." + }; + } + + const formattedTasks = tasksDue + .map( + t => + `${t.title}\nhttps://yourSubDomain.twenty.com/object/task/${t.id}` + ) + .join("\n\n"); + + return { formattedTasks }; +}; +``` + + +Replace `yourSubDomain` with your actual Twenty workspace subdomain. + + +### Step 6: Send Email (Inside Iterator) + +1. Add a **Send Email** action (still inside the iterator) +2. Configure: + +| Field | Value | +|-------|-------| +| **To** | `{{iterator.currentItem.userEmail}}` (workspace member's email) | +| **Subject** | Your Tasks Due Today | +| **Body** | `{{code.formattedTasks}}` | + +### Step 7: Test and Activate + +1. Click **Test** to run the workflow manually +2. Check inboxes for the emails +3. Activate the workflow + +## Related + +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) +- [Send Emails from Workflows](/user-guide/workflows/capabilities/send-emails-from-workflows) +- [Handle Arrays in Code Actions](/user-guide/workflows/how-tos/advanced-configurations/handle-arrays-in-code-actions) diff --git a/packages/twenty-docs/user-guide/workflows/professional-services.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/need-more-help/professional-services.mdx similarity index 67% rename from packages/twenty-docs/user-guide/workflows/professional-services.mdx rename to packages/twenty-docs/user-guide/workflows/how-tos/need-more-help/professional-services.mdx index f7a233f454..946a1ef439 100644 --- a/packages/twenty-docs/user-guide/workflows/professional-services.mdx +++ b/packages/twenty-docs/user-guide/workflows/how-tos/need-more-help/professional-services.mdx @@ -1,12 +1,7 @@ --- title: Professional Services -info: Get professional help building complex workflows and automations from Twenty's team and certified partners. -image: /images/user-guide/what-is-twenty/implementation_services.png -sectionInfo: Automate processes and integrate with external tools +description: Get professional help building complex workflows and automations from Twenty's team and certified partners. --- - - Header - ## When Do You Need Professional Help? @@ -27,7 +22,4 @@ Get help from our core team with our 4-hour [Onboarding packs](https://twenty.co - **Data Migration**: Import existing data with proper workflow integration ### Implementation Partners -Work with certified partners for advanced customizations. Contact us at contact@twenty.com to connect with our [implementation partners](https://twenty.com/implementation-services). - - - +Work with certified partners for advanced customizations. Contact us at contact@twenty.com to connect with our [implementation partners](https://twenty.com/partners). diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/need-more-help/workflow-troubleshooting.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/need-more-help/workflow-troubleshooting.mdx new file mode 100644 index 0000000000..2dc6b2fabf --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/need-more-help/workflow-troubleshooting.mdx @@ -0,0 +1,156 @@ +--- +title: Workflow Troubleshooting +description: Common workflow issues and how to resolve them. +--- + + +## Common Issues and Solutions + +### Workflow Not Triggering + +**Symptoms**: Your workflow doesn't run when you expect it to. + +**Possible Causes**: +1. **Workflow not activated**: Ensure the workflow is set to "Active" not "Draft" +2. **Trigger conditions not met**: Verify the trigger matches your expected event +3. **Field not monitored**: For "Record is Updated" triggers, ensure the specific field is being watched +4. **Permissions**: Check you have permission to run workflows + +**Solutions**: +- Verify workflow status in the workflow list +- Test with the specific action you expect to trigger it +- Review trigger configuration +- Contact your admin about permissions + +### Workflow Triggers Too Early (Empty Fields) + +**Symptoms**: When manually creating a record in the UI, your workflow triggers before you've had time to fill in all the fields. The workflow runs with mostly empty field values. + +**Why this happens**: Twenty saves everything in real-time — there's no separate "edit" vs "read" mode. When you create a record, it's saved immediately, triggering the "Record is created" event before you can fill in additional fields. + +**When "Record is created" works well**: +- Records created via API calls (fields are populated in a single request) +- Records created via import +- Automated record creation from other workflows + +**Solution**: For records created manually in the UI, use **"Record is created or updated"** as your trigger instead. This way: +- The workflow triggers after the user has finished filling in and saving the fields +- You get the complete data rather than empty values + + +If you only want the workflow to run once per record, add a Filter action to check a field like `createdAt equals updatedAt` (first save) or use a custom checkbox field to track if the workflow has already run. + + +### Actions Failing + +**Symptoms**: Workflow runs but some actions fail. + +**Possible Causes**: +1. **Missing data**: Required fields are empty +2. **Invalid references**: Variables from previous steps don't exist +3. **API errors**: External services returning errors +4. **Permission issues**: Action requires permissions you don't have + +**Solutions**: +- Check the workflow run details for error messages +- Verify all required fields have values +- Test API connections independently +- Review role permissions + +### HTTP Request Errors + +**Symptoms**: HTTP Request actions fail or return unexpected results. + +**Common Error Codes**: +- **400**: Bad request - check your request body format +- **401**: Unauthorized - verify API key +- **403**: Forbidden - check API permissions +- **404**: Not found - verify endpoint URL +- **429**: Too many requests - implement rate limiting +- **500**: Server error - external service issue + +**Solutions**: +- Verify API endpoint URL +- Check authentication headers +- Test the API call outside of Twenty first +- Add error handling in Code actions + +### Code Action Errors + +**Symptoms**: JavaScript code fails to execute. + +**Common Issues**: +1. **Syntax errors**: Typos or invalid JavaScript +2. **Undefined variables**: Referencing variables that don't exist +3. **Type errors**: Operations on wrong data types +4. **Timeouts**: Code taking too long to execute + +**Solutions**: +- Use the built-in code editor validation +- Test code logic in a JavaScript console first +- Add console.log statements for debugging +- Simplify complex operations + +### Email Not Sending + +**Symptoms**: Send Email action doesn't deliver emails. + +**Possible Causes**: +1. **No email account connected**: Check Settings → Accounts +2. **Invalid email address**: Recipient email is malformed +3. **Sending limits**: Email provider rate limits reached +4. **Spam filters**: Emails being blocked + +**Solutions**: +- Verify email account connection +- Validate recipient email addresses +- Check email provider limits +- Review email content for spam triggers + +## Debugging Workflows + +### Using Workflow Runs + +1. Go to the workflow editor +2. Open the **Runs** panel +3. Find the failed run +4. Click to see step-by-step details +5. Review error messages and output data + +### Testing Individual Steps + +1. For Code actions, use the **Test** button +2. For HTTP requests, test the endpoint separately +3. Create test records to trigger workflows +4. Use manual triggers for controlled testing + +### Common Debugging Patterns + +**Add logging**: +Use Code actions to log intermediate values for debugging. + +**Isolate steps**: +Test each step independently to identify failures. + +**Check data flow**: +Verify that each step receives the expected input data. + +## Best Practices to Avoid Issues + +### Before Activation +- Test thoroughly in draft mode +- Validate all API connections +- Review trigger conditions carefully +- Document expected behavior + +### During Development +- Use descriptive step names +- Add comments in Code actions +- Test with realistic data +- Plan for edge cases + +### After Activation +- Monitor initial runs closely +- Set up alerts for failures +- Review run history regularly +- Keep workflows simple when possible diff --git a/packages/twenty-docs/user-guide/workflows/how-tos/need-more-help/workflows-faq.mdx b/packages/twenty-docs/user-guide/workflows/how-tos/need-more-help/workflows-faq.mdx new file mode 100644 index 0000000000..a1720549fd --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/how-tos/need-more-help/workflows-faq.mdx @@ -0,0 +1,239 @@ +--- +title: Workflows FAQ +description: Frequently asked questions about workflows in Twenty. +--- + + + + + This is likely a permissions issue. You need access to workflows to create and activate them. + + **Solution**: Contact your workspace administrator to grant you workflow access under **Settings → Roles**. + + If you don't see the Workflows section at all in your sidebar, this confirms it's a permissions issue. + + + + Manual workflows only appear in the navbar if properly configured: + + 1. The workflow must be **activated** (not in draft mode) + 2. The navbar placement must be set to **Pinned** + 3. For Single/Bulk triggers, you must be on the correct object page + + **To check**: Open the workflow → click the trigger → verify "Navbar placement" is set to "Pinned". + + You can always access manual workflows via **Cmd + K** (or **Ctrl + K**) regardless of navbar settings. + + + + | Type | Records Required | Workflow Runs | + |------|------------------|---------------| + | **Global** | None | Once, no record input | + | **Single** | One or more selected | Once per selected record | + | **Bulk** | One or more selected | Once, with all records as array | + + - **Global**: Use when the workflow doesn't need any record context (e.g., generate a report) + - **Single**: Use when you want to process each selected record independently (e.g., send individual emails) + - **Bulk**: Use when you need to process records together or optimize credit usage (requires Iterator action) + + See [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers) for details. + + + + An explicit If/Else node is not yet available but is on our roadmap. + + **Current workaround**: Create multiple branches from your step, each starting with a **Filter** action: + + ``` + Step 1 + │ + ├── Branch A: Filter (condition = true) → Actions... + │ + └── Branch B: Filter (condition = false) → Actions... + ``` + + Only the branch where the filter condition passes will execute its subsequent actions. + + See [How to Use Branches](/user-guide/workflows/capabilities/workflow-branches) for a step-by-step guide. + + + + **Yes**, branches run in parallel by default. + + If you want only one branch to execute: + - Add a **Filter** action at the start of each branch + - Set opposite conditions (e.g., Branch A: status = "Open", Branch B: status ≠ "Open") + + Branches that fail their filter condition stop executing, while others continue. + + + + **Yes**. After your parallel branches complete, you can add a step that both branches connect to. + + In the workflow editor: + 1. Complete your branched actions + 2. Add a new step after the branches + 3. Drag connections from the end of each branch to this new step + + The merged step will execute after all connected branches complete. + + + + **Search Records returns a maximum of 200 records.** + + If you need to process more: + - Add more specific filters to reduce results + - Use scheduled workflows to process in batches + - Consider using the API for bulk operations + + For most workflows, 200 records is sufficient. If you regularly hit this limit, consider restructuring your automation. + + + + **Not yet.** CC and BCC fields for the Send Email action are on our roadmap. + + **Current workaround**: Add multiple Send Email actions to send to additional recipients, or use an HTTP Request to send via an external email service that supports CC. + + + + Every action produces output data that can be used in subsequent steps. + + **To reference previous step data**: + - Use the variable picker when configuring a field + - Or type `{{stepName.fieldName}}` directly + + **Examples**: + - Trigger data: `{{trigger.object.email}}` + - Search results: `{{searchRecords[0].name}}` + - Code output: `{{code.calculatedValue}}` + + Hover over any field in the action configuration to see available variables from previous steps. + + + + **Iterator requires an array input.** Common issues: + + 1. **Input is not an array**: Ensure you're passing results from Search Records or another action that returns an array + 2. **Array is empty**: Add a filter before Iterator to check `{{searchRecords.length}} > 0` + 3. **Wrong variable selected**: Make sure you select the array itself, not a single record + + **Correct setup**: + 1. Search Records (returns array) + 2. Filter: length > 0 + 3. Iterator: select `{{searchRecords}}` + 4. Actions inside iterator use `{{iterator.currentItem.fieldName}}` + + + + Code actions (serverless functions) have a **default timeout of 5 minutes** (300 seconds). + + The maximum configurable timeout is **15 minutes** (900 seconds). + + If your code exceeds this limit, the action will fail with a timeout error. + + **Tips to avoid timeouts**: + - Break large operations into smaller chunks using Iterator + - Avoid heavy computations; use external services via HTTP Request for intensive processing + - Optimize your code to reduce execution time + - If you need longer processing, consider using scheduled workflows that process data in batches + + + + Workflow runs show the execution history and help you debug issues. + + **Access runs**: + - In workflow editor → **Runs** panel on the right + - Or go to **Workflow Runs** in the sidebar + + **Understanding a run**: + - **Status**: Running, Completed, Failed, Waiting + - **Steps**: See which steps executed and their output + - **Errors**: Click failed steps to see error messages + - **Data**: View input/output data at each step + + See [Workflow Runs](/user-guide/workflows/capabilities/workflow-runs) for details. + + + + Workflow runs might be failing immediately due to rate limits. + + **Hard limit: 5,000 runs per hour per workspace.** + + If you exceed this limit, workflows are immediately marked as failed and won't appear in your runs list as expected. + + **Common scenarios that hit this limit**: + - Selecting more than 5,000 records with a Single manual trigger + - Multiple workflows running simultaneously across your workspace + - High-frequency automated triggers (e.g., Record Updated on a busy object) + + **Solutions**: + - Use **Bulk** triggers instead of Single to process many records in one run + - Space out large batch operations + - Use filters to reduce trigger frequency + - Schedule heavy workflows during off-peak hours + + + + Twenty has two rate limits to ensure system stability: + + | Limit | Value | Behavior | + |-------|-------|----------| + | **Soft limit** | 100 runs/minute | Runs queue in "Not Started" status, processed gradually | + | **Hard limit** | 5,000 runs/hour | Runs immediately fail | + + **Soft limit (100/min)**: Your workflows won't fail—they just wait in the queue and are processed over time. You can trigger more than 100 records; execution will be slower. + + **Hard limit (5,000/hr)**: This applies to your entire workspace. If all your workflows combined exceed 5,000 runs in an hour, additional runs will fail immediately. + + **Tips to stay within limits**: + - Use Bulk triggers with Iterator instead of Single triggers for large batches + - Combine related automations into fewer workflows + - Use scheduled workflows to spread load over time + + + + **No, there is no automatic retry functionality at the moment.** + + If a workflow run fails, you'll need to: + 1. Review the error in **Settings → Workflows → [Your Workflow] → Runs** + 2. Fix the issue (data, configuration, or external service) + 3. Manually trigger the workflow again on the affected record(s) + + **Tips to reduce failures**: + - Add **Filter** nodes to validate data before actions + - Use **Search Records** to check if related records exist + - Test thoroughly with a few records before bulk operations + + Automatic retry functionality is on our roadmap for a future release. + + + + **Yes, if your workflows are triggered by record creation or updates.** + + When you import data via CSV, each record created or updated can trigger workflows. A large import (thousands of records) could: + - Hit the 5,000 runs/hour limit + - Consume significant workflow credits + - Send unexpected emails or notifications + - Create duplicate tasks or records + + **Before a mass import**: + 1. Go to **Settings → Workflows** + 2. Identify workflows triggered by the object you're importing + 3. **Deactivate** them temporarily + 4. Run your CSV import + 5. **Reactivate** the workflows when done + + **Alternative**: If you need the workflows to run on imported data, import in smaller batches to stay within rate limits. + + + + If your workflow canvas looks messy with nodes scattered around, you can automatically organize it: + + 1. Right-click anywhere on the workflow canvas + 2. Click **Tidy up workflow** + + This will automatically rearrange all nodes into a clean, organized layout. + + + + diff --git a/packages/twenty-docs/user-guide/workflows/internal-automations.mdx b/packages/twenty-docs/user-guide/workflows/internal-automations.mdx deleted file mode 100644 index a49751b03c..0000000000 --- a/packages/twenty-docs/user-guide/workflows/internal-automations.mdx +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: Internal Automations -info: "Automate repetitive tasks to reduce manual work and keep your data accurate." -image: /images/user-guide/workflows/internal-automations.png -sectionInfo: Automate processes and integrate with external tools ---- - - Header - - -Below are workflow examples you could roll out to automate repetitive tasks to reduce manual work and keep your data up-to-date. - -## Data Management Automations - -### Auto-Flag Personal Emails -**Problem**: Your team needs to identify personal vs. business email addresses for better targeting and compliance. - -**Solution**: Create a workflow that automatically updates an "is personal email" field whenever an email address is added or updated. - -**Trigger**: Record is Updated (People object, Email field) - -**Actions**: -- Code action to check if email domain matches common personal providers (gmail.com, yahoo.com, etc.) -- Update Record to set the "is personal email" flag - -### Lead Assignment - Round Robin -**Problem**: New leads need to be distributed fairly across your sales team to ensure balanced workloads. - -**Solution**: Automatically assign new leads to sales reps using a round-robin system. - -**Trigger**: Record is Created (People object) - -**Actions**: -- Search Records to find the last assigned rep -- Code action to determine next rep in rotation -- Update Record to assign the lead to the selected rep -- Send Email to notify the assigned rep - -### Lead Assignment - Territory Based -**Problem**: Leads should be assigned based on geographic territories or company characteristics. - -**Solution**: Route leads to the appropriate sales rep based on location, company size, or industry. - -**Trigger**: Record is Created (People or Companies object) - -**Actions**: -- Code action to determine territory based on location/industry rules -- Search Records to find the territory owner -- Update Record to assign the lead -- Create Record for a follow-up task - -## Sales Process Automations - -### Opportunity Stage Management - Closed Won -**Problem**: When deals close, multiple manual updates are needed across different records and team members. - -**Solution**: Automatically handle all post-win activities when an opportunity moves to "Closed Won". - -**Trigger**: Record is Updated (Opportunities object, Stage field = "Closed Won") - -**Actions**: -- Update Record to change Company type from "Prospect" to "Customer" -- Create Record for onboarding tasks assigned to account manager -- Send Email notification to customer success team -- HTTP Request to update external billing system - -### Opportunity Stage Management - Closed Lost Renewal -**Problem**: When renewal opportunities are lost, the customer status needs to be updated for proper account management. - -**Solution**: Automatically update customer status when renewal deals are lost. - -**Trigger**: Record is Updated (Opportunities object, Stage = "Closed Lost" AND Type = "Renewal") - -**Actions**: -- Update Record to change Company type from "Customer" to "Churn Customer" -- Create Record for churn analysis task -- Send Email alert to customer success manager -- Update Record to add churn date and reason - -### Stale Opportunity Alerts -**Problem**: Opportunities sit without updates, causing deals to go cold and forecasts to become unreliable. - -**Solution**: Send automatic alerts when opportunities haven't been updated recently. - -**Trigger**: On a Schedule (daily) - -**Actions**: -- Search Records for opportunities not updated in X days -- Code action to format alert message with opportunity details -- Send Email to opportunity owner and manager -- Create Record for follow-up task if no response - -## Productivity Automations - -### Weekly Task Recap -**Problem**: Team members lose track of their upcoming tasks and deadlines. - -**Solution**: Send automated weekly email reminders with task summaries. - -**Trigger**: On a Schedule (every Monday at 8 AM) - -**Actions**: -- Search Records for tasks due this week by assignee -- Code action to format task list by person -- Send Email to each team member with their task recap -- Send Email to managers with team overview - -### Meeting Follow-up Automation -**Problem**: Important action items from meetings get forgotten or delayed. - -**Solution**: Automatically create follow-up tasks when meetings are scheduled or completed. - -**Trigger**: Record is Created (Activities object, Type = "Meeting") - -**Actions**: -- Create Record for pre-meeting preparation task -- Create Record for post-meeting follow-up task -- Send Email reminder to attendees -- Update Record to link tasks to the meeting - -### Cross-Object Field Synchronization -**Problem**: You need information from related records easily accessible (e.g., main contact's email on opportunity record). - -**Solution**: Automatically sync fields between related objects until nested fields are available. - -**Trigger**: Record is Updated (Opportunities object, Point of Contact field) - -**Actions**: -- Search Records to find the linked person's details -- Update Record to copy email address to opportunity -- Update Record to copy phone number to opportunity -- Update Record to copy company information - -## Data Validation and Cleanup - -### Phone Number Standardization -**Problem**: Phone numbers are entered in different formats, making them hard to use for calling or messaging. - -**Solution**: Automatically format phone numbers to a standard format when they're entered. - -**Trigger**: Record is Updated (People object, Phone field) - -**Actions**: -- Code action to parse and format phone number -- Update Record with standardized phone format -- Update Record to add country code if missing - - -For more complex automation needs, consider our [Professional Services](/user-guide/workflows/professional-services) or explore [External Tool Integration](/user-guide/workflows/external-tool-integration). - - diff --git a/packages/twenty-docs/user-guide/workflows/overview.mdx b/packages/twenty-docs/user-guide/workflows/overview.mdx new file mode 100644 index 0000000000..77f88c5d2c --- /dev/null +++ b/packages/twenty-docs/user-guide/workflows/overview.mdx @@ -0,0 +1,76 @@ +--- +title: Workflows +description: Learn how to build automations in Twenty. +image: /images/user-guide/workflows/workflow.png +--- + + + Workflows + + +## Why Workflows Matter + +Twenty was built to bring maximum flexibility to its users. Rather than forcing you to adapt your business processes to rigid, pre-built features, workflows enable you to build automations that create the CRM that best supports your unique business use cases. + +Workflows are Twenty's in-app feature for building these automations. They give you the building blocks to create exactly what your business needs, when it needs it. + +## What can I do with workflows? + +We recommend building automations for two main purposes: + +1. **Internal automations to facilitate your team's day-to-day**: Reduce the amount of manual entries and repetitive tasks that slow down your team. +2. **Bring data in and out of Twenty**: Connect Twenty via API calls and webhooks to your database and other tools. + +## Building Your First Workflow + +### Step 1: Create a New Workflow +1. Go to **Workflows** accessible below the other objects +2. Click **+ New Record** +3. Give your workflow a name + +### Step 2: Add a Trigger +Every workflow starts with a trigger. Choose from: +- **Record events**: When a record is created, updated, or deleted +- **Schedule**: Run at specific times (daily, weekly, etc.) +- **Manual**: Triggered by a user action +- **Webhook**: Triggered by a webhook + + + +### Step 3: Add Actions +After your trigger, add one or more actions: +- **Create Record**: Add new records to any object +- **Update Record**: Modify existing record data +- **Delete Record**: Remove records from objects +- **Search Records**: Find records matching criteria +- **Upsert Record**: Create or update based on matching criteria +- **Iterator**: Loop through arrays of records +- **Filter**: Control which records proceed +- **Delay**: Wait before continuing (duration or scheduled date) +- **Send Email**: Send emails via your connected account +- **Code**: Run custom JavaScript +- **HTTP Request**: Call external APIs +- **Form**: Get inputs from users within Twenty UI at the time of execution +- **AI Agent** (Coming soon): Run intelligent AI tasks + + + + +### Step 4: Test and Activate +1. Use the **Test** button to run your workflow with sample data +2. Review the results to ensure it works as expected +3. Toggle the workflow **Active** when ready + +## Workflow Best Practices + +- **Edit step names**: Rename your workflow steps to clearly describe what each one does. This helps with maintenance and makes it easier to hand off to coworkers +- **Leverage previous step data**: You can use fields from records returned by any previous step in your workflow +- **Start simple**: Begin with basic workflows and add complexity over time as you become more comfortable with the system +- **Plan before building**: Map out your workflow logic before you start building to avoid getting stuck halfway through + + +## Next Steps + +- [Workflow Triggers](/user-guide/workflows/capabilities/workflow-triggers) +- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions) +- [CRM Automations](/user-guide/workflows/how-tos/crm-automations/closed-won-automations) diff --git a/packages/twenty-docs/user-guide/workflows/workflow-credits.mdx b/packages/twenty-docs/user-guide/workflows/workflow-credits.mdx deleted file mode 100644 index 7b33a57418..0000000000 --- a/packages/twenty-docs/user-guide/workflows/workflow-credits.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Workflow Credits -info: Understand workflow credit consumption, monitoring, and cost management for your automations. -image: /images/user-guide/workflows/workflow-credits.png -sectionInfo: Automate processes and integrate with external tools ---- - - Header - - -Workflow credits power your automations in Twenty. Understanding how they work helps you optimize costs and manage your automation budget effectively. - -## Credit Allocation by Plan - -Workflow credits are allocated per workspace based on your subscription plan: - -- **Trial**: 5 million credits -- **Pro Plan**: 10 million credits per month -- **Organization Plan**: 20 million credits per month - -## 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**: Significant credit consumption (coming soon) - - AI prompts and processing will consume credits based on usage - -### 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 - -### Efficient Workflow Design -- **Start Simple**: Begin with basic actions and add complexity gradually -- **Test in Draft**: Thoroughly test workflows before activation to avoid wasting credits on errors -- **Minimize HTTP Requests**: Use efficient search criteria and combine operations where possible -- **Batch Processing**: Use bulk operations and Iterator actions efficiently -- **Error Handling**: Implement proper error handling to prevent unnecessary retries -- **Manual Trigger Optimization**: For manual triggers, choose `Bulk` availability to process multiple records in a single workflow run (see [Workflow Features](/user-guide/workflows/workflow-features) for details) - -### Action Optimization -- Use basic internal operations when possible (lower credit consumption) -- Optimize Code actions for efficiency -- Consider manual triggers for non-urgent processes -- Batch operations to reduce individual action calls - -### Credit Management -- **Regular Monitoring**: Check your credit usage weekly in Settings → Billing -- **Usage Tracking**: Keep track of consumption patterns to avoid unexpected overages -- **Plan Accordingly**: Consider upgrading your plan if you consistently need more credits -- **Workflow Review**: Regularly review high-consumption workflows and deactivate unused ones -- **Strategic Planning**: Plan workflow deployment based on credit availability - -For detailed billing information and credit management, visit **Settings → Billing** in your Twenty workspace. - - diff --git a/packages/twenty-docs/user-guide/workflows/workflow-features.mdx b/packages/twenty-docs/user-guide/workflows/workflow-features.mdx deleted file mode 100644 index aab6dd2909..0000000000 --- a/packages/twenty-docs/user-guide/workflows/workflow-features.mdx +++ /dev/null @@ -1,273 +0,0 @@ ---- -title: Workflow Features -info: Complete reference for all available workflow triggers, actions, and management features. -image: /images/user-guide/workflows/robot.png -sectionInfo: Automate processes and integrate with external tools ---- - - Header - - -## Workflow Triggers - -Workflows always start with a single trigger that defines when the automation should run. - -### Record is Created -Starts the workflow when a new record is created in a selected object (People, Companies, Opportunities, or any custom object). - -**Configuration**: Select the object type to monitor for new records. - -### Record is Updated -Starts the workflow when changes are made to an existing record. - -**Configuration**: -- Select the object type -- Optionally specify which fields to monitor for changes - -### Record is Updated or Created -Starts the workflow when a record is either created or updated in a selected object. - -**Why This Matters**: This trigger is particularly helpful because records created via different methods behave differently: -- **API/CSV imports**: Records are created with all fields populated immediately -- **Manual creation**: Records are created first, then fields are added in subsequent updates - -**Configuration**: -- Select the object type to monitor -- Optionally specify which fields to monitor for changes -- The workflow will trigger both on initial creation and any subsequent updates - -### Record is Deleted -Starts the workflow when a record is removed from an object. - -**Configuration**: Select the object type to monitor for deletions. - -### Launch Manually -Starts the workflow when triggered by a user action. This trigger can be accessed through the Cmd+K menu or via a custom button in the top navbar. - -**Availability Configuration**: -Choose how the workflow should handle record selection: - -- **Global**: No record is required to trigger this workflow. The workflow is triggered from anywhere (from any object) and does not use record(s) as input. - -- **Single**: The selected record(s) will be passed to your workflow. This is configured for a given object. Several records can be selected before triggering the workflow. The workflow will run as many times as there are records selected. - - - You cannot run more than 100 workflows in parallel at any given time. - - -- **Bulk**: The selected record(s) will be passed to your workflow. This is configured for a given object. Several records can be selected before triggering the workflow. The workflow will run once, providing the entire list of records as input. This means the workflow needs to contain an Iterator action. This is best for people who want to optimize/limit the number of workflow runs. - -**Additional Configuration**: -- Select the target object (for Single and Bulk availability) -- Choose a command icon for the workflow trigger -- Configure navbar placement (Pinned or Not Pinned) - -**Access Methods**: -- Cmd+K menu to find and launch manual workflows -- Custom button in the top navbar (if configured) - -### On a Schedule -Starts the workflow on a recurring basis you define. - -**Configuration**: -- Select time unit (minutes, hours, days) -- Enter a value or use custom cron expressions for advanced scheduling - -### Webhook -Starts the workflow when a GET or POST request is received from an external service. - -**Configuration**: -- Receive a unique webhook URL -- For POST requests, define the expected body structure -- Configure authentication if needed - -## Workflow Actions - -Actions define what happens after a trigger fires. You can chain multiple actions together. - -### Create a 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 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. - -**Configuration**: -- Select the target object -- Choose the specific record to update -- 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. - -**Best Practice**: Use branches after Search Records to handle "found" vs "not found" scenarios. - -### 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) -- Define the actions to perform on each record in the loop -- Configure the variable name to reference each record in the iteration - -**Example**: Search Records returns 5 people, then use Iterator to send an email to each person or update each record individually. - -**Note**: Iterator is currently in beta. Activate it under Settings > Releases > Lab. - -### Filter -Filters an array of records based on specified conditions, allowing only records that meet the criteria to pass through. - -**Configuration**: -- Select the array of records to filter -- Define filter conditions and criteria -- Configure which records should pass through to subsequent steps - -**Output**: Returns only the records that match the specified filter conditions. - -### Send Email -Sends an email from your workflow. - -**Prerequisites**: Add an email account in Settings > Accounts - -**Configuration**: -- Enter recipient email address -- Set subject line -- Compose message body -- Reference variables from previous steps for personalization - -**Note**: Email attachments will be available in Q1 2026. - -### Code -Runs custom JavaScript within your workflow. - -**Configuration**: -- Write JavaScript code in the editor -- Access variables from previous steps -- Return variables for use in subsequent steps -- Test code directly in the step - -**Access**: Manage API keys in Settings → API & Webhooks - -### Form -Prompts a form during workflow execution to collect user input. - -**Configuration**: -- Define input fields with types, labels, and placeholders -- Configure validation rules -- Set form title and description - -**Output**: Form responses are available for use in subsequent steps. - - -Forms are currently 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 notifications center will be released in 2026 to properly support forms in automated workflows. - - -### HTTP Request -Sends a request to an external API as part of your workflow. - -**Configuration**: -- Enter the API endpoint URL -- Select HTTP method (GET, POST, PUT, PATCH, DELETE) -- Add required headers and values -- Include request body for POST/PUT/PATCH requests -- Provide sample response for structure preview - -## Workflow Management - -### Creating Workflows -1. Click "+ Add a Workflow" to begin -2. Click "Untitled" to name your workflow -3. Choose and configure your workflow trigger -4. Add actions to your workflow -5. Test and iterate -6. Activate your workflow (currently in draft mode) once you're done editing it - -**Note**: If you don't see the Workflows section, this is due to a permissions issue. Contact your workspace administrator to grant you access to workflows. - -### Workflow Statuses -- **Draft**: Being edited, not yet published -- **Active**: Live version responding to triggers -- **Deactivated**: Previously active but manually stopped -- **Archived**: Past versions kept for history - -### Activating Workflows -Click **Activate** to publish your draft as a new version. This makes the workflow eligible to run when triggered but doesn't immediately execute it. - -### Testing Workflows -Test workflows before activation using: -- Manual triggers (when no record selected) -- Individual action testing (especially Code actions) -- Draft mode testing that doesn't activate the workflow - -### Workflow Runs -A **Run** is a record of workflow execution containing: -- Status (success, failed, running) -- Output data from each step -- Author and timestamps -- Error messages if applicable - -**Viewing Runs**: -- Check the **Runs** panel in the workflow editor -- Open **Workflow Runs** view for monitoring across all workflows - -**Performance Tip**: Hide workflow runs from the "All workflows" page and other workflow pages to improve loading performance, as large numbers of runs can slow down page loading. - -### Version History -- View all versions under the **Versions** field -- Click any version to view details -- Use **Use as draft** to restore previous versions -- Handle draft conflicts with override or return options - -## Best Practices - -### Workflow Organization -- **Descriptive Names**: Use clear, specific workflow names -- **Step Naming**: Rename steps to describe their function -- **Documentation**: Add comments in Code actions -- **Categorization**: Group related workflows logically -- **Custom Fields**: Add fields to the Workflow object in your data model (similar to other objects) to organize and categorize workflows with custom properties - -### Performance Optimization -- **Minimize API Calls**: Batch operations when possible -- **Efficient Searches**: Use specific filter criteria -- **Error Handling**: Plan for failure scenarios -- **Rate Limiting**: Respect external API limits - -### Data Flow Management -- **Branch Logic**: Use branches after Search Records -- **Variable Usage**: Leverage data from previous steps -- **Data Validation**: Validate inputs in Code actions -- **Field Mapping**: Plan data transformations carefully - -### Monitoring and Maintenance -- **Regular Monitoring**: Check workflow runs for errors -- **Performance Review**: Analyze execution times and success rates -- **Update Management**: Test changes in draft before activation -- **Team Coordination**: Document workflows for team members - -For practical examples of these features in action, see our [Internal Automations](/user-guide/workflows/internal-automations) and [External Tool Integration](/user-guide/workflows/external-tool-integration) guides. - diff --git a/packages/twenty-docs/user-guide/workflows/workflow-troubleshooting.mdx b/packages/twenty-docs/user-guide/workflows/workflow-troubleshooting.mdx deleted file mode 100644 index a9fce8d037..0000000000 --- a/packages/twenty-docs/user-guide/workflows/workflow-troubleshooting.mdx +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: Workflow Troubleshooting -info: Debug and optimize your workflows with troubleshooting techniques and performance optimization tips. -image: /images/user-guide/what-is-twenty/20.png -sectionInfo: Automate processes and integrate with external tools ---- - - Header - - -## Debugging with Workflow Runs - -Use the **Workflow Runs** interface to debug issues: -- Access via the **Runs** panel in the workflow editor -- Click on individual runs to see input/output data for each step -- Check execution status, error messages, and data flow between steps - -## Common Issues and Solutions - -### Workflow Not Triggering -**Problem**: Workflow doesn't execute when expected. - -**Solutions**: -- Verify the workflow is **Active** (not in Draft mode) -- Check trigger configuration matches your data structure -- For Record triggers, ensure the correct object and fields are selected -- For Webhook triggers, verify the URL and expected data format -- For Scheduled triggers, check the timing configuration - -### Forms Not Accessible -**Problem**: Form actions are hard to find or access in automated workflows. - - -Forms are currently 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 notifications center will be released in 2026 to properly support forms in automated workflows. - - -**Workaround**: Use manual triggers when forms are required, or restructure workflows to avoid forms in automated flows. - -### High Credit Consumption -**Problem**: Workflows consuming more credits than expected. - -**Common Causes & Solutions**: -- **Inefficient API Calls**: Batch API calls when possible instead of individual requests -- **Wrong Manual Trigger Configuration**: Use `Bulk` availability instead of `Single` to process multiple records in one workflow run -- **Missing Filters**: Add conditional logic to stop workflows when criteria aren't met -- **Unnecessary Steps**: Remove redundant actions and optimize workflow logic -- **Real-time vs. Scheduled**: Use scheduled workflows for non-urgent processes - -### Concurrent Workflow Limits -**Problem**: Hitting the 100 concurrent workflow limit per workspace. - - -You cannot run more than 100 workflows in parallel at any given time per workspace. - - -**Solutions**: -- Use `Bulk` availability for manual triggers to process multiple records in one run -- Implement delays between workflow executions using scheduled triggers -- Optimize workflows to run faster and reduce concurrent execution time -- Consider batch processing during off-peak hours - -### API Rate Limiting -**Problem**: External API calls failing due to rate limits. - -**Solutions**: -- Use scheduled workflows instead of real-time triggers when possible -- Implement delays between API calls in Code actions -- Batch API requests when the external service supports it -- Monitor workflow runs for rate limit errors and adjust timing - -### Iterator Issues -**Problem**: Iterator actions not working as expected. - -**Solutions**: -- **Note**: Iterator is currently in beta. Activate it under Settings → Releases → Lab -- Verify the input is an array of records from a previous step -- Check that actions within the Iterator are properly configured -- Use Iterator with `Bulk` manual triggers for optimal performance - -### Missing Permissions -**Problem**: Cannot access workflows section. - - -If you don't see the Workflows section, this is due to a permissions issue. Contact your workspace administrator to grant you access to workflows. - - -## Optimization Tips - -### Performance Best Practices -- **Start simple** and add complexity gradually -- **Use `Bulk` availability** for manual triggers to process multiple records efficiently -- **Add filters early** to stop workflows when criteria aren't met -- **Batch API calls** and use scheduled workflows for non-urgent processes -- **Hide workflow runs** from pages showing all workflows to improve loading performance -- **Monitor credit usage** regularly in Settings → Billing - -### Error Prevention -- **Test in draft mode** before activating workflows -- **Validate API responses** and implement fallback actions -- **Use descriptive step names** for easier maintenance -- **Document complex logic** for team members - -## Getting Help - -### Self-Service Resources -- Review [Workflow Features](/user-guide/workflows/workflow-features) for technical details -- Check [Workflow Credits](/user-guide/workflows/workflow-credits) for optimization tips -- Explore [Internal Automations](/user-guide/workflows/internal-automations) and [External Tool Integration](/user-guide/workflows/external-tool-integration) for examples - -### Professional Support -- Contact our [Professional Services](/user-guide/workflows/professional-services) for complex troubleshooting -- Reach out to support via contact@twenty.com for technical assistance - - diff --git a/tools/eslint-rules/rules/no-angle-bracket-placeholders.ts b/tools/eslint-rules/rules/no-angle-bracket-placeholders.ts index f612de3d96..5331ae0a03 100644 --- a/tools/eslint-rules/rules/no-angle-bracket-placeholders.ts +++ b/tools/eslint-rules/rules/no-angle-bracket-placeholders.ts @@ -72,6 +72,55 @@ export const rule: Rule.RuleModule = { return {}; } + const isInsideCodeBlock = (position: number, text: string): boolean => { + const codeBlockRanges = []; + let searchStart = 0; + + while (true) { + const openIndex = text.indexOf('```', searchStart); + if (openIndex === -1) { + break; + } + + const closeIndex = text.indexOf('```', openIndex + 3); + if (closeIndex === -1) { + break; + } + + codeBlockRanges.push({ + start: openIndex, + end: closeIndex + 3, + }); + + searchStart = closeIndex + 3; + } + + for (const range of codeBlockRanges) { + if (position >= range.start && position < range.end) { + return true; + } + } + + const beforeText = text.substring(0, position); + let inlineBacktickCount = 0; + + for (let i = 0; i < beforeText.length; i++) { + let insideFencedBlock = false; + for (const range of codeBlockRanges) { + if (i >= range.start && i < range.end) { + insideFencedBlock = true; + break; + } + } + + if (!insideFencedBlock && beforeText[i] === '`') { + inlineBacktickCount++; + } + } + + return inlineBacktickCount % 2 !== 0; + }; + return { Program: (node) => { const text = sourceCode.getText(); @@ -88,10 +137,10 @@ export const rule: Rule.RuleModule = { foundPositions.add(startPos); - // Check if we're inside a code block (between backticks) - const beforeText = text.substring(0, startPos); - const backticksBefore = (beforeText.match(/`/g) || []).length; - const insideCodeBlock = backticksBefore % 2 !== 0; + // Skip reporting errors inside code blocks + if (isInsideCodeBlock(startPos, text)) { + continue; + } context.report({ node: node as any, @@ -103,14 +152,6 @@ export const rule: Rule.RuleModule = { data: { name: tagName, }, - fix: insideCodeBlock - ? (fixer) => { - return fixer.replaceTextRange( - [startPos, endPos], - `{${tagName}}`, - ); - } - : undefined, }); } @@ -136,10 +177,10 @@ export const rule: Rule.RuleModule = { const endPos = startPos + match[0].length; - // Check if we're inside a code block (between backticks) - const beforeText = text.substring(0, match.index); - const backticksBefore = (beforeText.match(/`/g) || []).length; - const insideCodeBlock = backticksBefore % 2 !== 0; + // Skip reporting errors inside code blocks (valid syntax like Promise) + if (isInsideCodeBlock(startPos, text)) { + continue; + } context.report({ node: node as any, @@ -151,14 +192,6 @@ export const rule: Rule.RuleModule = { data: { name: tagName, }, - fix: insideCodeBlock - ? (fixer) => { - return fixer.replaceTextRange( - [startPos, endPos], - `{${tagName}}`, - ); - } - : undefined, }); } },