Airtable URLs encode base, table, view, and record identifiers. Understanding these patterns enables deep linking and API integration.
Key Takeaways
- 1Base IDs start with "app", table IDs with "tbl", record IDs with "rec"
- 2View IDs start with "viw" and determine display settings
- 3API base URL is api.airtable.com/v0/{baseId}
- 4Shared views have separate URLs from the main base
- 5Webhooks require enterprise plan or Airtable automation
“The Airtable API allows you to create, read, update, and delete records. Each request is scoped to a single base.”
Airtable ID Prefixes
Airtable uses distinctive three-letter prefixes to identify different resource types. Recognizing these prefixes helps you quickly understand what a URL or API response references without additional context.
| Prefix | Type | Example |
|---|---|---|
| app | Base | appABC123XYZ |
| tbl | Table | tblDEF456ABC |
| viw | View | viwGHI789DEF |
| rec | Record | recJKL012GHI |
| fld | Field | fldMNO345JKL |
| att | Attachment | attPQR678MNO |
Each ID combines the type prefix with a random alphanumeric string. When parsing URLs or debugging API responses, checking the prefix immediately tells you whether you are dealing with a base, table, record, or other resource type.
Airtable URLs follow a hierarchical structure from base to table to view to record. Each level adds specificity, and you can construct deep links to any resource in your Airtable workspace.
URL Structure
# Airtable URL patterns
# Base view
https://airtable.com/{baseId}
# Table view
https://airtable.com/{baseId}/{tableIdOrName}
# Specific view
https://airtable.com/{baseId}/{tableIdOrName}/{viewId}
# Record detail (modal)
https://airtable.com/{baseId}/{tableIdOrName}/{viewId}/{recordId}
# Examples
https://airtable.com/appABC123XYZ
https://airtable.com/appABC123XYZ/tblDEF456ABC
https://airtable.com/appABC123XYZ/tblDEF456ABC/viwGHI789DEF
https://airtable.com/appABC123XYZ/tblDEF456ABC/viwGHI789DEF/recJKL012GHI
# Alternative URL format (with table name)
https://airtable.com/appABC123XYZ/Tasks/Grid%20view/recJKL012GHIThe URL can use either IDs or names for tables and views. When using names, spaces and special characters must be URL-encoded. IDs are preferred for programmatic use since they remain stable even when tables or views are renamed.
Shared views provide read-only access to Airtable data without requiring users to have Airtable accounts. These URLs are commonly used for public dashboards, embedded content, and data collection forms.
Shared & Embedded Views
# Shared view URL (read-only, no login required)
https://airtable.com/shr{shareId}
# Example
https://airtable.com/shrABC123XYZ456DEF
# Shared form URL
https://airtable.com/shr{formId}
# Embedded view (iframe-friendly)
https://airtable.com/embed/shr{shareId}
# With specific record highlighted
https://airtable.com/embed/shr{shareId}?backgroundColor=blue&viewControls=on
# Embed parameters
?backgroundColor=purple|green|blue|red|orange|cyan|pink|yellow
&viewControls=on # Show view controls
&layout=card # Card layout
# Prefilled form URL
https://airtable.com/shr{formId}?prefill_Name=John&prefill_Email=john@example.comShare URLs use the shr prefix followed by a unique identifier. The embed URL variant is optimized for iframe display with optional styling parameters. Prefilled form fields use query parameters matching your field names, making it easy to pre-populate data from external systems.
The Airtable API provides full CRUD access to your bases and tables. Each API call is scoped to a single base, which means the base ID appears in every endpoint URL.
API Endpoints
// Airtable API base URL
const baseUrl = 'https://api.airtable.com/v0';
// Common endpoints
// GET /v0/{baseId}/{tableIdOrName} - List records
// POST /v0/{baseId}/{tableIdOrName} - Create record(s)
// PATCH /v0/{baseId}/{tableIdOrName} - Update record(s)
// DELETE /v0/{baseId}/{tableIdOrName} - Delete records
// GET /v0/{baseId}/{tableIdOrName}/{recordId} - Get single record
// List records with filters
const url = new URL(`${baseUrl}/${baseId}/${tableId}`);
url.searchParams.set('maxRecords', '100');
url.searchParams.set('view', 'Grid view');
url.searchParams.set('filterByFormula', 'AND({Status}="Active",{Priority}="High")');
url.searchParams.set('sort[0][field]', 'Created');
url.searchParams.set('sort[0][direction]', 'desc');
const response = await fetch(url.toString(), {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
const { records, offset } = await response.json();
// Pagination
if (offset) {
url.searchParams.set('offset', offset);
// Fetch next page
}The API uses formula syntax for filtering, which is the same formula language available in Airtable's UI. Pagination uses offset tokens rather than page numbers. When more records exist, the response includes an offset value to pass in your next request.
Building API URLs with the right parameters is crucial for efficient queries. The following function demonstrates how to construct URLs with filtering, sorting, and field selection options.
API Query Parameters
// Build Airtable API URL with parameters
function buildAirtableUrl(baseId, tableId, options = {}) {
const url = new URL(`https://api.airtable.com/v0/${baseId}/${tableId}`);
// Pagination
if (options.maxRecords) {
url.searchParams.set('maxRecords', options.maxRecords);
}
if (options.pageSize) {
url.searchParams.set('pageSize', options.pageSize);
}
if (options.offset) {
url.searchParams.set('offset', options.offset);
}
// View
if (options.view) {
url.searchParams.set('view', options.view);
}
// Fields to return
if (options.fields) {
options.fields.forEach((field, i) => {
url.searchParams.set(`fields[${i}]`, field);
});
}
// Filter formula
if (options.filterByFormula) {
url.searchParams.set('filterByFormula', options.filterByFormula);
}
// Sorting
if (options.sort) {
options.sort.forEach((sort, i) => {
url.searchParams.set(`sort[${i}][field]`, sort.field);
url.searchParams.set(`sort[${i}][direction]`, sort.direction || 'asc');
});
}
return url.toString();
}
// Usage
const url = buildAirtableUrl('appABC123', 'Tasks', {
view: 'Active Tasks',
fields: ['Name', 'Status', 'Due Date'],
filterByFormula: '{Status}!="Done"',
sort: [{ field: 'Due Date', direction: 'asc' }],
pageSize: 50
});The fields parameter is an array, so each field name needs its own indexed parameter. Sort configuration similarly uses indexed parameters for field and direction. The filterByFormula parameter accepts Airtable formula expressions for complex filtering logic.
When integrating with Airtable, you often need to parse URLs to extract resource IDs for API calls. The following utilities handle both regular base URLs and shared view URLs.
Extracting IDs from URLs
// Extract Airtable IDs from URLs
function parseAirtableUrl(url) {
const urlObj = new URL(url);
const pathname = urlObj.pathname;
const segments = pathname.split('/').filter(Boolean);
const result = {
baseId: null,
tableId: null,
viewId: null,
recordId: null,
shareId: null
};
// Shared view URL
if (segments[0]?.startsWith('shr')) {
result.shareId = segments[0];
return result;
}
// Regular URL
segments.forEach(segment => {
if (segment.startsWith('app')) result.baseId = segment;
else if (segment.startsWith('tbl')) result.tableId = segment;
else if (segment.startsWith('viw')) result.viewId = segment;
else if (segment.startsWith('rec')) result.recordId = segment;
});
return result;
}
// Build record URL
function buildRecordUrl(baseId, tableId, viewId, recordId) {
return `https://airtable.com/${baseId}/${tableId}/${viewId}/${recordId}`;
}
// Usage
const ids = parseAirtableUrl(
'https://airtable.com/appABC123/tblDEF456/viwGHI789/recJKL012'
);
console.log(ids);
// { baseId: 'appABC123', tableId: 'tblDEF456', viewId: 'viwGHI789', recordId: 'recJKL012' }The parser identifies IDs by their prefixes, making it robust against different URL formats. Shared URLs are detected first since they have a different structure. The buildRecordUrl function constructs deep links to specific records when you have all the component IDs.
Airtable webhooks notify your application when records change. While webhooks require higher-tier plans, you can also use Airtable Automations to send data to external URLs as a more accessible alternative.
Webhook URLs
// Airtable webhooks (Enterprise/Business plan)
// Using the Webhooks API
// Create webhook
const webhook = await fetch('https://api.airtable.com/v0/bases/{baseId}/webhooks', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
notificationUrl: 'https://yourapp.com/webhooks/airtable',
specification: {
options: {
filters: {
dataTypes: ['tableData'],
recordChangeScope: 'tbl{tableId}'
}
}
}
})
});
// Your webhook handler
app.post('/webhooks/airtable', (req, res) => {
const { base, webhook, timestamp, payloads } = req.body;
payloads.forEach(payload => {
const { changedTablesById } = payload;
// Process changes
});
res.sendStatus(200);
});
// Alternative: Airtable Automations send to custom URL
// In Airtable: Automations > Create > Trigger > When record matches conditions
// Action > Send request to custom URLThe Webhooks API lets you subscribe to changes with filters for specific tables or data types. Your notification URL receives batched updates with details about changed records. For users without webhook access, Airtable Automations provide similar functionality through a visual builder that can send custom HTTP requests.