i18n - docs translations (#17433)

Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
github-actions[bot]
2026-01-26 07:11:01 +01:00
committed by GitHub
parent c8c821a692
commit 2353bc62cc
361 changed files with 20096 additions and 17317 deletions
@@ -1,147 +1,147 @@
---
title: APIs
description: Query and modify your CRM data programmatically using REST or GraphQL.
title: API
description: Interrogez et modifiez vos données CRM par programmation à l'aide de REST ou de 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.
Twenty a été conçu pour être convivial pour les développeurs, offrant des API puissantes qui s'adaptent à votre modèle de données personnalisé. Nous fournissons quatre types d'API distincts pour répondre à différents besoins d'intégration.
## Developer-First Approach
## Approche axée sur les développeurs
Twenty generates APIs specifically for your data model:
Twenty génère des API spécifiquement pour votre modèle de données :
* **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
* **Pas besoin d'ID longs** : Utilisez directement les noms de vos objets et champs dans les points de terminaison
* **Objets standard et personnalisés traités à égalité** : Vos objets personnalisés bénéficient du même traitement API que ceux intégrés
* **Points de terminaison dédiés** : Chaque objet et champ a son propre point de terminaison API
* **Documentation personnalisée** : Générée spécifiquement pour le modèle de données de votre espace de travail
<Note>
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.
Votre documentation API personnalisée est disponible sous **Paramètres → API & Webhooks** après la création d'une clé API. Comme Twenty génère des API qui correspondent à votre modèle de données personnalisé, la documentation est propre à votre espace de travail.
</Note>
## The Two API Types
## Les deux types d'API
### Core API
### API principale
Accessed on `/rest/` or `/graphql/`
Accessible sur `/rest/` ou `/graphql/`
Work with your actual **records** (the data):
Travaillez avec vos **enregistrements** réels (les données) :
* Create, read, update, delete People, Companies, Opportunities, etc.
* Query and filter data
* Manage record relationships
* Créer, lire, mettre à jour, supprimer People, Companies, Opportunities, etc.
* Interroger et filtrer les données
* Gérer les relations entre les enregistrements
### Metadata API
### API de métadonnées
Accessed on `/rest/metadata/` or `/metadata/`
Accessible sur `/rest/metadata/` ou `/metadata/`
Manage your **workspace and data model**:
Gérez votre **espace de travail et votre modèle de données** :
* Create, modify, or delete objects and fields
* Configure workspace settings
* Define relationships between objects
* Créer, modifier ou supprimer des objets et des champs
* Configurer les paramètres de l'espace de travail
* Définir les relations entre les objets
## REST vs GraphQL
Both Core and Metadata APIs are available in REST and GraphQL formats:
Les API Core et Metadata sont disponibles aux formats REST et GraphQL :
| Format | Available Operations |
| ----------- | ---------------------------------------------------------- |
| **REST** | CRUD, batch operations, upserts |
| **GraphQL** | Same + **batch upserts**, relationship queries in one call |
| Format | Opérations disponibles |
| ----------- | ----------------------------------------------------------------------- |
| **REST** | CRUD, opérations par lot, upserts |
| **GraphQL** | Identique + **upserts par lot**, requêtes de relations en un seul appel |
Choose based on your needs — both formats access the same data.
Choisissez selon vos besoins — les deux formats accèdent aux mêmes données.
## API Endpoints
## Points d'accès API
| Environment | Base URL |
| --------------- | ------------------------- |
| **Cloud** | `https://api.twenty.com/` |
| **Self-Hosted** | `https://{your-domain}/` |
| Environnement | URL de base |
| ---------------- | ------------------------- |
| **Cloud** | `https://api.twenty.com/` |
| **Auto-hébergé** | `https://{your-domain}/` |
## Authentication
## Authentification
Every API request requires an API key in the header:
Chaque requête API nécessite une clé API dans l'en-tête :
```
Authorization: Bearer YOUR_API_KEY
```
### Create an API Key
### Créer une clé API
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
1. Allez dans **Paramètres → API & Webhooks**
2. Cliquez sur **+ Créer une clé**
3. Configurer:
* **Nom** : Nom descriptif pour la clé
* **Date d'expiration** : Date à laquelle la clé expire
4. Cliquez sur **Enregistrer**
5. **Copiez immédiatement** — la clé n'est affichée qu'une seule fois
<VimeoEmbed videoId="928786722" title="Creating API key" />
<VimeoEmbed videoId="928786722" title="Création d'une clé API" />
<Warning>
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.
Votre clé API donne accès à des données sensibles. Ne la partagez pas avec des services non fiables. Si elle est compromise, désactivez-la immédiatement et générez-en une nouvelle.
</Warning>
### Assign a Role to an API Key
### Attribuer un rôle à une clé API
For better security, assign a specific role to limit access:
Pour une meilleure sécurité, attribuez un rôle spécifique pour limiter l'accès :
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
1. Allez dans **Paramètres → Rôles**
2. Cliquez sur le rôle à attribuer
3. Ouvrez l'onglet **Attribution**
4. Sous **Clés API**, cliquez sur **+ Attribuer à une clé API**
5. Sélectionnez la clé API
The key will inherit that role's permissions. See [Permissions](/l/fr/user-guide/permissions-access/capabilities/permissions) for details.
La clé héritera des autorisations de ce rôle. Voir [Autorisations](/l/fr/user-guide/permissions-access/capabilities/permissions) pour plus de détails.
### Manage API Keys
### Gérer les clés API
**Regenerate**: Settings → APIs & Webhooks → Click key → **Regenerate**
**Régénérer** : Paramètres → API & Webhooks → Cliquez sur la clé → **Régénérer**
**Delete**: Settings → APIs & Webhooks → Click key → **Delete**
**Supprimer** : Paramètres → API & Webhooks → Cliquez sur la clé → **Supprimer**
## API Playground
## Bac à sable API
Test your APIs directly in the browser with our built-in playground — available for both **REST** and **GraphQL**.
Testez vos API directement dans le navigateur avec notre bac à sable intégré — disponible pour **REST** et **GraphQL**.
### Access the Playground
### Accéder au bac à sable
1. Go to **Settings → APIs & Webhooks**
2. Create an API key (required)
3. Click on **REST API** or **GraphQL API** to open the playground
1. Allez dans **Paramètres → API & Webhooks**
2. Créer une clé API (obligatoire)
3. Cliquez sur **REST API** ou **GraphQL API** pour ouvrir le bac à sable
### What You Get
### Ce que vous obtenez
* **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
* **Documentation interactive** : Générée pour votre modèle de données spécifique
* **Tests en direct** : Exécutez de véritables appels API sur votre espace de travail
* **Explorateur de schéma** : Parcourez les objets, champs et relations disponibles
* **Générateur de requêtes** : Construisez des requêtes avec l'autocomplétion
The playground reflects your custom objects and fields, so documentation is always accurate for your workspace.
Le bac à sable reflète vos objets et champs personnalisés, de sorte que la documentation est toujours précise pour votre espace de travail.
## Batch Operations
## Opérations par Lot
Both REST and GraphQL support batch operations:
REST et GraphQL prennent en charge les opérations par lot :
* **Batch size**: Up to 60 records per request
* **Operations**: Create, update, delete multiple records
* **Taille du lot** : Jusqu'à 60 enregistrements par requête
* **Opérations** : Créer, mettre à jour, supprimer plusieurs enregistrements
**GraphQL-only features:**
**Fonctionnalités spécifiques à GraphQL :**
* **Batch Upsert**: Create or update in one call
* Use plural object names (e.g., `CreateCompanies` instead of `CreateCompany`)
* **Upsert par lot** : Créer ou mettre à jour en un seul appel
* Utilisez des noms d'objets au pluriel (par exemple, `CreateCompanies` au lieu de `CreateCompany`)
## Rate Limits
## Limites de débit
API requests are throttled to ensure platform stability:
Les requêtes API sont limitées pour garantir la stabilité de la plateforme :
| Limit | Value |
| -------------- | -------------------- |
| **Requests** | 100 calls per minute |
| **Batch size** | 60 records per call |
| Limite | Valeur |
| ----------------- | ---------------------------- |
| **Requêtes** | 100 appels par minute |
| **Taille du lot** | 60 enregistrements par appel |
<Tip>
Use batch operations to maximize throughput — process up to 60 records in a single API call instead of making individual requests.
Utilisez les opérations par lot pour maximiser le débit — traitez jusqu'à 60 enregistrements dans un seul appel API au lieu d'effectuer des requêtes individuelles.
</Tip>
@@ -1,81 +1,88 @@
---
title: Twenty Apps
description: Build and manage Twenty customizations as code.
title: Applications Twenty
description: Créez et gérez les personnalisations Twenty sous forme de code.
---
<Warning>
Apps are currently in alpha testing. The feature is functional but still evolving.
Les applications sont actuellement en phase de test alpha. La fonctionnalité est fonctionnelle mais encore en évolution.
</Warning>
## What Are Apps?
## Que sont les applications ?
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.
Les applications vous permettent de créer et de gérer des personnalisations Twenty **sous forme de code**. Au lieu de tout configurer via linterface utilisateur, vous définissez votre modèle de données et des fonctions sans serveur dans le code — ce qui accélère la création, la maintenance et le déploiement sur plusieurs espaces de travail.
**What you can do today:**
**Ce que vous pouvez faire aujourd'hui:**
* Define custom objects and fields as code (managed data model)
* Build serverless functions with custom triggers
* Deploy the same app across multiple workspaces
* Définir des objets et des champs personnalisés sous forme de code (modèle de données géré)
* Créer des fonctions sans serveur avec des déclencheurs personnalisés
* Déployer la même application sur plusieurs espaces de travail
**Coming soon:**
**Bientôt disponible :**
* Custom UI layouts and components
* Mises en page et composants dinterface utilisateur personnalisés
## Prerequisites
## Prérequis
* Node.js 24+ and Yarn 4
* A Twenty workspace and an API key (create one at https://app.twenty.com/settings/api-webhooks)
* Node.js 24+ et Yarn 4
* Un espace de travail Twenty et une clé API (créez-en une sur https://app.twenty.com/settings/api-webhooks)
## Getting Started
## Prise en main
Create a new app using the official scaffolder, then authenticate and start developing:
Créez une nouvelle application avec loutil damorçage officiel, puis authentifiez-vous et commencez à développer :
```bash filename="Terminal"
# Scaffold a new app
# Générez une nouvelle application
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app
# Authenticate using your API key (you'll be prompted)
yarn auth
# Si vous n'utilisez pas yarn@4
corepack enable
yarn install
# Start dev mode: automatically syncs local changes to your workspace
yarn dev
# Authentifiez-vous avec votre clé API (une invite s'affichera)
yarn auth:login
# Démarrez le mode développement : synchronise automatiquement les modifications locales avec votre espace de travail
yarn app:dev
```
From here you can:
À partir d'ici, vous pouvez :
```bash filename="Terminal"
# Add a new entity to your application (guided)
yarn create-entity
yarn app:create-entity
# Generate a typed Twenty client and workspace entity types
yarn generate
yarn app:generate
# Run a onetime sync (instead of watch mode)
yarn sync
yarn app:sync
# Watch your application's functions logs
yarn logs
yarn function:logs
# Execute a function by name
yarn function:execute -n my-function -p '{"name": "test"}'
# Uninstall the application from the current workspace
yarn uninstall
yarn app:uninstall
# Display commands' help
yarn help
yarn app:help},{
```
See also: the CLI reference pages for [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) and [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
Voir aussi : les pages de référence CLI pour [create-twenty-app](https://www.npmjs.com/package/create-twenty-app) et [twenty-sdk CLI](https://www.npmjs.com/package/twenty-sdk).
## Project structure (scaffolded)
## Structure du projet (générée)
When you run `npx create-twenty-app@latest my-twenty-app`, the scaffolder:
Lorsque vous exécutez `npx create-twenty-app@latest my-twenty-app`, loutil de scaffolding :
* Copies a minimal base application into `my-twenty-app/`
* Adds a local `twenty-sdk` dependency and Yarn 4 configuration
* Creates config files and scripts wired to the `twenty` CLI
* Generates a default application config and a default function role
* Copie une application de base minimale dans `my-twenty-app/`
* Ajoute une dépendance locale à `twenty-sdk` et la configuration Yarn 4
* Crée des fichiers de configuration et des scripts reliés à la CLI `twenty`
* Génère une configuration dapplication par défaut et un rôle de fonction par défaut
A freshly scaffolded app looks like this:
Une application nouvellement générée ressemble à ceci :
```text filename="my-twenty-app/"
my-twenty-app/
@@ -85,79 +92,144 @@ my-twenty-app/
.nvmrc
.yarnrc.yml
.yarn/
releases/
yarn-4.9.2.cjs
install-state.gz
eslint.config.mjs
tsconfig.json
README.md
src/
application.config.ts
role.config.ts
// your entities, actions, and other app files
app/
application.config.ts # Obligatoire - configuration principale de l'application
default-function.role.ts # Rôle par défaut pour les fonctions serverless
// vos entités (*.object.ts, *.function.ts, *.role.ts)
utils/ # Optionnel - implémentations de gestionnaires et utilitaires
```
At a high level:
### Convention plutôt que configuration
* **package.json**: Declares the app name, version, engines (Node 24+, Yarn 4), and adds `twenty-sdk` plus scripts like `dev`, `sync`, `generate`, `create-entity`, `logs`, `uninstall`, and `auth` that delegate to the local `twenty` CLI.
* **.gitignore**: Ignores common artifacts such as `node_modules`, `.yarn`, `generated/` (typed client), `dist/`, `build/`, coverage folders, log files, and `.env*` files.
* **yarn.lock**, **.yarnrc.yml**, **.yarn/**: Lock and configure the Yarn 4 toolchain used by the project.
* **.nvmrc**: Pins the Node.js version expected by the project.
* **eslint.config.mjs** and **tsconfig.json**: Provide linting and TypeScript configuration for your apps TypeScript sources.
* **README.md**: A short README in the app root with basic instructions.
* **src/**: The main place where you define your application-as-code:
* `application.config.ts`: Global configuration for your app (metadata and runtime wiring). See “Application config” below.
* `role.config.ts`: Default function role used by your serverless functions. See “Default function role” below.
* Future entities, actions/functions, and any supporting code you add.
Les applications adoptent une approche **convention plutôt que configuration** où les entités sont détectées par leur suffixe de fichier. Cela permet une organisation flexible dans le dossier `src/app/` :
Later commands will add more files and folders:
| Suffixe de fichier | Type dentité |
| ------------------ | ------------------------------------- |
| `*.object.ts` | Définitions dobjets personnalisés |
| `*.function.ts` | Définitions de fonctions sans serveur |
| `*.role.ts` | Définitions de rôles |
* `yarn generate` will create a `generated/` folder (typed Twenty client + workspace types).
* `yarn create-entity` will add entity definition files under `src/` for your custom objects.
### Structures de dossiers prises en charge
## Authentication
Vous pouvez organiser vos entités selon lun des schémas suivants :
The first time you run `yarn auth`, you'll be prompted for:
**Traditionnelle (par type) :**
* API URL (defaults to http://localhost:3000 or your current workspace profile)
* API key
```text
src/app/
├── application.config.ts
├── objects/
│ └── postCard.object.ts
├── functions/
│ └── createPostCard.function.ts
└── roles/
└── admin.role.ts
```
Your credentials are stored per-user in `~/.twenty/config.json`. You can maintain multiple profiles and switch using `--workspace <name>`.
**Par fonctionnalité :**
Examples:
```text
src/app/
├── application.config.ts
└── post-card/
├── postCard.object.ts
├── createPostCard.function.ts
└── postCardAdmin.role.ts
```
**À plat :**
```text
src/app/
├── application.config.ts
├── postCard.object.ts
├── createPostCard.function.ts
└── admin.role.ts
```
Dans les grandes lignes :
* **package.json** : Déclare le nom de lapplication, la version, les moteurs (Node 24+, Yarn 4), et ajoute `twenty-sdk` ainsi que des scripts comme `dev`, `sync`, `generate`, `create-entity`, `logs`, `uninstall` et `auth` qui délèguent à la CLI locale `twenty`.
* **.gitignore** : Ignore les artefacts courants tels que `node_modules`, `.yarn`, `generated/` (client typé), `dist/`, `build/`, les dossiers de couverture, les fichiers journaux et les fichiers `.env*`.
* **yarn.lock**, **.yarnrc.yml**, **.yarn/** : Verrouillent et configurent la chaîne doutils Yarn 4 utilisée par le projet.
* **.nvmrc** : Fige la version de Node.js attendue par le projet.
* **eslint.config.mjs** et **tsconfig.json** : Fournissent la configuration de linting et TypeScript pour les sources TypeScript de votre application.
* **README.md** : Un bref README à la racine de lapplication avec des instructions de base.
* **src/app/** : Lendroit principal où vous définissez votre application sous forme de code :
* `application.config.ts` : Configuration globale de votre application (métadonnées et liaisons dexécution). Voir « Configuration de lapplication » ci-dessous.
* `*.role.ts` : Définitions de rôles utilisées par vos fonctions sans serveur. Voir « Rôle de fonction par défaut » ci-dessous.
* `*.object.ts` : Définitions dobjets personnalisés.
* `*.function.ts` : Définitions de fonctions sans serveur.
* **src/utils/** : Dossier facultatif pour les implémentations de gestionnaires et utilitaires.
Des commandes ultérieures ajouteront dautres fichiers et dossiers :
* `yarn app:generate` créera un dossier `generated/` (client Twenty typé + types de lespace de travail).
* `yarn app:create-entity` ajoutera des fichiers de définition dentité sous `src/app/` pour vos objets, fonctions ou rôles personnalisés.
l
## Authentification
La première fois que vous exécutez `yarn auth:login`, il vous sera demandé :
* URL de lAPI (par défaut http://localhost:3000 ou votre profil despace de travail actuel)
* Clé API
Vos identifiants sont stockés par utilisateur dans `~/.twenty/config.json`. Vous pouvez gérer plusieurs profils et basculer entre eux.
### Gestion des espaces de travail
```bash filename="Terminal"
# Login interactively (recommended)
yarn auth
yarn auth:login
# Use a specific workspace profile
yarn auth --workspace my-custom-workspace
# Login to a specific workspace profile
yarn auth:login --workspace my-custom-workspace
# List all configured workspaces
yarn auth:list
# Switch the default workspace (interactive)
yarn auth:switch
# Switch to a specific workspace
yarn auth:switch production
# Check current authentication status
yarn auth:status
```
## Use the SDK resources (types & config)
Une fois que vous avez changé d'espace de travail avec `auth:switch`, toutes les commandes suivantes utiliseront cet espace de travail par défaut. Vous pouvez toujours le surcharger temporairement avec `--workspace <name>`.
The twenty-sdk provides typed building blocks you use inside your app. Below are the key pieces you'll touch most often.
## Utiliser les ressources du SDK (types et configuration)
### Defining objects
Le paquet twenty-sdk fournit des blocs de construction typés et des fonctions utilitaires que vous utilisez dans votre application. Voici les éléments clés que vous manipulerez le plus souvent.
Custom objects are regular TypeScript classes annotated with decorators from `twenty-sdk`. They live under `src/objects/` in your app and describe both schema and behavior for records in your workspace.
### Fonctions utilitaires
Here is an example `postCard` object from the Hello World app:
Le SDK fournit quatre fonctions utilitaires avec validation intégrée pour définir les entités de votre application :
| Fonction | Objectif |
| ------------------ | ---------------------------------------------------------- |
| `defineApp()` | Configurer les métadonnées de lapplication |
| `defineObject()` | Définir des objets personnalisés avec des champs |
| `defineFunction()` | Définir des fonctions sans serveur avec des gestionnaires |
| `defineRole()` | Configurer les autorisations de rôle et laccès aux objets |
Ces fonctions valident votre configuration à lexécution et offrent une meilleure autocomplétion IDE et une sécurité de typage accrue.
### Définir des objets
Les objets personnalisés décrivent à la fois le schéma et le comportement des enregistrements dans votre espace de travail. Utilisez `defineObject()` pour définir des objets avec validation intégrée :
```typescript
import { type Note } from '../../generated';
import {
type AddressField,
Field,
FieldType,
type FullNameField,
Object,
OnDeleteAction,
Relation,
RelationType,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
} from 'twenty-sdk';
// src/app/postCard.object.ts
import { defineObject, FieldType } from 'twenty-sdk';
enum PostCardStatus {
DRAFT = 'DRAFT',
@@ -166,176 +238,186 @@ enum PostCardStatus {
RETURNED = 'RETURNED',
}
@Object({
export default defineObject({
universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
nameSingular: 'postCard',
namePlural: 'postCards',
labelSingular: 'Post card',
labelPlural: 'Post cards',
description: ' A post card object',
labelSingular: 'Post Card',
labelPlural: 'Post Cards',
description: 'A post card object',
icon: 'IconMail',
})
export class PostCard {
@Field({
universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
type: FieldType.TEXT,
label: 'Content',
description: "Postcard's content",
icon: 'IconAbc',
})
content: string;
@Field({
universalIdentifier: 'c6aa31f3-da76-4ac6-889f-475e226009ac',
type: FieldType.FULL_NAME,
label: 'Recipient name',
icon: 'IconUser',
})
recipientName: FullNameField;
@Field({
universalIdentifier: '95045777-a0ad-49ec-98f9-22f9fc0c8266',
type: FieldType.ADDRESS,
label: 'Recipient address',
icon: 'IconHome',
})
recipientAddress: AddressField;
@Field({
universalIdentifier: '87b675b8-dd8c-4448-b4ca-20e5a2234a1e',
type: FieldType.SELECT,
label: 'Status',
icon: 'IconSend',
defaultValue: `'${PostCardStatus.DRAFT}'`,
options: [
{ value: PostCardStatus.DRAFT, label: 'Draft', position: 0, color: 'gray' },
{ value: PostCardStatus.SENT, label: 'Sent', position: 1, color: 'orange' },
{ value: PostCardStatus.DELIVERED, label: 'Delivered', position: 2, color: 'green' },
{ value: PostCardStatus.RETURNED, label: 'Returned', position: 3, color: 'orange' },
],
})
status: PostCardStatus;
@Relation({
universalIdentifier: 'c9e2b4f4-b9ad-4427-9b42-9971b785edfe',
type: RelationType.ONE_TO_MANY,
label: 'Notes',
icon: 'IconComment',
inverseSideTargetUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.note,
onDelete: OnDeleteAction.CASCADE,
})
notes: Note[];
@Field({
universalIdentifier: 'e06abe72-5b44-4e7f-93be-afc185a3c433',
type: FieldType.DATE_TIME,
label: 'Delivered at',
icon: 'IconCheck',
isNullable: true,
defaultValue: null,
})
deliveredAt?: Date;
}
fields: [
{
universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
name: 'content',
type: FieldType.TEXT,
label: 'Content',
description: "Postcard's content",
icon: 'IconAbc',
},
{
universalIdentifier: 'c6aa31f3-da76-4ac6-889f-475e226009ac',
name: 'recipientName',
type: FieldType.FULL_NAME,
label: 'Recipient name',
icon: 'IconUser',
},
{
universalIdentifier: '95045777-a0ad-49ec-98f9-22f9fc0c8266',
name: 'recipientAddress',
type: FieldType.ADDRESS,
label: 'Recipient address',
icon: 'IconHome',
},
{
universalIdentifier: '87b675b8-dd8c-4448-b4ca-20e5a2234a1e',
name: 'status',
type: FieldType.SELECT,
label: 'Status',
icon: 'IconSend',
defaultValue: `'${PostCardStatus.DRAFT}'`,
options: [
{ value: PostCardStatus.DRAFT, label: 'Draft', position: 0, color: 'gray' },
{ value: PostCardStatus.SENT, label: 'Sent', position: 1, color: 'orange' },
{ value: PostCardStatus.DELIVERED, label: 'Delivered', position: 2, color: 'green' },
{ value: PostCardStatus.RETURNED, label: 'Returned', position: 3, color: 'orange' },
],
},
{
universalIdentifier: 'e06abe72-5b44-4e7f-93be-afc185a3c433',
name: 'deliveredAt',
type: FieldType.DATE_TIME,
label: 'Delivered at',
icon: 'IconCheck',
isNullable: true,
defaultValue: null,
},
],
});
```
Key points:
Points clés :
* The `@Object` decorator defines the object identity and labels used across the workspace; its `universalIdentifier` must be unique and stable across deployments.
* Each `@Field` decorator defines a field on the object with a type, label, and its own stable `universalIdentifier`.
* `@Relation` wires this object to other objects (standard or custom) and controls cascade behavior with `onDelete`.
* You can scaffold new objects using `yarn create-entity`, which guides you through naming, fields, and relationships, then generates object files similar to the `postCard` example.
* Utilisez `defineObject()` pour une validation intégrée et une meilleure prise en charge par lIDE.
* Le `universalIdentifier` doit être unique et stable entre les déploiements.
* Chaque champ nécessite un `name`, un `type`, un `label` et son propre `universalIdentifier` stable.
* Le tableau `fields` est facultatif — vous pouvez définir des objets sans champs personnalisés.
* Vous pouvez générer de nouveaux objets avec `yarn app:create-entity`, qui vous guide à travers le nommage, les champs et les relations.
### Application config (application.config.ts)
<Note>
**Les champs de base sont créés automatiquement.** Lorsque vous définissez un objet personnalisé, Twenty ajoute automatiquement des champs standard tels que `name`, `createdAt`, `updatedAt`, `createdBy`, `position` et `deletedAt`. Vous n'avez pas besoin de les définir dans votre tableau `fields` — ajoutez uniquement vos champs personnalisés.
</Note>
Every app has a single `application.config.ts` file that describes:
<Accordion title="Alternative : syntaxe basée sur des décorateurs">
Vous pouvez également définir des objets à laide de décorateurs TypeScript. Cette approche utilise une syntaxe basée sur les classes avec les décorateurs `@Object`, `@Field` et `@Relation` :
* **Who the app is**: identifiers, display name, and description.
* **How its functions run**: which role they use for permissions.
* **(Optional) variables**: keyvalue pairs exposed to your functions as environment variables.
```typescript
import {
type AddressField,
Field,
FieldType,
type FullNameField,
Object,
OnDeleteAction,
Relation,
RelationType,
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
} from 'twenty-sdk';
import { type Note } from '../../generated';
When you scaffold a new app, you start with a minimal config:
@Object({
universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
nameSingular: 'postCard',
namePlural: 'postCards',
labelSingular: 'Post card',
labelPlural: 'Post cards',
description: 'A post card object',
icon: 'IconMail',
})
export class PostCard {
@Field({
universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
type: FieldType.TEXT,
label: 'Content',
description: "Postcard's content",
icon: 'IconAbc',
})
content: string;
@Relation({
universalIdentifier: 'c9e2b4f4-b9ad-4427-9b42-9971b785edfe',
type: RelationType.ONE_TO_MANY,
label: 'Notes',
icon: 'IconComment',
inverseSideTargetUniversalIdentifier: STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.note,
onDelete: OnDeleteAction.CASCADE,
})
notes: Note[];
}
```
Remarque : lapproche avec décorateurs requiert `experimentalDecorators` dans votre configuration TypeScript.
</Accordion>
### Configuration de lapplication (application.config.ts)
Chaque application dispose dun seul fichier `application.config.ts` qui décrit :
* **Identité de lapplication** : identifiants, nom daffichage et description.
* **Exécution des fonctions** : le rôle utilisé pour les autorisations.
* **Variables (facultatif)** : paires clé–valeur exposées à vos fonctions en tant que variables denvironnement.
Utilisez `defineApp()` pour définir la configuration de votre application :
```typescript
import { type ApplicationConfig } from 'twenty-sdk';
// src/app/application.config.ts
import { defineApp } from 'twenty-sdk';
import { DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER } from './default-function.role';
const config: ApplicationConfig = {
universalIdentifier: '<generated-app-uuid>',
export default defineApp({
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
displayName: 'My Twenty App',
description: 'My first Twenty app',
functionRoleUniversalIdentifier: '<generated-role-uuid>',
};
export default config;
```
You can gradually extend this file as your app grows. For example, you can add an icon and application-scoped variables:
```typescript
import { type ApplicationConfig } from 'twenty-sdk';
const config: ApplicationConfig = {
universalIdentifier: '<your-app-uuid>',
displayName: 'My App',
description: 'What your app does',
icon: 'IconWorld', // Choose an icon by name
icon: 'IconWorld',
applicationVariables: {
DEFAULT_RECIPIENT_NAME: {
universalIdentifier: '<uuid>',
description: 'Default recipient used by functions',
universalIdentifier: '19e94e59-d4fe-4251-8981-b96d0a9f74de',
description: 'Default recipient name for postcards',
value: 'Jane Doe',
isSecret: false,
},
},
functionRoleUniversalIdentifier: '<your-role-uuid>',
};
export default config;
functionRoleUniversalIdentifier: DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER,
});
```
Notes:
Notes :
* `universalIdentifier` fields are deterministic IDs you own; generate them once and keep them stable across syncs.
* `applicationVariables` become environment variables for your functions (for example, `DEFAULT_RECIPIENT_NAME` is available as `process.env.DEFAULT_RECIPIENT_NAME`).
* `functionRoleUniversalIdentifier` must match the role you define in `role.config.ts` (see below).
* Les champs `universalIdentifier` sont des identifiants déterministes que vous possédez ; générez-les une fois et conservez-les stables entre les synchronisations.
* `applicationVariables` deviennent des variables denvironnement pour vos fonctions (par exemple, `DEFAULT_RECIPIENT_NAME` est disponible sous `process.env.DEFAULT_RECIPIENT_NAME`).
* `functionRoleUniversalIdentifier` doit correspondre au rôle que vous définissez dans votre fichier `*.role.ts` (voir ci-dessous).
#### Roles and permissions
#### Rôles et autorisations
Applications can define roles that encapsulate permissions on your workspaces objects and actions. The field `functionRoleUniversalIdentifier` in `application.config.ts` designates the default role used by your apps serverless functions.
Les applications peuvent définir des rôles qui encapsulent des autorisations sur les objets et actions de votre espace de travail. Le champ `functionRoleUniversalIdentifier` dans `application.config.ts` désigne le rôle par défaut utilisé par les fonctions sans serveur de votre application.
* The runtime API key injected as `TWENTY_API_KEY` is derived from this default function role.
* The typed client will be restricted to the permissions granted to that role.
* Follow leastprivilege: create a dedicated role with only the permissions your functions need, then reference its universal identifier.
* La clé API dexécution injectée sous `TWENTY_API_KEY` est dérivée de ce rôle de fonction par défaut.
* Le client typé sera limité aux autorisations accordées à ce rôle.
* Appliquez le principe du moindre privilège : créez un rôle dédié avec uniquement les autorisations nécessaires à vos fonctions, puis référencez son identifiant universel.
##### Default function role (role.config.ts)
##### Rôle de fonction par défaut (\*.role.ts)
When you scaffold a new app, the CLI also creates `src/role.config.ts`. This file exports the default role your serverless functions will use at runtime:
Lorsque vous générez une nouvelle application, la CLI crée également un fichier de rôle par défaut. Utilisez `defineRole()` pour définir des rôles avec validation intégrée :
```typescript
import { PermissionFlag, type RoleConfig } from 'twenty-sdk';
// src/app/default-function.role.ts
import { defineRole, PermissionFlag } from 'twenty-sdk';
export const functionRole: RoleConfig = {
universalIdentifier: '<generated-role-uuid>',
label: 'My Twenty App default function role',
description: 'My Twenty App default function role',
canReadAllObjectRecords: true,
canUpdateAllObjectRecords: true,
canSoftDeleteAllObjectRecords: true,
canDestroyAllObjectRecords: false,
};
```
export const DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER =
'b648f87b-1d26-4961-b974-0908fd991061';
The `universalIdentifier` of this role is automatically wired into `application.config.ts` as `functionRoleUniversalIdentifier`. In other words:
* **role.config.ts** defines what the default function role can do.
* **application.config.ts** points to that role so your functions inherit its permissions.
As you move beyond the initial scaffold, you should tighten this role and make it explicit about what it can access. A more production-ready role might look closer to:
```typescript
import { PermissionFlag, type RoleConfig } from 'twenty-sdk';
export const functionRole: RoleConfig = {
universalIdentifier: '<your-role-uuid>',
export default defineRole({
universalIdentifier: DEFAULT_FUNCTION_ROLE_UNIVERSAL_IDENTIFIER,
label: 'Default function role',
description: 'Default role for function Twenty client',
canReadAllObjectRecords: false,
@@ -363,41 +445,41 @@ export const functionRole: RoleConfig = {
canUpdateFieldValue: false,
},
],
permissionFlags: ['APPLICATIONS'],
};
permissionFlags: [PermissionFlag.APPLICATIONS],
});
```
Notes:
Le `universalIdentifier` de ce rôle est ensuite référencé dans `application.config.ts` en tant que `functionRoleUniversalIdentifier`. En dautres termes :
* Start from the scaffolded role, then progressively restrict it following leastprivilege.
* Replace the `objectPermissions` and `fieldPermissions` with the objects/fields your functions need.
* `permissionFlags` control access to platform-level capabilities. Keep them minimal; add only what you need.
* See a working example in the Hello World app: [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
* **\*.role.ts** définit ce que le rôle de fonction par défaut peut faire.
* **application.config.ts** pointe vers ce rôle afin que vos fonctions héritent de ses autorisations.
### Serverless function config and entrypoint
Notes :
Each function exports a main handler and a config describing its triggers. You can mix multiple trigger types.
* Partez du rôle généré, puis restreignez-le progressivement en suivant le principe du moindre privilège.
* Remplacez `objectPermissions` et `fieldPermissions` par les objets/champs dont vos fonctions ont besoin.
* `permissionFlags` contrôlent laccès aux capacités au niveau de la plateforme. Gardez-les au minimum ; najoutez que ce dont vous avez besoin.
* Voir un exemple fonctionnel dans lapplication Hello World : [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
### Configuration et point dentrée des fonctions sans serveur
Chaque fichier de fonction utilise `defineFunction()` pour exporter une configuration avec un gestionnaire et des déclencheurs facultatifs. Utilisez le suffixe de fichier `*.function.ts` pour la détection automatique.
```typescript
// src/actions/create-new-post-card.ts
import type {
FunctionConfig,
DatabaseEventPayload,
ObjectRecordCreateEvent,
CronPayload,
} from 'twenty-sdk';
import Twenty, { type Person } from '../generated';
// src/app/createPostCard.function.ts
import { defineFunction } from 'twenty-sdk';
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk';
import Twenty, { type Person } from '../../generated';
// main handler can accept parameters from route, cron, or database events
export const main = async (
const handler = async (
params:
| { name?: string }
| RoutePayload
| DatabaseEventPayload<ObjectRecordCreateEvent<Person>>
| CronPayload,
) => {
const client = new Twenty(); // generated typed client
const name = 'name' in params
? params.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
const name = 'name' in params.queryStringParameters
? params.queryStringParameters.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
: 'Hello world';
const result = await client.mutation({
@@ -410,14 +492,15 @@ export const main = async (
return result;
};
export const config: FunctionConfig = {
universalIdentifier: '<function-uuid>',
export default defineFunction({
universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
name: 'create-new-post-card',
timeoutSeconds: 2,
handler,
triggers: [
// Public HTTP route trigger '/s/post-card/create'
{
universalIdentifier: '<route-trigger-uuid>',
universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
type: 'route',
path: '/post-card/create',
httpMethod: 'GET',
@@ -425,39 +508,137 @@ export const config: FunctionConfig = {
},
// Cron trigger (CRON pattern)
{
universalIdentifier: '<cron-trigger-uuid>',
universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
type: 'cron',
pattern: '0 0 1 1 *',
},
// Database event trigger
{
universalIdentifier: '<db-trigger-uuid>',
universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
type: 'databaseEvent',
eventName: 'person.created',
eventName: 'person.updated',
updatedFields: ['name'],
},
],
});
```
Types de déclencheurs courants :
* **route** : Expose votre fonction sur un chemin et une méthode HTTP **sous lendpoint `/s/`** :
> p. ex. `path: '/post-card/create',` -> appel sur `<APP_URL>/s/post-card/create`
* **cron** : Exécute votre fonction selon une planification à laide dune expression CRON.
* **databaseEvent**: S'exécute lors des événements du cycle de vie des objets de l'espace de travail. Lorsque l'opération de l'événement est `updated`, des champs spécifiques à surveiller peuvent être spécifiés dans le tableau `updatedFields`. S'il est laissé indéfini ou vide, toute mise à jour déclenchera la fonction.
> p. ex. `person.updated`
Notes :
* Le tableau `triggers` est facultatif. Les fonctions sans déclencheurs peuvent servir de fonctions utilitaires appelées par dautres fonctions.
* Vous pouvez combiner plusieurs types de déclencheurs dans une seule fonction.
### Charge utile du déclencheur de route
<Warning>
**Changement incompatible (v1.16, janvier 2026):** Le format de la charge utile du déclencheur de route a changé. Avant la v1.16, les paramètres de requête, les paramètres de chemin et le corps de la requête étaient envoyés directement en tant que charge utile. À partir de la v1.16, ils sont imbriqués dans un objet `RoutePayload` structuré.
**Avant la v1.16 :**
```typescript
const handler = async (params) => {
const { param1, param2 } = params; // Direct access
};
```
**Après la v1.16 :**
```typescript
const handler = async (event: RoutePayload) => {
const { param1, param2 } = event.body; // Access via .body
const { queryParam } = event.queryStringParameters;
const { id } = event.pathParameters;
};
```
**Pour migrer les fonctions existantes :** Mettez à jour votre gestionnaire pour déstructurer à partir de `event.body`, `event.queryStringParameters` ou `event.pathParameters` plutôt que directement à partir de l'objet params.
</Warning>
Lorsqu'un déclencheur de route appelle votre fonction, elle reçoit un objet `RoutePayload` qui suit le format AWS HTTP API v2. Importez le type depuis `twenty-sdk` :
```typescript
import { defineFunction, type RoutePayload } from 'twenty-sdk';
const handler = async (event: RoutePayload) => {
// Access request data
const { headers, queryStringParameters, pathParameters, body } = event;
// HTTP method and path are available in requestContext
const { method, path } = event.requestContext.http;
return { message: 'Success' };
};
```
Common trigger types:
Le type `RoutePayload` a la structure suivante :
* route: Exposes your function on an HTTP path and method **under the `/s/` endpoint**:
| Nom de la propriété | Type | Description |
| ---------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------- |
| `headers` | `Record<string, string \| undefined>` | En-têtes HTTP (uniquement ceux répertoriés dans `forwardedRequestHeaders`) |
| `queryStringParameters` | `Record<string, string \| undefined>` | Paramètres de la chaîne de requête (plusieurs valeurs séparées par des virgules) |
| `pathParameters` | `Record<string, string \| undefined>` | Paramètres de chemin extraits du modèle de route (p. ex., `/users/:id` → `{ id: '123' }`) |
| `corps du message` | `object \| null` | Corps de la requête analysé (JSON) |
| `isBase64Encoded` | `booléen` | Indique si le corps est encodé en base64 |
| `requestContext.http.method` | `string` | Méthode HTTP (GET, POST, PUT, PATCH, DELETE) |
| `requestContext.http.path` | `string` | Chemin de la requête brut |
> e.g. `path: '/post-card/create',` -> call on `<APP_URL>/s/post-card/create`
### Transfert des en-têtes HTTP
* cron: Runs your function on a schedule using a CRON expression.
* databaseEvent: Runs on workspace object lifecycle events
Par défaut, les en-têtes HTTP des requêtes entrantes ne sont pas transmis à votre fonction sans serveur pour des raisons de sécurité. Pour accéder à des en-têtes spécifiques, listez-les explicitement dans le tableau `forwardedRequestHeaders` :
> e.g. `person.created`
```typescript
export default defineFunction({
universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
name: 'webhook-handler',
handler,
triggers: [
{
universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
type: 'route',
path: '/webhook',
httpMethod: 'POST',
isAuthRequired: false,
forwardedRequestHeaders: ['x-webhook-signature', 'content-type'],
},
],
});
```
You can create new functions in two ways:
Dans votre gestionnaire, vous pouvez ensuite accéder à ces en-têtes :
* **Scaffolded**: Run `yarn create-entity --path <custom-path>` and choose the option to add a new function. This generates a starter file under `<custom-path>` with a `main` handler and a `config` block similar to the example above.
* **Manual**: Create a new file and export `main` and `config` yourself, following the same pattern.
```typescript
const handler = async (event: RoutePayload) => {
const signature = event.headers['x-webhook-signature'];
const contentType = event.headers['content-type'];
### Generated typed client
// Validate webhook signature...
return { received: true };
};
```
Run yarn generate to create a local typed client in generated/ based on your workspace schema. Use it in your functions:
<Note>
Les noms d'en-têtes sont normalisés en minuscules. Accédez-y en utilisant des clés en minuscules (par exemple, `event.headers['content-type']`).
</Note>
Vous pouvez créer de nouvelles fonctions de deux façons :
* **Générée** : Exécutez `yarn app:create-entity` et choisissez loption pour ajouter une nouvelle fonction. Cela génère un fichier de démarrage avec un gestionnaire et une configuration.
* **Manuelle** : Créez un nouveau fichier `*.function.ts` et utilisez `defineFunction()`, en suivant le même modèle.
### Client typé généré
Exécutez yarn app:generate pour créer un client typé local dans generated/ basé sur le schéma de votre espace de travail. Utilisez-le dans vos fonctions :
```typescript
import Twenty from './generated';
@@ -466,34 +647,34 @@ const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
```
The client is re-generated by `yarn generate`. Re-run after changing your objects and `yarn sync` or when onboarding to a new workspace.
Le client est régénéré par `yarn app:generate`. Relancez la commande après avoir modifié vos objets et exécuté `yarn app:sync`, ou lors de lintégration à un nouvel espace de travail.
#### Runtime credentials in serverless functions
#### Identifiants dexécution dans les fonctions sans serveur
When your function runs on Twenty, the platform injects credentials as environment variables before your code executes:
Lorsque votre fonction sexécute sur Twenty, la plateforme injecte des identifiants sous forme de variables denvironnement avant lexécution de votre code :
* `TWENTY_API_URL`: Base URL of the Twenty API your app targets.
* `TWENTY_API_KEY`: Shortlived key scoped to your applications default function role.
* `TWENTY_API_URL` : URL de base de lAPI Twenty ciblée par votre application.
* `TWENTY_API_KEY` : Clé de courte durée limitée au rôle de fonction par défaut de votre application.
Notes:
* You do not need to pass URL or API key to the generated client. It reads `TWENTY_API_URL` and `TWENTY_API_KEY` from process.env at runtime.
* The API keys permissions are determined by the role referenced in your `application.config.ts` via `functionRoleUniversalIdentifier`. This is the default role used by serverless functions of your application.
* Applications can define roles to follow leastprivilege. Grant only the permissions your functions need, then point `functionRoleUniversalIdentifier` to that roles universal identifier.
* Vous navez pas besoin de passer lURL ou la clé API au client généré. Il lit `TWENTY_API_URL` et `TWENTY_API_KEY` depuis process.env à lexécution.
* Les autorisations de la clé API sont déterminées par le rôle référencé dans votre `application.config.ts` via `functionRoleUniversalIdentifier`. Il sagit du rôle par défaut utilisé par les fonctions sans serveur de votre application.
* Les applications peuvent définir des rôles pour appliquer le principe du moindre privilège. Naccordez que les autorisations dont vos fonctions ont besoin, puis faites pointer `functionRoleUniversalIdentifier` vers lidentifiant universel de ce rôle.
### Hello World example
### Exemple Hello World
Explore a minimal, end-to-end example that demonstrates objects, functions, and multiple triggers [here](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world):
Découvrez un exemple minimal de bout en bout qui démontre des objets, des fonctions et plusieurs déclencheurs [ici](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/hello-world) :
## Manual setup (without the scaffolder)
## Configuration manuelle (sans loutil de scaffolding)
While we recommend using `create-twenty-app` for the best getting-started experience, you can also set up a project manually. Do not install the CLI globally. Instead, add `twenty-sdk` as a local dependency and wire scripts in your package.json:
Même si nous recommandons dutiliser `create-twenty-app` pour une expérience de démarrage optimale, vous pouvez également configurer un projet manuellement. Ninstallez pas la CLI globalement. Ajoutez plutôt `twenty-sdk` comme dépendance locale et reliez des scripts dans votre package.json :
```bash filename="Terminal"
yarn add -D twenty-sdk
```
Then add scripts like these:
Ajoutez ensuite des scripts comme ceux-ci :
```json filename="package.json"
{
@@ -510,13 +691,13 @@ Then add scripts like these:
}
```
Now you can run the same commands via Yarn, e.g. `yarn dev`, `yarn sync`, etc.
Vous pouvez désormais exécuter les mêmes commandes via Yarn, par exemple `yarn app:dev`, `yarn app:sync`, etc.
## Troubleshooting
## Résolution des problèmes
* Authentication errors: run `yarn auth` and ensure your API key has the required permissions.
* Cannot connect to server: verify the API URL and that the Twenty server is reachable.
* Types or client missing/outdated: run `yarn generate` and then `yarn dev`.
* Dev mode not syncing: ensure `yarn dev` is running and that changes are not ignored by your environment.
* Erreurs dauthentification : exécutez `yarn auth:login` et assurez-vous que votre clé API dispose des autorisations requises.
* Impossible de se connecter au serveur : vérifiez lURL de lAPI et que le serveur Twenty est accessible.
* Types ou client manquants/obsolètes : exécutez `yarn app:generate` puis `yarn app:dev`.
* Le mode dev ne se synchronise pas : assurez-vous que `yarn app:dev` est en cours dexécution et que les modifications ne sont pas ignorées par votre environnement.
Discord Help Channel: https://discord.com/channels/1130383047699738754/1130386664812982322
Canal daide Discord : https://discord.com/channels/1130383047699738754/1130386664812982322
@@ -1,44 +1,44 @@
---
title: Webhooks
description: Receive real-time notifications when events occur in your CRM.
description: Recevez des notifications en temps réel lorsque des événements se produisent dans votre 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.
Les webhooks envoient des données à vos systèmes en temps réel lorsque des événements se produisent dans Twenty — aucune interrogation n'est nécessaire. Utilisez-les pour maintenir les systèmes externes synchronisés, déclencher des automatisations ou envoyer des alertes.
## Create a Webhook
## Créer un Webhook
1. Go to **Settings → APIs & Webhooks → Webhooks**
2. Click **+ Create webhook**
3. Enter your webhook URL (must be publicly accessible)
4. Click **Save**
1. Allez dans **Paramètres → API & Webhooks → Webhooks**
2. Cliquez sur **+ Créer un webhook**
3. Saisissez votre URL de webhook (doit être publiquement accessible)
4. Cliquez sur **Enregistrer**
The webhook activates immediately and starts sending notifications.
Le webhook s'active immédiatement et commence à envoyer des notifications.
<VimeoEmbed videoId="928786708" title="Creating a webhook" />
<VimeoEmbed videoId="928786708" title="Création d'un webhook" />
### Manage Webhooks
### Gérer les Webhooks
**Edit**: Click the webhook → Update URL → **Save**
**Modifier**: Cliquez sur le webhook → Mettre à jour l'URL → **Enregistrer**
**Delete**: Click the webhook → **Delete** → Confirm
**Supprimer**: Cliquez sur le webhook → **Supprimer** → Confirmer
## Events
## Événements
Twenty sends webhooks for these event types:
Twenty envoie des webhooks pour ces types d'événements :
| Event | Example |
| ------------------ | ---------------------------------------------------------- |
| **Record Created** | `person.created`, `company.created`, `note.created` |
| **Record Updated** | `person.updated`, `company.updated`, `opportunity.updated` |
| **Record Deleted** | `person.deleted`, `company.deleted` |
| Événement | Exemple |
| ----------------------------- | ---------------------------------------------------------- |
| **Enregistrement créé** | `person.created`, `company.created`, `note.created` |
| **Enregistrement mis à jour** | `person.updated`, `company.updated`, `opportunity.updated` |
| **Enregistrement supprimé** | `person.deleted`, `company.deleted` |
All event types are sent to your webhook URL. Event filtering may be added in future releases.
Tous les types d'événements sont envoyés à votre URL de webhook. Le filtrage des événements pourrait être ajouté dans de prochaines versions.
## Payload Format
## Format de la charge utile
Each webhook sends an HTTP POST with a JSON body:
Chaque webhook envoie une requête HTTP POST avec un corps JSON :
```json
{
@@ -55,35 +55,35 @@ Each webhook sends an HTTP POST with a JSON body:
}
```
| Field | Description |
| ----------- | ------------------------------------------------ |
| `event` | What happened (e.g., `person.created`) |
| `data` | The full record that was created/updated/deleted |
| `timestamp` | When the event occurred (UTC) |
| Champ | Description |
| ------------ | ----------------------------------------------------------- |
| `événement` | Ce qui s'est passé (par exemple, `person.created`) |
| `données` | L'enregistrement complet qui a été créé/mis à jour/supprimé |
| `horodatage` | Quand l'événement s'est produit (UTC) |
<Note>
Respond with a **2xx HTTP status** (200-299) to acknowledge receipt. Non-2xx responses are logged as delivery failures.
Répondez avec un **statut HTTP 2xx** (200-299) pour accuser réception. Les réponses non 2xx sont consignées comme des échecs de livraison.
</Note>
## Webhook Validation
## Validation des Webhooks
Twenty signs each webhook request for security. Validate signatures to ensure requests are authentic.
Twenty signe chaque requête de webhook pour des raisons de sécurité. Validez les signatures pour garantir l'authenticité des requêtes.
### Headers
### En-têtes
| Header | Description |
| ---------------------------- | --------------------- |
| `X-Twenty-Webhook-Signature` | HMAC SHA256 signature |
| `X-Twenty-Webhook-Timestamp` | Request timestamp |
| En-tête | Description |
| ---------------------------- | ------------------------ |
| `X-Twenty-Webhook-Signature` | Signature HMAC SHA256 |
| `X-Twenty-Webhook-Timestamp` | Horodatage de la requête |
### Validation Steps
### Étapes de validation
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`
1. Récupérez l'horodatage depuis `X-Twenty-Webhook-Timestamp`
2. Créez la chaîne : `{timestamp}:{JSON payload}`
3. Calculez le HMAC SHA256 en utilisant votre secret de webhook
4. Comparez avec `X-Twenty-Webhook-Signature`
### Example (Node.js)
### Exemple (Node.js)
```javascript
const crypto = require("crypto");
@@ -103,10 +103,10 @@ 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 |
| Méthode | Direction | Cas d'utilisation |
| -------------------------------------- | --------- | ------------------------------------------------------------------------------------- |
| **Webhooks** | SORTIE | Notifier automatiquement les systèmes externes de toute modification d'enregistrement |
| **Workflow + requête HTTP** | SORTIE | Envoyer des données avec une logique personnalisée (filtres, transformations) |
| **Déclencheur de webhook de workflow** | ENTRÉE | Recevoir des données dans Twenty depuis des systèmes externes |
For receiving external data, see [Set Up a Webhook Trigger](/l/fr/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger).
Pour recevoir des données externes, voir [Configurer un déclencheur de webhook](/l/fr/user-guide/workflows/how-tos/connect-to-other-tools/set-up-a-webhook-trigger).
@@ -1,34 +1,34 @@
---
title: Extend
description: Extend Twenty's functionality with APIs, webhooks, and custom apps.
title: Étendre
description: Étendez les fonctionnalités de Twenty avec des API, des webhooks et des applications personnalisées.
---
<Frame>
<img src="/images/user-guide/integrations/plug.png" alt="AI" />
<img src="/images/user-guide/integrations/plug.png" alt="IA" />
</Frame>
## Overview
## Vue d'ensemble
Twenty is designed to be extensible. Use our APIs, webhooks, and app framework to integrate with your existing tools and build custom functionality.
Twenty est conçu pour être extensible. Utilisez nos API, nos webhooks et notre framework d'applications pour vous intégrer à vos outils existants et créer des fonctionnalités personnalisées.
## What You Can Do
## Ce que vous pouvez faire
* **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!
* **API** : Interrogez et modifiez vos données CRM par programmation à l'aide de REST ou de GraphQL
* **Webhooks** : Recevez des notifications en temps réel lorsque des événements se produisent dans Twenty
* **Applications** : Créez des applications personnalisées qui étendent les capacités de Twenty - Bientôt disponible !
## Getting Started
## Prise en main
<CardGroup cols={2}>
<Card title="APIs" icon="code" href="/l/fr/developers/extend/capabilities/apis">
Connect to Twenty programmatically
<Card title="API" icon="code" href="/l/fr/developers/extend/capabilities/apis">
Connectez-vous à Twenty par programmation
</Card>
<Card title="Webhooks" icon="bell" href="/l/fr/developers/extend/capabilities/webhooks">
Get notified of events in real-time
Recevez des notifications d'événements en temps réel
</Card>
<Card title="Apps" icon="puzzle-piece" href="/l/fr/developers/extend/capabilities/apps">
Build customizations as code (Alpha)
<Card title="Applications" icon="puzzle-piece" href="/l/fr/developers/extend/capabilities/apps">
Créez des personnalisations sous forme de code (Alpha)
</Card>
</CardGroup>