Appwrite 2.5.0 API 使用详解

Appwrite 2.5.0 REST API 逐条 curl 实测:认证体系与四类凭证、健康检查、组织/项目/Key 管理链路(含组织头要求)、数据库/集合/属性/文档 CRUD 与查询语法、TablesDB 新 API、用户与存储接口,全部真实回显照抄(长响应标注节选),附实测错误码速查表与查询语法坑位。

AppwriteAppwriteBaaS2026/10/18

Appwrite 2.5.0 API 使用详解

本文全部接口于 2026-10-18 在 Appwrite 2.5.0 实测环境逐条 curl 验证,回显为真实输出;超长响应标注「节选」。覆盖管理链路(组织/项目/Key)与业务链路(数据库/集合/文档、TablesDB、用户、存储)。

一、环境信息

项目内容
实测日期2026-10-18
实测版本Appwrite 2.5.0(/v1/health/version 返回 {"version":"2.5.0"})
API 基地址http://127.0.0.1:8102/v1(宿主端口 8102,部署见《Appwrite Docker Compose 部署指南》)
管理账号admin@example.com / q1w2e3r4(console 根管理员)
实测组织/项目quzuo-org / quzuo-demo
参数配置依据《Appwrite 2.5.0 配置参数详解》

二、认证体系与调用约定

2.1 四类凭证

凭证传递方式适用面
项目 ID请求头 X-Appwrite-Project: <projectId>所有业务 API 必带;管理 API 用 console
项目 API Key请求头 X-Appwrite-Key: <secret>业务 API(按 scope 授权)
管理员会话Cookie a_session_console(登录后获得)管理链路(组织/项目/Key)
组织头请求头 X-Appwrite-Organization: <orgId>组织级管理 API 必带(2.x 新增)

2.5.0 的关键变化:项目管理从 /v1/projects 迁移到 /v1/organization/projects,仅凭项目 API Key 调管理端点会 401,必须用管理员会话 + 组织头(实测见 4.2 节)。

2.2 无凭证调用的典型 401

curl -s http://127.0.0.1:8102/v1/databases -H 'X-Appwrite-Project: quzuo-demo'

实测回显:

{"message":"User (role: guests) missing scopes ([\"databases.read\"])","code":401,"type":"general_unauthorized_scope","version":"2.5.0"}

message 直接给出缺失的 scope 名,排障时按提示补 Key 或加 scope 即可。

三、健康检查 API

3.1 总健康(带 Key 与项目)

curl -s http://127.0.0.1:8102/v1/health \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY"

实测回显:

{"name":"http","ping":0,"status":"pass"}

3.2 数据库健康

curl -s http://127.0.0.1:8102/v1/health/db \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY"

实测回显:

{"total":2,"statuses":[{"name":"Console.DB (console)","ping":0,"status":"pass"},{"name":"Projects.DB (database_db_main)","ping":0,"status":"pass"}]}

3.3 缓存健康

{"total":1,"statuses":[{"name":"Cache","ping":0,"status":"pass"}]}

3.4 版本查询(需管理员会话)

curl -s http://127.0.0.1:8102/v1/health/version \
  -b cookies.txt -H 'X-Appwrite-Project: console'

实测回显:

{"version":"2.5.0"}

用项目 API Key 调它会 401(missing scopes (["public"]))——public 不在 Key scope 白名单内,此端点仅供 console 会话使用。

四、组织与项目管理 API

4.1 创建组织(组织本质是 console team)

curl -s -b cookies.txt -X POST http://127.0.0.1:8102/v1/teams \
  -H 'X-Appwrite-Project: console' -H 'Content-Type: application/json' \
  -d '{"teamId":"quzuo-org","name":"Quzuo Org"}'

实测回显(节选):

