# Table

> Part of the NocoDB documentation (Workflows > Scripts > API Reference). Index of all pages: https://nocodb.com/llms.txt. Any docs page is available as Markdown by adding `.md` to its URL.

URL: https://nocodb.com/docs/workflows/scripts/api-reference/table
Last updated: 2026-09-25

Documentation for the Table object in NocoDB Scripts

The `Table` object represents a table in your NocoDB base and provides methods to access, query, and modify records within that table.

## Overview

Table objects are typically accessed through the `base` object and provide the primary way to:

* Query records using various filters and conditions
* Create, update, and delete records
* Access and modify table fields and views
* Perform bulk operations on table data

## Properties

| Property      | Type             | Description                                                        |
| ------------- | ---------------- | ------------------------------------------------------------------ |
| `id`          | `string`         | The unique identifier of the table                                 |
| `name`        | `string`         | The name of the table                                              |
| `description` | `string \| null` | The description of the table (if any)                              |
| `fields`      | `Field[]`        | Array of user-defined fields in the table (excludes system fields) |
| `views`       | `View[]`         | Array of all views defined for the table                           |
| `base`        | `Base`           | Reference to the parent base that this table belongs to            |

## Methods

### getField

Retrieves a field from the table by its ID or name. This method searches both user-defined fields and system fields.

**Parameters:**

* `idOrName` (`string`): The ID or name of the field to retrieve

**Returns:**

* `Field` object if a match is found
* `null` if no field matches the provided input

**Note:** While the `fields` property only includes user-defined fields, `getField()` can access both user fields and system fields (like Created Time, Last Modified Time, etc.)

**Example:**

```javascript
// Get a field by name
const titleField = projectsTable.getField('Title');

// Get a field by ID
const statusField = projectsTable.getField('c12345');

// Check if a field exists
if (titleField) {
  output.text(`Field "${titleField.name}" found with type: ${titleField.type}`);
} else {
  output.text('Field not found.');
}
```

### getView

Retrieves a view from the table by its ID or name.

**Parameters:**

* `idOrName` (`string`): The ID or name of the view to retrieve

**Returns:**

* `View` object if a match is found
* `null` if no view matches the provided input

**Example:**

```javascript
// Get a view by name
const activeProjectsView = projectsTable.getView('Active Projects');

// Get a view by ID
const completedTasksView = projectsTable.getView('viw12345');

// Check if a view exists
if (activeProjectsView) {
  output.text(`View "${activeProjectsView.name}" found with type: ${activeProjectsView.type}`);
} else {
  output.text('View not found.');
}
```

### selectRecordsAsync

Queries records from the table with optional filtering and sorting.

**Parameters:**

* `options` (optional): Object with the following properties:
  * `fields` (`Array<Field | string>`): Specific fields to include in the result. If not specified, all fields are included.
  * `sorts` (`Array<{field: Field | string, direction: 'asc' | 'desc'}>`): Sorting options
  * `recordIds` (`Array<string>`): Specific record IDs to retrieve
  * `pageSize` (`number`): Maximum number of records to return per page (default: 50)
  * `page` (`number`): Page number for pagination (default: 1)
  * `where` (`string`): Where filter condition.

**Returns:** `Promise<RecordQueryResult>` - A promise that resolves to a RecordQueryResult object with pagination support

**Example:**

```javascript
// Query records with options
const queryResult = await tasksTable.selectRecordsAsync({
  fields: ['Task Name', 'Status', 'Due Date'],
  sorts: [
    {field: 'Due Date', direction: 'asc'},
    {field: 'Status', direction: 'desc'}
  ],
  pageSize: 100
});

output.text(`Retrieved ${queryResult.records.length} records.`);

// Process the records
for (const record of queryResult.records) {
  const taskName = record.getCellValue('Task Name');
  const status = record.getCellValue('Status');
  output.text(`- ${taskName}: ${status}`);
}

// Check if there are more records
if (queryResult.hasMoreRecords) {
  // Load the next page of records
  const nextPage = await queryResult.loadMoreRecords();
  output.text(`Loaded ${nextPage.records.length} more records.`);
}
```

### selectRecordAsync

Retrieves a single record from the table by its ID.

**Parameters:**

* `recordId` (`string`): The ID of the record to retrieve
* `options` (optional): Object with the following properties:
  * `fields` (`Array<Field | string>`): Specific fields to include in the result

**Returns:** `Promise<Record | null>` - A promise that resolves to the Record object if a match is found

