Complete automation guide for Twenty CRM - Create objects, fields, relations, and views programmatically
This repository contains a complete technical reference for automating Twenty CRM setup using REST and GraphQL APIs. Everything can be done programmatically - no UI required!
- Create Objects - Custom data models (Projects, Tasks, etc.)
- Create Fields - All field types (TEXT, SELECT, RELATION, etc.)
- Create Relations - Link objects together
- Create Views - Table, Kanban, Calendar, Gallery views
- Manage Data - Full CRUD operations
- π€ AI Agents - Complete reference for LLMs to automate CRM setup
- π¨βπ» Developers - Programmatic CRM configuration
- π§ DevOps - Infrastructure as Code for CRM
- π Data Engineers - Automated data model management
1. Login to Twenty CRM
2. Go to Settings β APIs & Webhooks
3. Create API Key
4. Copy the key
pip install requestsimport requests
API_URL = "https://your-instance.com"
API_KEY = "your-api-key"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# Create object
mutation = '''
mutation {
createOneObject(input: {
object: {
nameSingular: "task"
namePlural: "tasks"
labelSingular: "Task"
labelPlural: "Tasks"
icon: "IconCheckbox"
}
}) { id }
}
'''
response = requests.post(f"{API_URL}/metadata", headers=HEADERS, json={"query": mutation})
object_id = response.json()["data"]["createOneObject"]["id"]
print(f"β
Object created: {object_id}")LLM_REFERENCE.md - Complete technical reference in a single file
This document contains:
- β All verified API endpoints
- β Complete code examples
- β Error handling patterns
- β Best practices
- β Production-ready templates
Perfect for AI agents - No additional context needed!
All capabilities tested and confirmed:
- β Objects: Created successfully (Status 200)
- β Fields: 45+ fields created (Status 201)
- β Relations: 6 relations created (Status 201)
- β Views: Mutations verified and accessible
| Feature | REST API | GraphQL API | Status |
|---|---|---|---|
| Create Objects | β | β
/metadata |
Verified |
| Create Fields | β
/rest/metadata/fields |
β
/metadata |
Verified |
| Create Relations | β
/rest/metadata/fields |
β | Verified |
| Create Views | β | β
/metadata |
Verified |
| Data CRUD | β
/graphql |
β
/graphql |
Verified |
All operations work with API Keys - no JWT required!
field_data = {
"name": "status",
"label": "Status",
"type": "SELECT",
"icon": "IconFlag",
"objectMetadataId": object_id,
"options": [
{"label": "To Do", "value": "TODO", "color": "blue", "position": 0},
{"label": "Done", "value": "DONE", "color": "green", "position": 1}
]
}
requests.post(f"{API_URL}/rest/metadata/fields", headers=HEADERS, json=field_data)relation_data = {
"name": "projectRelation",
"label": "Project",
"type": "RELATION",
"icon": "IconLink",
"objectMetadataId": from_object_id,
"relationCreationPayload": {
"type": "MANY_TO_ONE",
"targetObjectMetadataId": to_object_id,
"targetFieldLabel": "Tasks",
"targetFieldIcon": "IconLink"
}
}
requests.post(f"{API_URL}/rest/metadata/fields", headers=HEADERS, json=relation_data)mutation = '''
mutation {
createCoreView(input: {
objectMetadataId: "%s"
name: "All Tasks"
type: "table"
icon: "IconTable"
}) { id }
}
''' % object_id
requests.post(f"{API_URL}/metadata", headers=HEADERS, json={"query": mutation})| Type | Description | Options Required |
|---|---|---|
| TEXT | Single line text | No |
| RICH_TEXT | Multi-line formatted text | No |
| NUMBER | Numeric values | No |
| DATE | Date only | No |
| BOOLEAN | True/False | No |
| SELECT | Single choice dropdown | Yes |
| MULTI_SELECT | Multiple choices | Yes |
| LINKS | URLs | No |
| RELATION | Link to another object | Special |
| Type | Best For | Icon |
|---|---|---|
table |
Detailed data viewing | IconTable |
kanban |
Workflow management | IconLayoutKanban |
calendar |
Date-based data | IconCalendar |
gallery |
Visual/image data | IconLayoutGrid |
# Objects
nameSingular: "task" # camelCase
namePlural: "tasks" # camelCase
labelSingular: "Task" # Title Case
labelPlural: "Tasks" # Title Case
# Fields
name: "projectName" # camelCase
label: "Project Name" # Title Caseimport time
time.sleep(0.2) # 200ms between requestsif response.status_code == 201:
print("β
Created")
elif "not available" in response.text:
print("βοΈ Already exists")
else:
print(f"β Error: {response.text}")Before deploying:
- API key is valid
- Object names follow camelCase
- Field names are unique per object
- SELECT fields have options array
- Rate limiting implemented
- Error handling in place
See LLM_REFERENCE.md for a complete production-ready example with:
- Object creation
- Field creation (TEXT, SELECT)
- View creation
- Error handling
- Rate limiting
Contributions welcome! Please:
- Test all changes
- Update documentation
- Follow existing patterns
- Add examples
MIT License - feel free to use in your projects!
If this helped you automate your Twenty CRM setup, please star the repo!
Made with β€οΈ for the Twenty CRM community