diff --git a/src/routes/docs/products/databases/+layout.svelte b/src/routes/docs/products/databases/+layout.svelte index 4c1adcdaa5..1f29abca44 100644 --- a/src/routes/docs/products/databases/+layout.svelte +++ b/src/routes/docs/products/databases/+layout.svelte @@ -95,6 +95,10 @@ label: 'CSV imports', href: '/docs/products/databases/csv-imports', new: isNewUntil('31 Jul 2025') + }, + { + label: 'Timestamp overrides', + href: '/docs/products/databases/timestamp-overrides' } ] }, diff --git a/src/routes/docs/products/databases/legacy/documents/+page.markdoc b/src/routes/docs/products/databases/legacy/documents/+page.markdoc index 6dfb33fcd4..25d856cfa8 100644 --- a/src/routes/docs/products/databases/legacy/documents/+page.markdoc +++ b/src/routes/docs/products/databases/legacy/documents/+page.markdoc @@ -375,273 +375,7 @@ mutation { ``` {% /multicode %} -# Set custom $createdAt and $updatedAt {% #custom-timestamps %} -{% info title="Server SDKs required" %} -To manually set `$createdAt` and `$updatedAt`, you must use a **server SDK** with an **API key**. These attributes can be passed inside the `data` parameter on any of the create, update, or upsert routes (single or bulk). -{% /info %} - -You can override a document's timestamps by providing ISO 8601 strings (for example, `2025-08-10T12:34:56.000Z`) in the `data` payload. If these attributes are not provided, Appwrite will set them automatically. - -{% multicode %} -```server-nodejs -const sdk = require('node-appwrite'); - -const client = new sdk.Client() - .setEndpoint('https://.cloud.appwrite.io/v1') - .setProject('') - .setKey(''); - -const databases = new sdk.Databases(client); - -// Single document (create) -await databases.createDocument( - '', - '', - sdk.ID.unique(), - { - '$createdAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), - '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), - // ...your attributes - } -); - -// Single document (update) -await databases.updateDocument( - '', - '', - '', - { - '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), - // ...your attributes - } -); - -// Bulk (create) -await databases.createDocuments( - '', - '', - [ - { - '$id': sdk.ID.unique(), - '$createdAt': new Date('').toISOString(), - '$updatedAt': new Date('').toISOString(), - // ...your attributes - } - ] -); - -// Bulk (upsert) -await databases.upsertDocuments( - '', - '', - [ - { - '$id': '', - '$createdAt': new Date('').toISOString(), - '$updatedAt': new Date('').toISOString(), - // ...your attributes - } - ] -); -``` -```server-php -use Appwrite\Client; -use Appwrite\ID; -use Appwrite\Services\Databases; - -$client = (new Client()) - ->setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint - ->setProject('') // Your project ID - ->setKey(''); // Your secret API key - -$databases = new Databases($client); - -// Single document (create) -$databases->createDocument( - databaseId: '', - collectionId: '', - documentId: '', - [ - '$createdAt' => (new DateTime(''))->format(DATE_ATOM), - '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), - // ...your attributes - ] -); - -// Single document (update) -$databases->updateDocument( - databaseId: '', - collectionId: '', - documentId: '', - [ - '$updatedAt': (new DateTime(''))->format(DATE_ATOM), - // ...your attributes - ] -); -// Bulk (create) -$databases->createDocuments( - databaseId: '', - collectionId: '', - [ - [ - '$id': ID::unique(), - '$createdAt': (new DateTime(''))->format(DATE_ATOM), - '$updatedAt': (new DateTime(''))->format(DATE_ATOM), - // ...your attributes - ] - ] -); - -// Bulk (upsert) -$databases->upsertDocuments( - databaseId: '', - collectionId: '', - documents: [ - [ - '$id' => '', - '$createdAt' => (new DateTime(''))->format(DATE_ATOM), - '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), - // ...your attributes - ], - ], -); -``` -```server-swift -import Appwrite -import Foundation - -// MARK: - Client setup -let client = Client() - .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint - .setProject("") // Your project ID - .setKey("") // Your secret API key - -let databases = Databases(client) - -let isoFormatter = ISO8601DateFormatter() -isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] -let customDate = isoFormatter.date(from: "") ?? Date() -let createdAt = isoFormatter.string(from: customDate) -let updatedAt = isoFormatter.string(from: customDate) - -// MARK: - Single document (create) -do { - let created = try await databases.createDocument( - databaseId: "", - collectionId: "", - documentId: "", - data: [ - "$createdAt": createdAt, - "$updatedAt": updatedAt, - // ...your attributes - ] - ) - print("Created:", created) -} catch { - print("Create error:", error) -} - -// MARK: - Single document (update) -do { - let updated = try await databases.updateDocument( - databaseId: "", - collectionId: "", - documentId: "", - data: [ - "$updatedAt": updatedAt, - // ...your attributes - ] - ) - print("Updated:", updated) -} catch { - print("Update error:", error) -} - -// MARK: - Bulk (create) -do { - let bulkCreated = try await databases.createDocuments( - databaseId: "", - collectionId: "", - documents: [ - [ - "$id": ID.unique(), - "$createdAt": createdAt, - "$updatedAt": updatedAt, - // ...your attributes - ] - ] - ) - print("Bulk create:", bulkCreated) -} catch { - print("Bulk create error:", error) -} - -// MARK: - Bulk (upsert) -do { - let bulkUpserted = try await databases.upsertDocuments( - databaseId: "", - collectionId: "", - documents: [ - [ - "$id": "", - "$createdAt": createdAt, - "$updatedAt": updatedAt, - // ...your attributes - ] - ] - ) - print("Bulk upsert:", bulkUpserted) -} catch { - print("Bulk upsert error:", error) -} -``` -```server-python -from appwrite.client import Client -from appwrite.services.databases import Databases -from appwrite.id import ID -from datetime import datetime, timezone - -client = Client() -client.set_endpoint('https://.cloud.appwrite.io/v1') -client.set_project('') -client.set_key('') - -databases = Databases(client) - -iso = datetime(2025, 8, 10, 12, 34, 56, tzinfo=timezone.utc).isoformat() - -# Single (create) -databases.create_document( - database_id='', - collection_id='', - document_id=ID.unique(), - data={ - '$createdAt': iso, - '$updatedAt': iso, - # ...your attributes - } -) - -# Bulk (create) -databases.create_documents( - database_id='', - collection_id='', - documents=[{ - '$id': ID.unique(), - '$createdAt': iso, - '$updatedAt': iso, - # ...your attributes - }] -) -``` -{% /multicode %} - -{% info title="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 attributes as needed. If omitted, Appwrite sets them. -- This also works with bulk routes such as `createDocuments` and `upsertDocuments`. See [Bulk operations](#bulk-operations). -{% /info %} # Permissions {% #permissions %} In Appwrite, permissions can be granted at the collection level and the document level. @@ -652,10 +386,26 @@ Users only need to be granted access at either the collection or document level [Learn about configuring permissions](/docs/products/databases/legacy/permissions). -# Bulk operations {% #bulk-operations %} +# Next steps {% #next-steps %} + +Continue learning with these related guides: + +{% cards %} +{% cards_item href="/docs/products/databases/queries" title="Queries" %} +Learn how to filter, sort, and search your documents with various query operators. +{% /cards_item %} + +{% cards_item href="/docs/products/databases/pagination" title="Pagination" %} +Handle large datasets by implementing pagination in your document queries. +{% /cards_item %} -In Appwrite, you can perform bulk operations on documents within a collection. This allows you to create, update, upsert, or delete multiple documents in a single request. +{% cards_item href="/docs/products/databases/bulk-operations" title="Bulk operations" %} +Perform create, update, and delete operations on multiple documents simultaneously. +{% /cards_item %} -As of now, bulk operations can only be performed via the server-side SDKs. The client-side SDKs do not support bulk operations. +{% cards_item href="/docs/products/databases/timestamp-overrides" title="Timestamp overrides" %} +Set custom creation and update timestamps when migrating data or backdating records. +{% /cards_item %} +{% /cards %} -[Learn more about bulk operations](/docs/products/databases/legacy/bulk-operations). \ No newline at end of file +[Learn more about bulk operations](/docs/products/databases/bulk-operations). diff --git a/src/routes/docs/products/databases/timestamp-overrides/+page.markdoc b/src/routes/docs/products/databases/timestamp-overrides/+page.markdoc new file mode 100644 index 0000000000..d8dfd767a4 --- /dev/null +++ b/src/routes/docs/products/databases/timestamp-overrides/+page.markdoc @@ -0,0 +1,1029 @@ +--- +layout: article +title: Timestamp overrides +description: Set custom $createdAt and $updatedAt timestamps for your documents when using server SDKs. +--- + +When creating or updating documents, 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. + +{% info title="Server SDKs required" %} +To manually set `$createdAt` and `$updatedAt`, you must use a **server SDK** with an **API key**. These attributes can be passed inside the `data` parameter on any of the create, update, or upsert routes (single or bulk). +{% /info %} + +# Setting custom timestamps {% #setting-custom-timestamps %} + +You can override a document's timestamps by providing ISO 8601 strings (for example, `2025-08-10T12:34:56.000Z`) in the `data` payload. If these attributes are not provided, Appwrite will set them automatically. + +## Single document operations {% #single-document-operations %} + +### Create with custom timestamps {% #create-custom %} + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const databases = new sdk.Databases(client); + +await databases.createDocument( + '', + '', + sdk.ID.unique(), + { + '$createdAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), + '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), + // ...your attributes + } +); +``` +```server-php +use Appwrite\Client; +use Appwrite\ID; +use Appwrite\Services\Databases; + +$client = (new Client()) + ->setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$databases = new Databases($client); + +$databases->createDocument( + databaseId: '', + collectionId: '', + documentId: '', + [ + '$createdAt' => (new DateTime(''))->format(DATE_ATOM), + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ] +); +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let databases = Databases(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] +let customDate = isoFormatter.date(from: "") ?? Date() +let createdAt = isoFormatter.string(from: customDate) +let updatedAt = isoFormatter.string(from: customDate) + +do { + let created = try await databases.createDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: [ + "$createdAt": createdAt, + "$updatedAt": updatedAt, + // ...your attributes + ] + ) + print("Created:", created) +} catch { + print("Create error:", error) +} +``` +```server-python +from appwrite.client import Client +from appwrite.services.databases import Databases +from appwrite.id import ID +from datetime import datetime, timezone + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +databases = Databases(client) + +iso = datetime(2025, 8, 10, 12, 34, 56, tzinfo=timezone.utc).isoformat() + +databases.create_document( + database_id='', + collection_id='', + document_id=ID.unique(), + data={ + '$createdAt': iso, + '$updatedAt': iso, + # ...your attributes + } +) +``` +require 'appwrite' +require 'time' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +databases = Databases.new(client) + +custom_date = Time.parse('2025-08-10T12:34:56.000Z').iso8601 + +databases.create_document( + database_id: '', + collection_id: '', + document_id: ID.unique(), + data: { + '$createdAt' => custom_date, + '$updatedAt' => custom_date, + # ...your attributes + } +) +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Databases databases = new Databases(client); + +string customDate = DateTimeOffset.Parse("2025-08-10T12:34:56.000Z").ToString("O"); + +await databases.CreateDocument( + databaseId: "", + collectionId: "", + documentId: ID.Unique(), + data: new Dictionary + { + ["$createdAt"] = customDate, + ["$updatedAt"] = customDate, + // ...your attributes + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Databases databases = Databases(client); + +String customDate = DateTime.parse('2025-08-10T12:34:56.000Z').toIso8601String(); + +await databases.createDocument( + databaseId: '', + collectionId: '', + documentId: ID.unique(), + data: { + '\$createdAt': customDate, + '\$updatedAt': customDate, + // ...your attributes + }, +); +``` +{% /multicode %} + +### Update with custom timestamps {% #update-custom %} + +When updating documents, you can also set a custom `$updatedAt` timestamp: + +{% multicode %} +```server-nodejs +await databases.updateDocument( + '', + '', + '', + { + '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), + // ...your attributes + } +); +``` +```server-php +$databases->updateDocument( + databaseId: '', + collectionId: '', + documentId: '', + [ + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ] +); +```server-python +databases.update_document( + database_id='', + collection_id='', + document_id='', + data={ + '$updatedAt': iso, + # ...your attributes + } +) +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let databases = Databases(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] +let updatedAt = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) + +do { + let updated = try await databases.updateDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: [ + "$updatedAt": updatedAt, + // ...your attributes + ] + ) + print("Updated:", updated) +} catch { + print("Update error:", error) +} +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +databases = Databases.new(client) + +custom_date = Time.parse('').iso8601 + +databases.update_document( + database_id: '', + collection_id: '', + document_id: '', + data: { + '$updatedAt' => custom_date, + # ...your attributes + } +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Databases databases = new Databases(client); + +string customDate = DateTimeOffset.Parse("").ToString("O"); + +await databases.UpdateDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: new Dictionary + { + ["$updatedAt"] = customDate, + // ...your attributes + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Databases databases = Databases(client); + +String customDate = DateTime.parse('').toIso8601String(); + +await databases.updateDocument( + databaseId: '', + collectionId: '', + documentId: '', + data: { + '\$updatedAt': customDate, + // ...your attributes + }, +); +``` +{% /multicode %} + +## Bulk operations {% #bulk-operations %} + +Custom timestamps also work with bulk operations, allowing you to set different timestamps for each document in the batch: + +### Bulk create {% #bulk-create %} + +{% multicode %} +```server-nodejs +await databases.createDocuments( + '', + '', + [ + { + '$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 attributes + }, + { + '$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 attributes + } + ] +); +``` +```server-python +databases.create_documents( + database_id='', + collection_id='', + documents=[ + { + '$id': ID.unique(), + '$createdAt': datetime(2024, 1, 1, tzinfo=timezone.utc).isoformat(), + '$updatedAt': datetime(2024, 1, 1, tzinfo=timezone.utc).isoformat(), + # ...your attributes + }, + { + '$id': ID.unique(), + '$createdAt': datetime(2024, 2, 1, tzinfo=timezone.utc).isoformat(), + '$updatedAt': datetime(2024, 2, 1, tzinfo=timezone.utc).isoformat(), + # ...your attributes + } + ] +) +``` +```server-php +use Appwrite\Client; +use Appwrite\ID; +use Appwrite\Services\Databases; + +$client = (new Client()) + ->setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$databases = new Databases($client); + +$databases->createDocuments( + databaseId: '', + collectionId: '', + documents: [ + [ + '$id' => ID::unique(), + '$createdAt' => (new DateTime(''))->format(DATE_ATOM), + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ], + [ + '$id' => ID::unique(), + '$createdAt' => (new DateTime(''))->format(DATE_ATOM), + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ], + ] +); +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let databases = Databases(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] + +let first = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) +let second = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) + +do { + let bulkCreated = try await databases.createDocuments( + databaseId: "", + collectionId: "", + documents: [ + [ + "$id": ID.unique(), + "$createdAt": first, + "$updatedAt": first, + // ...your attributes + ], + [ + "$id": ID.unique(), + "$createdAt": second, + "$updatedAt": second, + // ...your attributes + ] + ] + ) + print("Bulk create:", bulkCreated) +} catch { + print("Bulk create error:", error) +} +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +databases = Databases.new(client) + +first = Time.parse('').iso8601 +second = Time.parse('').iso8601 + +databases.create_documents( + database_id: '', + collection_id: '', + documents: [ + { + '$id' => ID.unique(), + '$createdAt' => first, + '$updatedAt' => first, + # ...your attributes + }, + { + '$id' => ID.unique(), + '$createdAt' => second, + '$updatedAt' => second, + # ...your attributes + } + ] +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Databases databases = new Databases(client); + +string first = DateTimeOffset.Parse("").ToString("O"); +string second = DateTimeOffset.Parse("").ToString("O"); + +await databases.CreateDocuments( + databaseId: "", + collectionId: "", + documents: new List + { + new Dictionary + { + ["$id"] = ID.Unique(), + ["$createdAt"] = first, + ["$updatedAt"] = first, + // ...your attributes + }, + new Dictionary + { + ["$id"] = ID.Unique(), + ["$createdAt"] = second, + ["$updatedAt"] = second, + // ...your attributes + } + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Databases databases = Databases(client); + +String first = DateTime.parse('').toIso8601String(); +String second = DateTime.parse('').toIso8601String(); + +await databases.createDocuments( + databaseId: '', + collectionId: '', + documents: [ + { + '\$id': ID.unique(), + '\$createdAt': first, + '\$updatedAt': first, + // ...your attributes + }, + { + '\$id': ID.unique(), + '\$createdAt': second, + '\$updatedAt': second, + // ...your attributes + } + ], +); +``` +{% /multicode %} + +### Bulk upsert {% #bulk-upsert %} + +{% multicode %} +```server-nodejs +await databases.upsertDocuments( + '', + '', + [ + { + '$id': '', + '$createdAt': new Date('2024-01-01T00:00:00.000Z').toISOString(), + '$updatedAt': new Date('2025-01-01T00:00:00.000Z').toISOString(), + // ...your attributes + } + ] +); +``` +```server-python +databases.upsert_documents( + database_id='', + collection_id='', + documents=[ + { + '$id': '', + '$createdAt': datetime(2024, 1, 1, tzinfo=timezone.utc).isoformat(), + '$updatedAt': datetime(2025, 1, 1, tzinfo=timezone.utc).isoformat(), + # ...your attributes + } + ] +) +``` +```server-php +use Appwrite\Client; +use Appwrite\ID; +use Appwrite\Services\Databases; + +$client = (new Client()) + ->setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$databases = new Databases($client); + +$databases->upsertDocuments( + databaseId: '', + collectionId: '', + documents: [ + [ + '$id' => '', + '$createdAt' => (new DateTime(''))->format(DATE_ATOM), + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ], + ] +); +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let databases = Databases(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] +let createdAt = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) +let updatedAt = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) + +do { + let bulkUpserted = try await databases.upsertDocuments( + databaseId: "", + collectionId: "", + documents: [ + [ + "$id": "", + "$createdAt": createdAt, + "$updatedAt": updatedAt, + // ...your attributes + ] + ] + ) + print("Bulk upsert:", bulkUpserted) +} catch { + print("Bulk upsert error:", error) +} +``` +```server-ruby +require 'appwrite' +require 'time' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +databases = Databases.new(client) + +custom_date = Time.parse('').iso8601 + +databases.upsert_documents( + database_id: '', + collection_id: '', + documents: [ + { + '$id' => '', + '$createdAt' => custom_date, + '$updatedAt' => custom_date, + # ...your attributes + } + ] +) +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +Databases databases = new Databases(client); + +string createdAt = DateTimeOffset.Parse("").ToString("O"); +string updatedAt = DateTimeOffset.Parse("").ToString("O"); + +await databases.UpsertDocuments( + databaseId: "", + collectionId: "", + documents: new List + { + new Dictionary + { + ["$id"] = "", + ["$createdAt"] = createdAt, + ["$updatedAt"] = updatedAt, + // ...your attributes + } + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +Databases databases = Databases(client); + +String createdAt = DateTime.parse('').toIso8601String(); +String updatedAt = DateTime.parse('').toIso8601String(); + +await databases.upsertDocuments( + databaseId: '', + collectionId: '', + documents: [ + { + '\$id': '', + '\$createdAt': createdAt, + '\$updatedAt': updatedAt, + // ...your attributes + } + ], +); +``` +{% /multicode %} + +# Common use cases {% #use-cases %} + +Custom timestamps are particularly useful in several scenarios: + +## Data migration {% #data-migration %} +When migrating existing data from another system, you can preserve the original +creation and modification times: + +{% multicode %} +```server-nodejs +await databases.createDocument( + '', + 'blog_posts', + sdk.ID.unique(), + { + '$createdAt': '', + '$updatedAt': '', + title: '', + content: '<CONTENT>' + } +) +``` +```server-php +$databases->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'blog_posts', + documentId: ID::unique(), + [ + '$createdAt' => '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt' => '<LAST_MODIFIED_ISO>', + 'title' => '<TITLE>', + 'content' => '<CONTENT>' + ] +); +``` +```server-swift +let _ = try await databases.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "blog_posts", + documentId: ID.unique(), + data: [ + "$createdAt": "<ORIGINAL_CREATED_AT_ISO>", + "$updatedAt": "<LAST_MODIFIED_ISO>", + "title": "<TITLE>", + "content": "<CONTENT>" + ] +) +``` +```server-python +databases.create_document( + database_id='<DATABASE_ID>', + collection_id='blog_posts', + document_id=ID.unique(), + data={ + '$createdAt': '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt': '<LAST_MODIFIED_ISO>', + 'title': '<TITLE>', + 'content': '<CONTENT>' + } +) +``` +```server-ruby +databases.create_document( + database_id: '<DATABASE_ID>', + collection_id: 'blog_posts', + document_id: ID.unique(), + data: { + '$createdAt' => '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt' => '<LAST_MODIFIED_ISO>', + 'title' => '<TITLE>', + 'content' => '<CONTENT>' + } +) +``` +```server-dotnet +await databases.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "blog_posts", + documentId: ID.Unique(), + data: new Dictionary<string, object> + { + ["$createdAt"] = "<ORIGINAL_CREATED_AT_ISO>", + ["$updatedAt"] = "<LAST_MODIFIED_ISO>", + ["title"] = "<TITLE>", + ["content"] = "<CONTENT>" + } +); +``` +```server-dart +await databases.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'blog_posts', + documentId: ID.unique(), + data: { + '\$createdAt': '<ORIGINAL_CREATED_AT_ISO>', + '\$updatedAt': '<LAST_MODIFIED_ISO>', + 'title': '<TITLE>', + 'content': '<CONTENT>' + }, +); +``` +{% /multicode %} + +## Backdating records {% #backdating %} +For historical data entry or when creating records that represent past events: + +{% multicode %} +```server-nodejs +await databases.createDocument( + '<DATABASE_ID>', + 'transactions', + sdk.ID.unique(), + { + '$createdAt': '2023-12-31T23:59:59.000Z', + '$updatedAt': '2023-12-31T23:59:59.000Z', + amount: 1000, + type: 'year-end-bonus' + } +) +``` +```server-php +$databases->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'transactions', + documentId: ID::unique(), + [ + '$createdAt' => '2023-12-31T23:59:59.000Z', + '$updatedAt' => '2023-12-31T23:59:59.000Z', + 'amount' => 1000, + 'type' => 'year-end-bonus' + ] +); +``` +```server-swift +let _ = try await databases.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "transactions", + documentId: ID.unique(), + data: [ + "$createdAt": "2023-12-31T23:59:59.000Z", + "$updatedAt": "2023-12-31T23:59:59.000Z", + "amount": 1000, + "type": "year-end-bonus" + ] +) +``` +```server-python +databases.create_document( + database_id='<DATABASE_ID>', + collection_id='transactions', + document_id=ID.unique(), + data={ + '$createdAt': '2023-12-31T23:59:59.000Z', + '$updatedAt': '2023-12-31T23:59:59.000Z', + 'amount': 1000, + 'type': 'year-end-bonus' + } +) +``` +```server-ruby +databases.create_document( + database_id: '<DATABASE_ID>', + collection_id: 'transactions', + document_id: ID.unique(), + data: { + '$createdAt' => '2023-12-31T23:59:59.000Z', + '$updatedAt' => '2023-12-31T23:59:59.000Z', + 'amount' => 1000, + 'type' => 'year-end-bonus' + } +) +``` +```server-dotnet +await databases.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "transactions", + documentId: ID.Unique(), + data: new Dictionary<string, object> + { + ["$createdAt"] = "2023-12-31T23:59:59.000Z", + ["$updatedAt"] = "2023-12-31T23:59:59.000Z", + ["amount"] = 1000, + ["type"] = "year-end-bonus" + } +); +``` +```server-dart +await databases.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'transactions', + documentId: ID.unique(), + data: { + '\$createdAt': '2023-12-31T23:59:59.000Z', + '\$updatedAt': '2023-12-31T23:59:59.000Z', + 'amount': 1000, + 'type': 'year-end-bonus' + }, +); +``` +{% /multicode %} + +## Synchronization {% #synchronization %} +When synchronizing data between systems while maintaining timestamp consistency: + +{% multicode %} +```server-nodejs +await databases.upsertDocument( + '<DATABASE_ID>', + 'users', + '<DOCUMENT_ID_OR_NEW_ID>', + { + '$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>', + profile: '<PROFILE_DATA>' + } +) +``` +```server-php +$databases->upsertDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'users', + documentId: '<DOCUMENT_ID_OR_NEW_ID>', + [ + '$updatedAt' => '<EXTERNAL_LAST_MODIFIED_ISO>', + 'profile' => '<PROFILE_DATA>' + ] +); +``` +```server-swift +let _ = try await databases.upsertDocument( + databaseId: "<DATABASE_ID>", + collectionId: "users", + documentId: "<DOCUMENT_ID_OR_NEW_ID>", + data: [ + "$updatedAt": "<EXTERNAL_LAST_MODIFIED_ISO>", + "profile": "<PROFILE_DATA>" + ] +) +``` +```server-python +databases.upsert_document( + database_id='<DATABASE_ID>', + collection_id='users', + document_id='<DOCUMENT_ID_OR_NEW_ID>', + data={ + '$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>', + 'profile': '<PROFILE_DATA>' + } +) +``` +```server-ruby +databases.upsert_document( + database_id: '<DATABASE_ID>', + collection_id: 'users', + document_id: '<DOCUMENT_ID_OR_NEW_ID>', + data: { + '$updatedAt' => '<EXTERNAL_LAST_MODIFIED_ISO>', + 'profile' => '<PROFILE_DATA>' + } +) +``` +```server-dotnet +await databases.UpsertDocument( + databaseId: "<DATABASE_ID>", + collectionId: "users", + documentId: "<DOCUMENT_ID_OR_NEW_ID>", + data: new Dictionary<string, object> + { + ["$updatedAt"] = "<EXTERNAL_LAST_MODIFIED_ISO>", + ["profile"] = "<PROFILE_DATA>" + } +); +``` +```server-dart +await databases.upsertDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'users', + documentId: '<DOCUMENT_ID_OR_NEW_ID>', + data: { + '\$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>', + 'profile': '<PROFILE_DATA>' + }, +); +``` +{% /multicode %} + +{% info title="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 attributes as needed. If omitted, Appwrite sets them automatically. +- Custom timestamps work with all document operations: create, update, upsert, and their bulk variants. +{% /info %} +