Appwrite .NET SDK
Installation
Setting Up the Client
Code Examples
User Management
Database Operations
Note: Use
TablesDB(not the deprecatedDatabasesclass) for all new code. Only useDatabasesif the existing codebase already relies on it or the user explicitly requests it.Tip: Prefer named arguments (e.g.,
databaseId: "...") for all SDK method calls. Only use positional arguments if the existing codebase already uses them or the user explicitly requests it.
String Column Types
Note: The legacy
stringtype is deprecated. Use explicit column types for all new columns.
varcharis stored inline and counts towards the 64 KB row size limit. Prefer for short, indexed fields like names, slugs, or identifiers.text,mediumtext, andlongtextare stored off-page (only a 20-byte pointer lives in the row), so they don't consume the row size budget.sizeis not required for these types.
Query Methods
File Storage
InputFile Factory Methods
Teams
Role-based access: Use
Role.Team("[TEAM_ID]")for all team members orRole.Team("[TEAM_ID]", "editor")for a specific team role when setting permissions.
Serverless Functions
Writing a Function Handler (.NET runtime)
Server-Side Rendering (SSR) Authentication
SSR apps using .NET frameworks (ASP.NET, Blazor Server, etc.) use the server SDK to handle auth. You need two clients:
- Admin client — uses an API key, creates sessions, bypasses rate limits (reusable singleton)
- Session client — uses a session cookie, acts on behalf of a user (create per-request, never share)
Email/Password Login (ASP.NET Minimal API)
Authenticated Requests
OAuth2 SSR Flow
Cookie security: Always use
HttpOnly,Secure, andSameSite = SameSiteMode.Strictto prevent XSS. The cookie name must bea_session_<PROJECT_ID>.
Forwarding user agent: Call
sessionClient.SetForwardedUserAgent(ctx.Request.Headers["User-Agent"])to record the end-user's browser info for debugging and security.
Error Handling
Common error codes:
Permissions & Roles (Critical)
Appwrite uses permission strings to control access to resources. Each permission pairs an action (read, update, delete, create, or write which grants create + update + delete) with a role target. By default, no user has access unless permissions are explicitly set at the row/file level or inherited from the table/bucket settings. Permissions are arrays of strings built with the Permission and Role helpers.
Database Row with Permissions
File Upload with Permissions
When to set permissions: Set row/file-level permissions when you need per-resource access control. If all rows in a table share the same rules, configure permissions at the table/bucket level and leave row permissions empty.
Common mistakes:
- Forgetting permissions — the resource becomes inaccessible to all users (including the creator)
Role.Any()withwrite/update/delete— allows any user, including unauthenticated guests, to modify or remove the resourcePermission.Read(Role.Any())on sensitive data — makes the resource publicly readable

