Why Connect Airtable to Odoo?
Airtable sits between spreadsheets and databases. Teams use it for everything from content calendars to inventory tracking to CRM pipelines. The problem arises when Airtable data needs to flow into Odoo for invoicing, accounting, or supply chain operations — or when Odoo data needs to be accessible in Airtable's friendly interface for non-technical team members.
Connecting Airtable to Odoo gives you the best of both worlds: Airtable's flexible, visual interface for data management and Odoo's robust business process automation for operations.
Common Sync Scenarios
| Airtable Base | Odoo Model | Use Case |
|---|---|---|
| Content calendar | project.task | Marketing team plans in Airtable, tasks sync to Odoo for billing |
| Product catalog | product.template | Product team manages specs in Airtable, syncs to Odoo for sales |
| Lead tracker | crm.lead | SDR team qualifies in Airtable, leads sync to Odoo CRM |
| Vendor database | res.partner | Procurement manages vendors in Airtable, syncs to Odoo purchasing |
| Event registrations | event.registration | Event signups in Airtable flow to Odoo event management |
Integration Methods
Zapier / Make (Easiest)
Both platforms have native Airtable and Odoo connectors. Set up triggers on Airtable record creation or update, then create or update corresponding Odoo records. Best for low-volume, one-directional sync.
Airtable Webhooks + Custom Script
Airtable's webhook automations can send HTTP requests to an Odoo endpoint when records change. This provides near-real-time sync without middleware costs.
Airtable API + Odoo Scheduled Action
Poll Airtable's REST API from an Odoo scheduled action. Fetch changed records and sync them. This approach gives you full control and works well for bidirectional sync.
Step 1: Get Airtable API Access
- Go to airtable.com/create/tokens
- Create a Personal Access Token
- Select scopes:
data.records:read,data.records:write - Select the bases you want to sync
- Copy the token
Step 2: Fetch Airtable Records
import requests
AIRTABLE_TOKEN = 'patXXXXXX'
BASE_ID = 'appXXXXXX'
TABLE_NAME = 'Products'
def fetch_airtable_records():
records = []
offset = None
while True:
params = {}
if offset:
params['offset'] = offset
resp = requests.get(
f'https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}',
headers={'Authorization': f'Bearer {AIRTABLE_TOKEN}'},
params=params
)
data = resp.json()
records.extend(data['records'])
offset = data.get('offset')
if not offset:
break
return recordsStep 3: Push to Odoo
import xmlrpc.client
models = xmlrpc.client.ServerProxy(f'{ODOO_URL}/xmlrpc/2/object')
for record in fetch_airtable_records():
fields = record['fields']
airtable_id = record['id']
existing = models.execute_kw(db, uid, key, 'product.template', 'search',
[[('x_airtable_id', '=', airtable_id)]])
vals = {
'name': fields.get('Product Name'),
'list_price': fields.get('Price', 0),
'description_sale': fields.get('Description', ''),
'x_airtable_id': airtable_id,
}
if existing:
models.execute_kw(db, uid, key, 'product.template', 'write',
[existing, vals])
else:
models.execute_kw(db, uid, key, 'product.template', 'create', [vals])Step 4: Reverse Sync (Odoo to Airtable)
def push_to_airtable(odoo_record):
# Check if record exists in Airtable
if odoo_record.get('x_airtable_id'):
requests.patch(
f'https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}/{odoo_record["x_airtable_id"]}',
headers={'Authorization': f'Bearer {AIRTABLE_TOKEN}'},
json={'fields': {
'Stock Qty': odoo_record['qty_available'],
'Last Sale': odoo_record['last_sale_date'],
}}
)
else:
resp = requests.post(
f'https://api.airtable.com/v0/{BASE_ID}/{TABLE_NAME}',
headers={'Authorization': f'Bearer {AIRTABLE_TOKEN}'},
json={'fields': {
'Product Name': odoo_record['name'],
'Price': odoo_record['list_price'],
}}
)
# Store Airtable ID back in Odoo
return resp.json()['id']Handling Conflicts
Bidirectional sync introduces conflict risk when both systems are edited simultaneously. Best practices:
- Designate one system as the source of truth per field (e.g., price in Odoo, description in Airtable)
- Use last-modified timestamps to determine which change wins
- Log conflicts for manual review rather than silently overwriting
- Add a sync status field in both systems for visibility
Airtable Rate Limits
Airtable allows 5 requests per second per base. For large syncs, implement batching (up to 10 records per request for creates/updates) and respect rate limits with exponential backoff. A full sync of 1,000 records takes approximately 3-4 minutes.
DeployMonkey + Airtable
DeployMonkey instances support the XML-RPC and JSON-RPC APIs needed for Airtable sync scripts. Our AI agent can help design your field mapping and set up the scheduled sync action in Odoo.