🗄️ Airtable API
Typ: REST API
Auth: API Key / OAuth 2.0
Status: ✅ Marktführer
Übersicht
Airtable als flexible Datenbank für: - Mieterverwaltung - Objektdaten - Wartungshistorie - CRM-Funktionen
API Endpoints
| Methode | Endpunkt | Beschreibung | Cache TTL |
|---|---|---|---|
GET |
/api/airtable/bases |
Alle Bases | 1h |
GET |
/api/airtable/bases/:id/tables |
Tabellen einer Base | 30min |
GET |
/api/airtable/:baseId/:tableId |
Records abrufen | 1min |
GET |
/api/airtable/:baseId/:tableId/:recordId |
Einzelner Record | 1min |
POST |
/api/airtable/:baseId/:tableId |
Record erstellen | - |
PATCH |
/api/airtable/:baseId/:tableId/:recordId |
Record aktualisieren | - |
DELETE |
/api/airtable/:baseId/:tableId/:recordId |
Record löschen | - |
GET |
/api/airtable/:baseId/:tableId/search |
Suche/Filter | 1min |
Airtable API Beispiel
const AIRTABLE_API = 'https://api.airtable.com/v0';
interface AirtableRecord<T> {
id: string;
createdTime: string;
fields: T;
}
interface Tenant {
Name: string;
Email: string;
Unit: string[];
RentAmount: number;
ContractStart: string;
ContractEnd?: string;
Status: 'Active' | 'Terminated' | 'Pending';
}
async function getTenants(baseId: string, tableId: string): Promise<AirtableRecord<Tenant>[]> {
const response = await fetch(
`${AIRTABLE_API}/${baseId}/${tableId}?filterByFormula={Status}='Active'`,
{
headers: {
'Authorization': `Bearer ${process.env.AIRTABLE_API_KEY}`,
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
return data.records;
}
async function createTenant(baseId: string, tableId: string, tenant: Partial<Tenant>) {
const response = await fetch(`${AIRTABLE_API}/${baseId}/${tableId}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.AIRTABLE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fields: tenant
})
});
return response.json();
}
async function updateTenant(baseId: string, tableId: string, recordId: string, updates: Partial<Tenant>) {
const response = await fetch(`${AIRTABLE_API}/${baseId}/${tableId}/${recordId}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.AIRTABLE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fields: updates
})
});
return response.json();
}
Filter & Sortierung
// Airtable Formula Syntax
const filters = {
// Aktive Mieter
active: "filterByFormula={Status}='Active'",
// Miete > 1000€
highRent: "filterByFormula={RentAmount}>1000",
// Verträge die bald enden (30 Tage)
expiring: "filterByFormula=AND({ContractEnd}!='',{ContractEnd}<=DATEADD(TODAY(),30,'days'))",
// Suche nach Name
byName: (name: string) => `filterByFormula=FIND('${name}',{Name})>0`,
// Sortierung
sort: "sort[0][field]=RentAmount&sort[0][direction]=desc"
};
Webhook für Änderungen
// Airtable Webhook (via Automation)
app.post('/webhooks/airtable', async (req, res) => {
const { base, table, record, action } = req.body;
switch (action) {
case 'create':
await syncNewTenant(record);
break;
case 'update':
await updateLocalCache(record);
break;
case 'delete':
await removeFromCache(record.id);
break;
}
res.sendStatus(200);
});
Umgebungsvariablen
# Airtable
AIRTABLE_API_KEY="pat..."
AIRTABLE_BASE_ID="app..."
# Table IDs
AIRTABLE_TENANTS_TABLE="tbl..."
AIRTABLE_PROPERTIES_TABLE="tbl..."
AIRTABLE_CONTRACTS_TABLE="tbl..."
Rate Limits
| Plan | Limit |
|---|---|
| Free | 5 req/sec |
| Pro | 5 req/sec |
| Enterprise | 50 req/sec |
Marktführer • Flexible Schema • 5 req/sec