{"$id":"quzuo-org","$createdAt":"2026-10-18T12:13:40.682+00:00","$updatedAt":"2026-10-18T12:13:40.682+00:00","name":"Quzuo Org","total":1,...

4.2 创建项目

curl -s -b cookies.txt -X POST http://127.0.0.1:8102/v1/organization/projects \
  -H 'X-Appwrite-Project: console' -H 'X-Appwrite-Organization: quzuo-org' \
  -H 'Content-Type: application/json' \
  -d '{"projectId":"quzuo-demo","name":"Quzuo Demo"}'

实测回显(节选):

{"$id":"quzuo-demo","$createdAt":"2026-10-18T12:13:46.808+00:00","$updatedAt":"2026-10-18T12:13:46.808+00:00","name":"Quzuo Demo","teamId":"quzuo-org","region":"default",...

4.3 创建项目 API Key(scope 白名单实测)

curl -s -b cookies.txt -X POST http://127.0.0.1:8102/v1/organization/projects/quzuo-demo/keys \
  -H 'X-Appwrite-Project: console' -H 'X-Appwrite-Organization: quzuo-org' \
  -H 'Content-Type: application/json' \
  -d '{"keyId":"docs-test-key","name":"docs-test-key","scopes":["project.read","databases.read","databases.write","collections.read","collections.write","documents.read","documents.write","buckets.read","buckets.write","files.read","files.write","users.read","users.write","tables.read","tables.write","columns.read","columns.write","rows.read","rows.write","health.read"]}'

实测回显(节选;secret 仅创建响应中完整出现一次):

{"$id":"docs-test-key","name":"docs-test-key","scopes":["project.read","usage.read",...],"expire":null,"secret":"standard_8ac04ec4d6d309620c031ee4122f2be445aa4b77425cfbee03252e176c3a57e1e74e9b62b558b8e47a5b2f7165b75f11a3b94b9e823961128515649b5ff0bb465ac49b80fd30bdc6cb948254528acc19d0cfc66b607709ce8a447cfd98736718b44c2011c23fc5cedbb66aeb6651802e510850a2e6b6e44ec827139e05d70fec",...}

传入白名单外 scope(如 public)时返回 400,message 内附完整合法清单(节选):

{"message":"Invalid `scopes` param: Value must a valid array no longer than 200 items and Value must be one of (project.read, project.write, usage.read, keys.read, keys.write, platforms.read, ...","code":400,"type":"general_argument_invalid","version":"2.5.0"}

4.4 查询当前项目

curl -s http://127.0.0.1:8102/v1/project \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY"

实测回显(节选):

{"$id":"quzuo-demo","$createdAt":"2026-10-18T12:13:46.808+00:00","$updatedAt":"2026-10-18T12:16:46.079+00:00","name":"Quzuo Demo","teamId":"quzuo-org","region":"default","smtpEnabled":false,...

五、数据库 API(legacy:库/集合/属性)

5.1 创建数据库

curl -s -X POST http://127.0.0.1:8102/v1/databases \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY" \
  -H 'Content-Type: application/json' \
  -d '{"databaseId":"shop","name":"Shop"}'

实测回显:

{"$id":"shop","name":"Shop","$createdAt":"2026-10-18T12:15:19.034+00:00","$updatedAt":"2026-10-18T12:15:19.034+00:00","enabled":true,"type":"legacy","status":"ready"}

注意 "type":"legacy":2.5.0 里走 /v1/databases 建的是传统集合库;新的表模型走 /v1/tablesdb(见第七节,其库的 type 为 tablesdb)。

5.2 创建集合

curl -s -X POST http://127.0.0.1:8102/v1/databases/shop/collections \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY" \
  -H 'Content-Type: application/json' \
  -d '{"collectionId":"products","name":"Products","permissions":["read(\"any\")"],"documentSecurity":false}'

实测回显:

{"$id":"products","$createdAt":"2026-10-18T12:16:13.896+00:00","$updatedAt":"2026-10-18T12:16:13.896+00:00","$permissions":["read(\"any\")"],"databaseId":"shop","name":"Products","enabled":true,"documentSecurity":false,"attributes":[],"indexes":[],"bytesMax":65535,"bytesUsed":1067}

5.3 创建属性(四种类型)

必填字符串属性(128 字节):

{"key":"name","type":"string","status":"processing","error":"","required":true,"array":false,"$createdAt":"2026-10-18T12:16:13.933+00:00","$updatedAt":"2026-10-18T12:16:13.933+00:00","size":128,"default":null,"encrypt":false}

数值属性(float,实际落库为 double):

{"key":"price","type":"double","status":"processing","error":"","required":false,"array":false,"$createdAt":"2026-10-18T12:16:24.931+00:00","$updatedAt":"2026-10-18T12:16:24.931+00:00","min":0,"max":100000,"default":null}

整型属性(带默认值):

{"key":"stock","type":"integer","status":"processing","error":"","required":false,"array":false,"$createdAt":"2026-10-18T12:16:24.952+00:00","$updatedAt":"2026-10-18T12:16:24.952+00:00","min":0,"max":1000000,"default":0}

字符串数组属性:

{"key":"tags","type":"string","status":"processing","error":"","required":false,"array":true,"$createdAt":"2026-10-18T12:16:24.980+00:00","$updatedAt":"2026-10-18T12:16:24.980+00:00","size":64,"default":null,"encrypt":false}

5.4 等待属性就绪并核对

属性创建后为 processing,约 8 秒后变 available。查询集合核对:

curl -s http://127.0.0.1:8102/v1/databases/shop/collections/products \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY" \
  | python3 -c "import json,sys; d=json.load(sys.stdin); print([(a['key'],a['status']) for a in d['attributes']])"

实测回显:

[('name', 'available'), ('price', 'available'), ('stock', 'available'), ('tags', 'available')]

文档写入必须等全部依赖属性 available,否则 400。

六、文档 CRUD 与查询

6.1 创建文档(自动 ID)

curl -s -X POST http://127.0.0.1:8102/v1/databases/shop/collections/products/documents \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY" \
  -H 'Content-Type: application/json' \
  -d '{"documentId":"unique()","data":{"name":"机械键盘 K870","price":399.00,"stock":120,"tags":["外设","机械轴"]}}'

实测回显:

{"name":"机械键盘 K870","price":399,"stock":120,"tags":["外设","机械轴"],"$id":"6ad4b8ae1223941c7b2c","$permissions":[],"$createdAt":"2026-10-18T12:16:46.075+00:00","$updatedAt":"2026-10-18T12:16:46.075+00:00","$sequence":"1","$databaseId":"shop","$collectionId":"products"}

创建文档(指定 ID sku-001,回显同结构,$id":"sku-001"、$sequence":"2")。

6.2 查询(排序 + 条件过滤)

按 price 倒序列出全部:

curl -s "http://127.0.0.1:8102/v1/databases/shop/collections/products/documents?queries[0]={"method":"orderDesc","attribute":"price"}" \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY"

实测回显(节选):

{"total":2,"documents":[{"name":"机械键盘 K870","price":399,"stock":120,"tags":["外设","机械轴"],"$id":"6ad4b8ae1223941c7b2c",...},{...sku-001...}]}

条件过滤(price ≥ 100 且倒序,URL 编码后实际请求):

queries[0]={"method":"greaterThanEqual","attribute":"price","values":[100]}
queries[1]={"method":"orderDesc","attribute":"price"}

实测回显(total 与顺序核对):

total: 2
[('6ad4b8ae1223941c7b2c', '机械键盘 K870', 399), ('sku-001', '无线鼠标 M220', 129.5)]

⚠️ 实测坑:method 写 gte 报 400——

{"message":"Invalid query method: gte","code":400,"type":"general_query_invalid","version":"2.5.0"}

2.5.0 的查询方法使用全名:equal、notEqual、lessThan、lessThanEqual、greaterThan、greaterThanEqual、between、search、orderAsc、orderDesc 等。

6.3 更新文档

curl -s -X PATCH http://127.0.0.1:8102/v1/databases/shop/collections/products/documents/sku-001 \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY" \
  -H 'Content-Type: application/json' \
  -d '{"data":{"price":119.00}}'

实测回显(字段核对):

price now: 119 | updatedAt: 2026-10-18T12:17:23.101+00:00

6.4 删除文档

curl -s -X DELETE http://127.0.0.1:8102/v1/databases/shop/collections/products/documents/6ad4b8ae1223941c7b2c \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY" -w 'HTTP %{http_code}\n'

实测回显:

HTTP 204

删除后重查列表 total: 1,确认只剩 sku-001。

七、TablesDB 新 API(库/表/列/行)

7.1 建库与建表

POST /v1/tablesdb  {"databaseId":"crm","name":"CRM"}
→ {"$id":"crm","name":"CRM","$createdAt":"2026-10-18T12:17:43.370+00:00","$updatedAt":"2026-10-18T12:17:43.370+00:00","enabled":true,"type":"tablesdb","status":"ready"}

POST /v1/tablesdb/crm/tables  {"tableId":"customers","name":"Customers","permissions":["read(\"any\")"],"rowSecurity":false}
→ {"$id":"customers","$createdAt":"2026-10-18T12:17:43.402+00:00","$updatedAt":"2026-10-18T12:17:43.402+00:00","$permissions":["read(\"any\")"],"databaseId":"crm","name":"Customers","enabled":true,"rowSecurity":false,"columns":[],"indexes":[],"bytesMax":65535,"bytesUsed":1067}

7.2 建列与写行

POST /v1/tablesdb/crm/tables/customers/columns/string  {"key":"cname","size":128,"required":true}
→ {"key":"cname","type":"string","status":"processing",...,"size":128,...}

POST /v1/tablesdb/crm/tables/customers/rows  {"rowId":"c-001","data":{"cname":"李四"}}
→ {"cname":"李四","$id":"c-001","$permissions":[],"$createdAt":"2026-10-18T12:18:02.102+00:00","$updatedAt":"2026-10-18T12:18:02.102+00:00","$sequence":"1","$databaseId":"crm","$tableId":"customers"}

路径映射规律:legacy 的 collections/attributes/documents 在新模型中对应 tables/columns/rows,rowSecurity 对应 documentSecurity。两套 API 并存且数据互不相通,新项目建议直接用 TablesDB。

八、用户管理 API

curl -s -X POST http://127.0.0.1:8102/v1/users \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY" \
  -H 'Content-Type: application/json' \
  -d '{"userId":"unique()","email":"zhang@example.com","password":"q1w2e3r4","name":"张三"}'

实测回显(节选,注意密码以 argon2id 哈希返回,明文不落库):

{
    "$id": "6ad4b8e74c86ac7c8393",
    "$createdAt": "2026-10-18T12:17:43.329+00:00",
    "name": "张三",
    "password": "$argon2id$v=19$m=7168,t=5,p=1$RURTQUpLajg0VllMSk5TWA$ZBEqOQqzqDUepvg7sEv5JXFq4mSADpmyOrJNX75ehw4",
    "hash": "argon2",
    "hashOptions": {"type": "argon2","memory_cost": 7168,"time_cost": 5,"threads": 1}
    ...
}

九、存储 API

9.1 创建桶

curl -s -X POST http://127.0.0.1:8102/v1/storage/buckets \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY" \
  -H 'Content-Type: application/json' \
  -d '{"bucketId":"docs","name":"Docs","permissions":["read(\"any\")","create(\"users\")"],"fileSecurity":false,"enabled":true,"maximumFileSize":30000000}'

实测回显(节选):

{"$id":"docs","$createdAt":"2026-10-18T12:25:23.046+00:00","$updatedAt":"2026-10-18T12:25:23.046+00:00","$permissions":["read(\"any\")","create(\"users\")"],"fileSecurity":false,"name":"Docs","enabled":true,"maximumFileS...

maximumFileSize 受服务端 _APP_STORAGE_LIMIT 约束(实测:把该参数降到 1024 后,上例请求被 400 拒绝:Value must be a valid range between 1 and 1,024),详见《Appwrite 2.5.0 配置参数详解》第九章。

9.2 上传文件(multipart/form-data)

curl -s -X POST http://127.0.0.1:8102/v1/storage/buckets/docs/files \
  -H 'X-Appwrite-Project: quzuo-demo' -H "X-Appwrite-Key: $AWKEY" \
  -F 'fileId=unique()' -F 'file=@/tmp/small.bin'

实测回显(节选,200B 文件成功):

{"$id":"6ad4bab322e350def298","bucketId":"docs","$createdAt":"2026-10-18T12:25:23.152+00:00","$updatedAt":"2026-10-18T12:25:23.152+00:00","$permissions":[],"name":"small.bin","folder":"","key":"small.bin","signature":"fbaf48ec981a5eecdb57b929fdd426e8...

超限上传(2KB,桶上限 1024 时)实测回显:

{"message":"File size not allowed","code":400,"type":"storage_invalid_file_size","version":"2.5.0"}

十、错误码速查(全部实测)

codetype触发场景(实测)message 要点
400general_argument_invalidscope 超出白名单;maximumFileSize 超限;桶文件超限另有 storage_invalid_file_size提示合法取值范围
400general_query_invalid查询 method 写了 gteInvalid query method: gte
400storage_invalid_file_size上传文件大于桶上限File size not allowed
401general_unauthorized_scope无 Key / 缺 scope 访问业务 APImissing scopes (["databases.read"])
401user_email_not_whitelistedconsole 注册邮箱不在白名单Console registration is restricted...
401user_unauthorized用项目 Key 调 console-only 端点The current user is not authorized...
404document_not_found取不存在的文档Document with the requested ID 'no-such-doc' could not be found.
404storage_bucket_not_found取不存在的桶Storage bucket with the requested ID could not be found.
409database_already_exists重复的 databaseIdDatabase with the requested ID 'shop' already exists. Try again with a different ID or use ID.unique()...
501user_console_count_exceeded根管理员数已达上限(_APP_CONSOLE_WHITELIST_ROOT=enabled)提示将 ROOT 设为 disabled 或用白名单

十一、FAQ

11.1 为什么用项目 API Key 调项目管理接口是 401?

2.x 项目归属组织,管理链路(/v1/organization/*)只认「console 管理员会话 + X-Appwrite-Organization 头」。项目 Key 的 scope 白名单里没有组织管理类权限(实测报错同时给出全部合法 scope)。脚本化初始化的正确姿势:先登录拿会话,再走组织端点建项目与 Key,之后业务操作全部用项目 Key。

11.2 查询过滤的写法坑?

queries[] 数组里放 JSON 对象(URL 编码)。方法名必须用全名(greaterThanEqual),缩写(gte)实测 400。数值条件用 values 数组;排序用 orderDesc/orderAsc 且同样以 query 对象表达,没有独立的 sort 参数。

11.3 文档写入报 400 说 attribute unknown?

属性创建后处于 processing,需轮询到 available 才能写入。实测 8 秒左右就绪。批量建属性后逐个 GET 属性或 GET 集合核对 status。

11.4 API Key 的 secret 第二次查不到?

secret 仅在创建响应中返回一次,列表/详情接口只回脱敏摘要。创建时立即入库保管;泄露只能删除重建。

11.5 legacy collections 与 TablesDB 怎么选?

数据互不相通。存量项目/旧 SDK 兼容走 legacy;新项目用 TablesDB(type":"tablesdb" 的库),路径与字段名整体从集合语义换到表语义,未来演进以 TablesDB 为主。

十二、参考链接