Docs
Skip to content

VectorsDB

CSV imports_

Import embeddings into Appwrite VectorsDB by uploading a CSV file. Learn how to format the embeddings and metadata columns for a bulk import.

4 min read

Raw

Appwrite's CSV Import feature allows you to create multiple documents in a collection by uploading a single CSV file. This is especially useful for loading precomputed embeddings, seeding test environments, or migrating vectors from another system.

Prepare your CSV

A VectorsDB collection has a fixed schema, so every CSV maps to the same two columns:

ColumnTypeDescription
embeddingsvectorThe embedding vector, written as a JSON array. Required, and its length must equal the collection's dimension.
metadataobjectArbitrary JSON stored alongside the vector, written as a JSON object. Optional.

Each row represents a new document. The embeddings value is parsed as a JSON array of numbers, and the metadata value is parsed as a JSON object. Each row is validated before being imported.

An example of a valid CSV file for a collection created with dimension: 4:

Plain text
$id,embeddings,metadata
vec_1,"[0.12,0.04,0.88,0.31]","{""title"":""First vector"",""year"":2024}"
vec_2,"[0.55,0.61,0.07,0.42]","{""title"":""Second vector"",""year"":2025}"
vec_3,"[0.20,0.20,0.20,0.20]","{""title"":""Third vector"",""year"":2025}"

The double quotes around each value let you include the commas inside the JSON array and object. The inner double quotes of the JSON keys and string values are escaped by doubling them (""). See Special characters for the escaping rules.

Metadata values

The metadata column is an object, so each value must be a valid JSON object or the literal null:

  • A JSON object, for example "{""key"":""value""}". An empty object "{}" is also valid.
  • null (the unquoted literal) stores no metadata for that document.

A blank metadata value is not accepted. To omit metadata for a row, use null rather than leaving the field empty:

Plain text
$id,embeddings,metadata
vec_1,"[0.12,0.04,0.88,0.31]","{""title"":""With metadata""}"
vec_2,"[0.55,0.61,0.07,0.42]",null

Create and update timestamps

You can also optionally include $createdAt and $updatedAt columns to set custom timestamps for imported documents. If omitted, Appwrite sets these automatically during import.

An example of a valid CSV file with $createdAt and $updatedAt timestamps:

Plain text
$id,$createdAt,$updatedAt,embeddings,metadata
vec_1,2025-08-10T12:34:56.000Z,2025-08-10T12:34:56.000Z,"[0.12,0.04,0.88,0.31]","{""title"":""First vector""}"
vec_2,2025-08-11T09:15:00.000Z,2025-08-11T10:00:00.000Z,"[0.55,0.61,0.07,0.42]","{""title"":""Second vector""}"

Permissions

You can set permissions for documents in your CSV file by adding data for the $permissions column. Make sure document level security is enabled for your collection.

An example of a valid permissions string:

Plain text
"read(""any""),update(""users""),delete(""user:user_id"")"

The roles used are API strings that can be found in the permissions documentation.

A full example of a valid CSV file with document permissions:

Plain text
$id,embeddings,metadata,$permissions
vec_1,"[0.12,0.04,0.88,0.31]","{""title"":""First vector""}","read(""any""),update(""user:user_id""),delete(""user:user_id"")"
vec_2,"[0.55,0.61,0.07,0.42]","{""title"":""Second vector""}","read(""users""),update(""user:user_id"")"

Special characters

The embeddings and metadata values are JSON written inside CSV fields, so you need to escape the characters that CSV treats specially.

Comma

The JSON array and object both contain commas, so wrap each value in double quotes ("[0.1,0.2,0.3,0.4]"). Without the surrounding quotes, the commas would be read as column separators.

Double quotes

JSON keys and string values use double quotes, and a double quote inside a quoted CSV field must be escaped by doubling it (""). For example, the object {"title":"hello"} is written in the CSV as "{""title"":""hello""}".

Run the import

CSV imports run as a background migration. First upload your CSV to a storage bucket, then start the import against the target collection with POST /v1/migrations/csv/imports and an API key that has the migrations.write scope. The request takes the bucketId and fileId that hold your CSV, plus the databaseId and collectionId of the collection you are importing into.

The onDuplicate option controls what happens when a document with an existing $id is encountered: fail (the default) aborts on the first conflict, skip ignores it, and overwrite replaces the existing document.

Additional resources

Was this page helpful?

Share what worked or what we should fix. Once approved, our agents automatically apply suggested updates to the docs.