Skip to content

Timestamp overrides

When creating or updating rows, Appwrite automatically sets $createdAt and $updatedAt timestamps. However, there are scenarios where you might need to set these timestamps manually, such as when migrating data from another system or backfilling historical records.

Server SDKs required

To manually set $createdAt and $updatedAt, you must use a server SDK with an API key. These columns can be passed inside the data parameter on any of the create, update, or upsert routes (single or bulk).

Setting custom timestamps

You can override a row's timestamps by providing ISO 8601 strings (for example, 2025-08-10T12:34:56.000Z) in the data payload. If these columns are not provided, Appwrite will set them automatically.

Custom timestamps work with all row operations: create, update, upsert, and their bulk variants.

Single row operations

When working with individual rows, you can set custom timestamps during create, update, and upsert operations.

Create with custom timestamps

const sdk = require('node-appwrite');

const client = new sdk.Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<API_KEY>');

const tablesDB = new sdk.TablesDB(client);

await tablesDB.createRow({
    databaseId: '<DATABASE_ID>',
    tableId: '<TABLE_ID>',
    rowId: sdk.ID.unique(),
    data: {
        '$createdAt': new Date('2025-08-10T12:34:56.000Z').toISOString(),
        '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(),
        // ...your columns
    }
});

Update with custom timestamps

When updating rows, you can also set a custom $updatedAt timestamp:

await tablesDB.updateRow({
    databaseId: '<DATABASE_ID>',
    tableId: '<TABLE_ID>',
    rowId: '<ROW_ID>',
    data: {
        '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(),
        // ...your columns
    }
});

Bulk operations

Custom timestamps also work with bulk operations, allowing you to set different timestamps for each row in the batch:

Bulk create

await tablesDB.createRows({
    databaseId: '<DATABASE_ID>',
    tableId: '<TABLE_ID>',
    rows: [
        {
            '$id': sdk.ID.unique(),
            '$createdAt': new Date('2024-01-01T00:00:00.000Z').toISOString(),
            '$updatedAt': new Date('2024-01-01T00:00:00.000Z').toISOString(),
            // ...your columns
        },
        {
            '$id': sdk.ID.unique(),
            '$createdAt': new Date('2024-02-01T00:00:00.000Z').toISOString(),
            '$updatedAt': new Date('2024-02-01T00:00:00.000Z').toISOString(),
            // ...your columns
        }
    ]
});

Bulk upsert

await tablesDB.upsertRows({
    databaseId: '<DATABASE_ID>',
    tableId: '<TABLE_ID>',
    rows: [
        {
            '$id': '<ROW_ID_OR_NEW_ID>',
            '$createdAt': new Date('2024-01-01T00:00:00.000Z').toISOString(),
            '$updatedAt': new Date('2025-01-01T00:00:00.000Z').toISOString(),
            // ...your columns
        }
    ]
});

Common use cases

Custom timestamps are particularly useful in several scenarios:

Data migration

When migrating existing data from another system, you can preserve the original creation and modification times:

await tablesDB.createRow({
    databaseId: '<DATABASE_ID>',
    tableId: 'blog_posts',
    rowId: sdk.ID.unique(),
    data: {
    '$createdAt': '<ORIGINAL_CREATED_AT_ISO>',
    '$updatedAt': '<LAST_MODIFIED_ISO>',
    title: '<TITLE>',
    content: '<CONTENT>'
  }
})

Backdating records

For historical data entry or when creating records that represent past events:

await tablesDB.createRow({
    databaseId: '<DATABASE_ID>',
    tableId: 'transactions',
    rowId: sdk.ID.unique(),
    data: {
    '$createdAt': '2023-12-31T23:59:59.000Z',
    '$updatedAt': '2023-12-31T23:59:59.000Z',
    amount: 1000,
    type: 'year-end-bonus'
  }
})

Synchronization

When synchronizing data between systems while maintaining timestamp consistency:

await tablesDB.upsertRow({
    databaseId: '<DATABASE_ID>',
    tableId: 'users',
    rowId: '<ROW_ID_OR_NEW_ID>',
    data: {
    '$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>',
    profile: '<PROFILE_DATA>'
  }
})
Timestamp format and usage
  • Values must be valid ISO 8601 date-time strings (UTC recommended). Using toISOString() (JavaScript) or datetime.isoformat() (Python) is a good default.
  • You can set either or both columns as needed. If omitted, Appwrite sets them automatically.