Twenty CRM self-hosted: Salesforce Alternative for SMBs
What This Article Covers
- What Twenty is: a modern open-source CRM, “Salesforce for developers”.
- Docker setup and initial configuration.
- Data model: Companies, People, Opportunities, Workflows.
- REST and GraphQL APIs for integrations.
- AI integration: lead scoring and follow-ups with Ollama.
Introduction
Twenty is the latest credible open-source CRM, explicitly built as a “developer-friendly Salesforce alternative”. React frontend, NestJS backend, Postgres underneath. Modern UI, clean API, actively maintained.
For small and medium-sized businesses that want to self-host customer data (GDPR compliance!), Twenty is the most pragmatic choice: significantly leaner than Salesforce or SuiteCRM, yet fully capable for sales operations.
Typical Use Cases
- Sales Pipeline: deals, stages, activities, classic CRM.
- Lead Management: leads from website forms to Twenty to AI qualification.
- Customer 360: all interactions per customer in one place.
- AI-Powered Follow-ups: Ollama drafts follow-up emails for open deals.
- Newsletter Export: export segments for email workflows.
Installation: Docker
services:
twenty:
image: twentycrm/twenty:latest
ports:
- "127.0.0.1:3000:3000"
environment:
- PG_DATABASE_URL=postgres://twenty:geheim@db:5432/twenty
- SERVER_URL=https://crm.deine-domain.de
- FRONT_URL=https://crm.deine-domain.de
- ACCESS_TOKEN_SECRET=langer-zufaelliger-string
- LOGIN_TOKEN_SECRET=langer-zufaelliger-string-2
- REFRESH_TOKEN_SECRET=langer-zufaelliger-string-3
- FILE_STORAGE_TYPE=local
volumes: [twenty_data:/app/packages/twenty-server/.local-storage]
depends_on: [db]
restart: always
db:
image: postgres:16
environment:
POSTGRES_USER: twenty
POSTGRES_PASSWORD: geheim
POSTGRES_DB: twenty
volumes: [pg_data:/var/lib/postgresql/data]
restart: always
volumes:
twenty_data:
pg_data:
After startup, visit http://localhost:3000 to sign up and create your first workspace.
Data Model
- Companies: your account records.
- People: contacts linked to companies.
- Opportunities: deals with a stage-based pipeline (Kanban view).
- Tasks/Notes: activities and follow-ups.
- Custom Objects: define your own object types.
The model intentionally mirrors Salesforce, making migration and conceptual mapping straightforward.
API for Integrations
Twenty supports both REST and GraphQL. Grab an API key from Settings > APIs:
# List companies
curl -H "Authorization: Bearer DEIN_API_KEY" \
"https://crm.deine-domain.de/rest/companies"
# Create a person
curl -X POST -H "Authorization: Bearer DEIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":{"firstName":"Max","lastName":"Mustermann"},
"emails":{"primaryEmail":"max@firma.de"}}' \
"https://crm.deine-domain.de/rest/people"
AI Integration: Lead Scoring and Follow-ups
import requests
import ollama
TWENTY = "https://crm.deine-domain.de"
HEADERS = {"Authorization": "Bearer DEIN_API_KEY"}
client = ollama.Client(host="http://ollama:11434")
# Open opportunities with no activity for 7 days
deals = requests.get(f"{TWENTY}/rest/opportunities",
headers=HEADERS).json()["data"]
for deal in deals["opportunities"]:
prompt = f"""Deal: {deal['name']}
Stage: {deal['stage']}
Amount: {deal.get('amount',{}).get('amountMicros',0)/1e6}€
Last updated: {deal.get('updatedAt')}
Write a brief, friendly follow-up email draft (3-4 sentences)."""
draft = client.chat(model="llama3.1:8b",
messages=[{"role":"user","content":prompt}])["message"]["content"]
# Attach as task/note to the deal
requests.post(f"{TWENTY}/rest/notes", headers=HEADERS, json={
"title": "AI Follow-up Suggestion",
"body": draft,
"targets": [{"opportunityId": deal["id"]}],
})
n8n Integration
Twenty offers webhooks (Settings > Webhooks > HTTP calls on object events). A typical workflow looks like this:
Twenty Webhook: new lead
│
▼
Ollama: enrich lead data (estimate industry, set priority)
│
▼
Twenty API: update fields + create task for sales
│
▼
If score > X > Slack/Telegram alert to sales team
Security
- Secrets: the three token secrets in
.envmust be long and random. - HTTPS: use a reverse proxy like Caddy, since your CRM contains sensitive customer data.
- API Keys: create separate keys per integration, revokable in Twenty.
- GDPR: on-premise means no data processing agreement with a US provider needed, a major advantage over Salesforce or HubSpot.
Twenty vs. Alternatives
| CRM | Strength | Weakness |
|---|---|---|
| Twenty | Modern UI, open source, developer-friendly | Young, fewer features than SuiteCRM |
| SuiteCRM | Mature, powerful | Legacy UI, heavyweight |
| HubSpot | Marketing integration | Cloud, expensive, US-based hosting |
| Salesforce | Industry standard | Expensive, complex, cloud-only |
| NocoDB | Simpler than a CRM | Not a true CRM data model |
Further Resources
- IRC-Coding.de: programming tutorials on GraphQL, REST APIs.
- NocoDB: for lighter data hubs.
- Chatwoot: customer service counterpart.
- n8n: workflow automation.
- Docker: container basics.
Key Takeaways:
- Twenty is a modern open-source CRM, “developer-friendly Salesforce”.
- Docker plus Postgres, clean REST and GraphQL APIs, Kanban pipeline.
- On-premise means GDPR-friendly without data processing agreements.
- AI integration for lead scoring, follow-up drafts, data enrichment.
- The best open-source CRM entry point for SMBs.
FAQ
Is Twenty production-ready?
Can I migrate from Salesforce or HubSpot?
Email integration?
Custom fields and objects?
Resource requirements?
Mobile app?
Sources and Further Reading
- Twenty: GitHub.
- Twenty Docs: Documentation.
- IRC-Coding.de: Programming tutorials.