**Example:**

```javascript
// Get a specific record by ID
const recordId = '123';
const record = await contactsTable.selectRecordAsync(recordId, {
  fields: ['Name', 'Email', 'Phone']
});

if (record) {
  output.text(`Contact: ${record.getCellValue('Name')}`);
  output.text(`Email: ${record.getCellValue('Email')}`);
  output.text(`Phone: ${record.getCellValue('Phone')}`);
} else {
  output.text(`Record with ID ${recordId} not found.`);
}
```

### createRecordAsync

Creates a new record in the table with the specified field values.

**Parameters:**

* `data` (`Object`): Object mapping field names or IDs to their values.

**Returns:** `Promise<string>` - A promise that resolves to the ID of the created record

**Example:**

```javascript
// Create a new record
const newRecordId = await contactsTable.createRecordAsync({
  'Name': 'John Doe',
  'Email': 'john.doe@example.com',
  'Phone': '(555) 123-4567',
  'Status': 'Active'
});

output.text(`New record created with ID: ${newRecordId}`);

// Create a record with field IDs
const newRecordId2 = await contactsTable.createRecordAsync({
  'c123456': 'Jane Smith',  // Name field
  'c456789': 'jane@example.com'  // Email field
});
```

### createRecordsAsync

Creates multiple records in the table.

**Parameters:**

* `data` (`Array<{fields: Object}>`): Array of objects, each with a `fields` property mapping field names or IDs to their values.

**Note:** Unlike [createRecordAsync](#createrecordasync), which takes a flat object, each entry here must wrap its values in `fields`. Values placed outside `fields` are ignored, which creates blank records.

**Limit:** You may create up to 10 records in one call.

**Returns:** `Promise<Array<string>>` - A promise that resolves to an array of IDs of the created records

**Example:**

```javascript
// Create multiple records at once
const newRecordIds = await contactsTable.createRecordsAsync([
  { fields: {
    'Name': 'John Doe',
    'Email': 'john.doe@example.com',
    'Status': 'Active'
  }},
  { fields: {
    'Name': 'Jane Smith',
    'Email': 'jane.smith@example.com',
    'Status': 'Pending'
  }},
  { fields: {
    'Name': 'Bob Johnson',
    'Email': 'bob.johnson@example.com',
    'Status': 'Active'
  }}
]);

output.text(`Created ${newRecordIds.length} new records.`);
```

### updateRecordAsync

Updates a record with the specified field values.

**Parameters:**

* `recordId` (`string | NocoDBRecord`): The ID of the record to update or a NocoDBRecord object
* `data` (`Object`): Object mapping field names or IDs to their new values.

**Returns:** `Promise<void>` - A promise that resolves when the update is complete

**Example:**

```javascript
// Update a record by ID
await contactsTable.updateRecordAsync('123', {
  'Status': 'Inactive',
  'Last Contact Date': new Date().toISOString()
});

// Update a record using a Record object
const record = await contactsTable.selectRecordAsync('123');
if (record) {
  await contactsTable.updateRecordAsync(record, {
    'Notes': 'Customer requested follow-up next quarter.'
  });
  output.text('Record updated successfully.');
}
```

### updateRecordsAsync

Updates multiple records with the specified field values.

**Parameters:**

* `records` (`Array<{id: string | NocoDBRecord, fields: Object}>`): Array of objects with record IDs (or NocoDBRecord objects) and field values to update.

**Limit:** You may update up to 10 records in one call.

**Returns:** `Promise<void>` - A promise that resolves when all updates are complete

**Example:**

```javascript
// Update multiple records at once
await contactsTable.updateRecordsAsync([
  {
    id: '123',
    fields: {
      'Status': 'Active',
      'Last Contact Date': new Date().toISOString()
    }
  },
  {
    id: 'rec67890',
    fields: {
      'Status': 'Inactive',
      'Notes': 'Customer no longer interested.'
    }
  }
]);

output.text('Records updated successfully.');
```

### deleteRecordAsync

Deletes a record from the table.

**Parameters:**

* `recordIdOrRecord` (`string | NocoDBRecord`): The ID of the record to delete or a NocoDBRecord object

**Returns:** `Promise<boolean>` - A promise that resolves to `true` when the deletion is complete

**Example:**

```javascript
// Delete a record by ID
await tasksTable.deleteRecordAsync('123');
output.text('Record deleted successfully.');

// Delete a record using a Record object
const record = await tasksTable.selectRecordAsync('678');
if (record) {
  await tasksTable.deleteRecordAsync(record);
  output.text(`Record "${record.name}" deleted successfully.`);
}
```

### deleteRecordsAsync

Deletes multiple records from the table.

**Parameters:**

* `recordIds` (`Array<string>`): Array of record IDs to delete

**Limit:** You may delete up to 10 records in one call.

**Returns:** `Promise<boolean>` - A promise that resolves to `true` when all deletions are complete

**Example:**

```javascript
// Delete multiple records by ID
await tasksTable.deleteRecordsAsync(['123', '678', '246']);
output.text('Records deleted successfully.');

// Delete records using a query result
const completedTasks = await tasksTable.selectRecordsAsync({
  fields: ['Status'],
  where: '(Status, eq, Completed)',
});

const recordsToDelete = completedTasks.records.map(record => record.id);

// deleteRecordsAsync accepts at most 10 records per call
for (let i = 0; i < recordsToDelete.length; i += 10) {
  await tasksTable.deleteRecordsAsync(recordsToDelete.slice(i, i + 10));
}
output.text(`Deleted ${recordsToDelete.length} completed tasks.`);
```

### createFieldAsync

Creates a new field in the table with the specified configuration.

**Parameters:**

* `field` (`Object`): Field configuration object with:
  * `name` (`string`): Name for the new field
  * `type` (`UITypes`): Type of field to create
  * `description` (`string`, optional): Description for the field
  * `options` (`Object`, optional): Type-specific options for the field

**Returns:** `Promise<Field>` - A promise that resolves to the created Field object

**Example:**

```javascript
// Create a new field
const ratingField = await projectsTable.createFieldAsync({
  name: 'Priority',
  type: UITypes.Rating,
  description: 'Project priority from 1-5',
  options: {
    icon: 'star',
    max_value: 5,
    color: '#FFCC00'
  }
});

output.text(`Created new field: ${ratingField.name}`);

// Create a select field
const statusField = await tasksTable.createFieldAsync({
  name: 'Status',
  type: UITypes.SingleSelect,
  options: {
    choices: [
      { title: 'Not Started', color: '#808080' },
      { title: 'In Progress', color: '#3366FF' },
      { title: 'Review', color: '#FF9900' },
      { title: 'Completed', color: '#33CC33' }
    ]
  }
});
```

## Examples

### Querying and Filtering Records

```javascript
// Get the "Tasks" table
const tasksTable = base.getTable('Tasks');

// Get all tasks
const allTasks = await tasksTable.selectRecordsAsync();
output.text(`Total tasks: ${allTasks.records.length}`);

// Use a view to get filtered records
const inProgressView = tasksTable.getView('In Progress Tasks');
if (inProgressView) {
  const inProgressTasks = await inProgressView.selectRecordsAsync();
  output.text(`In-progress tasks: ${inProgressTasks.records.length}`);
}

// Get specific fields and sort by due date
const upcomingTasks = await tasksTable.selectRecordsAsync({
  fields: ['Task Name', 'Due Date', 'Status', 'Assigned To'],
  sorts: [
    { field: 'Due Date', direction: 'asc' }
  ],
  pageSize: 10
});

// Display the upcoming tasks
output.markdown('# Upcoming Tasks');
for (const task of upcomingTasks.records) {
  const name = task.getCellValue('Task Name');
  const dueDate = task.getCellValue('Due Date');
  const status = task.getCellValue('Status');
  const assignee = task.getCellValue('Assigned To');
  
  const assigneeName = assignee ? assignee.name : 'Unassigned';
  
  output.text(`- ${name} (${status}) due on ${dueDate} - Assigned to: ${assigneeName}`);
}
```

### Creating and Updating Records

```javascript
// Get the "Projects" table
const projectsTable = base.getTable('Projects');

// Create a new project
const newProjectId = await projectsTable.createRecordAsync({
  'Project Name': 'Website Redesign',
  'Start Date': new Date().toISOString(),
  'Status': 'Planning',
  'Budget': 15000,
  'Description': 'Complete overhaul of company website.'
});

output.text(`Created new project with ID: ${newProjectId}`);

// Retrieve the created project
const newProject = await projectsTable.selectRecordAsync(newProjectId);
if (newProject) {
  output.text(`New project: ${newProject.getCellValue('Project Name')}`);
  
  // Update the project after creation
  await projectsTable.updateRecordAsync(newProjectId, {
    'Project Lead': session.currentUser.id,
    'Team Size': 5
  });
  
  output.text('Project updated with lead and team size.');
}

// Create multiple tasks for the project
const tasksTable = base.getTable('Tasks');
const tasks = [
  { fields: {
    'Task Name': 'Requirements Gathering',
    'Project': newProjectId,
    'Status': 'Not Started',
    'Due Date': new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()
  }},
  { fields: {
    'Task Name': 'Wireframes',
    'Project': newProjectId,
    'Status': 'Not Started',
    'Due Date': new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toISOString()
  }},
  { fields: {
    'Task Name': 'Design Mockups',
    'Project': newProjectId,
    'Status': 'Not Started',
    'Due Date': new Date(Date.now() + 21 * 24 * 60 * 60 * 1000).toISOString()
  }}
];

const taskIds = await tasksTable.createRecordsAsync(tasks);
output.text(`Created ${taskIds.length} tasks for the project.`);
```

### Bulk Processing with Pagination

```javascript
// Get the "Contacts" table
const contactsTable = base.getTable('Contacts');

// Function to process all records with pagination
async function processAllRecords() {
  let queryResult = await contactsTable.selectRecordsAsync({
    fields: ['Name', 'Email', 'Last Contact Date'],
    pageSize: 100 // Process in batches of 100
  });
  
  let processedCount = 0;
  let updatedCount = 0;

  while (queryResult.hasMoreRecords) {
    await queryResult.loadMoreRecords();
  }
  
  // Process first batch
  let recordsToUpdate = [];
  for (const record of queryResult.records) {
    processedCount++;
    
    const lastContactDate = record.getCellValue('Last Contact Date');
    // If no contact in the last 90 days, mark for update
    if (!lastContactDate || new Date(lastContactDate) < new Date(Date.now() - 90 * 24 * 60 * 60 * 1000)) {
      recordsToUpdate.push({
        id: record.id,
        fields: {
          'Status': 'Needs Follow-up',
          'Notes': 'No contact in the last 90 days.'
        }
      });
    }
  }
  
  // updateRecordsAsync accepts at most 10 records per call, so send in chunks
  for (let i = 0; i < recordsToUpdate.length; i += 10) {
    const chunk = recordsToUpdate.slice(i, i + 10);
    await contactsTable.updateRecordsAsync(chunk);
    updatedCount += chunk.length;
  }
  
  output.text(`Processing complete! Processed ${processedCount} total records, updated ${updatedCount}.`);
}

// Run the process
await processAllRecords();
```

## Best Practices

1. **Batch operations** - When creating or updating many records, use the bulk methods (`createRecordsAsync`, `updateRecordsAsync`) instead of individual calls for better performance. Each call accepts at most 10 records, so split larger sets into chunks of 10.

2. **Paginate large queries** - When working with large tables, use pagination via the `pageSize` option and `loadMoreRecords()` method to avoid memory issues.

3. **Error handling** - Always wrap async operations in try/catch blocks to handle errors gracefully.

4. **Optimize field selection** - Only request the fields you need by using the `fields` option in queries to improve performance.

## Related

* [Base](/docs/workflows/scripts/api-reference/base)
* [Record](/docs/workflows/scripts/api-reference/record)
* [Field](/docs/workflows/scripts/api-reference/field)
* [View](/docs/workflows/scripts/api-reference/view)

---

## Related pages

- [Base](https://nocodb.com/docs/workflows/scripts/api-reference/base.md): Documentation for the base object in NocoDB Scripts
- [Cursor](https://nocodb.com/docs/workflows/scripts/api-reference/cursor.md): Documentation for the Cursor object in NocoDB Scripts
- [View](https://nocodb.com/docs/workflows/scripts/api-reference/view.md): Documentation for the View object in NocoDB Scripts
- [Field](https://nocodb.com/docs/workflows/scripts/api-reference/field.md): Documentation for the Field object and Field Types in NocoDB Scripts
- [RecordQueryResult](https://nocodb.com/docs/workflows/scripts/api-reference/record-query-result.md): Documentation for the RecordQueryResult object in NocoDB Scripts
- [Record](https://nocodb.com/docs/workflows/scripts/api-reference/record.md): Documentation for the NocoDBRecord object in NocoDB Scripts
- [Session](https://nocodb.com/docs/workflows/scripts/api-reference/session.md): Documentation for the Session object in NocoDB Scripts
- [Collaborator](https://nocodb.com/docs/workflows/scripts/api-reference/collaborator.md): Documentation for the Collaborator object in NocoDB Scripts
