Appwrite Elixir SDK

View Source

Hex.pm Docs License

Elixir client SDK for Appwrite — the open-source backend-as-a-service platform. Covers all client-facing APIs: Auth · Databases · TablesDB · Storage · Functions · Sites · Tokens · Teams · Messaging · GraphQL · Locale · Avatars · Health.


Installation

Add appwrite to your dependencies in mix.exs:

def deps do
  [
    {:appwrite, "~> 1.0"}
  ]
end

Then fetch:

mix deps.get

Configuration

config/config.exs

config :appwrite,
  project_id: System.get_env("APPWRITE_PROJECT_ID"),
  secret:     System.get_env("APPWRITE_SECRET"),
  root_uri:   System.get_env("APPWRITE_ENDPOINT", "https://cloud.appwrite.io/v1")
import Config

if config_env() == :prod do
  config :appwrite,
    project_id: System.fetch_env!("APPWRITE_PROJECT_ID"),
    secret:     System.fetch_env!("APPWRITE_SECRET"),
    root_uri:   System.get_env("APPWRITE_ENDPOINT", "https://cloud.appwrite.io/v1")
end

Self-hosted Appwrite? Set APPWRITE_ENDPOINT to your instance URL, e.g. https://appwrite.mycompany.com/v1.


Quick start

alias Appwrite.Services.{Accounts, Database, Storage}
alias Appwrite.Utils.{Id, Query, Permission, Role}

# Create a new user
{:ok, _user} = Accounts.create(Id.unique(), "alice@example.com", "secret123")

# Email + password login
{:ok, _session} = Accounts.create_email_password_session("alice@example.com", "secret123")

# Query documents
{:ok, result} = Database.list_documents("my-db", "posts", [
  Query.equal("published", true),
  Query.order_desc("created_at"),
  Query.limit(10)
])

# Upload a file
file_content = File.read!("report.pdf")
{:ok, file} = Storage.create_file("my-bucket", Id.unique(), %{
  "name" => "report.pdf",
  "data" => file_content,
  "type" => "application/pdf",
  "size" => byte_size(file_content)
})

# Get a download URL (unauthenticated via token)
{:ok, token} = Appwrite.Services.Tokens.create_file_token("my-bucket", file["$id"])
{:ok, url} = Storage.get_file_download("my-bucket", file["$id"], token["secret"])

Services

ModuleAppwrite API
Appwrite.Services.AccountsAuth, sessions, MFA, OAuth2, recovery
Appwrite.Services.AvatarsAvatars, flags, QR codes, screenshots
Appwrite.Services.DatabaseDocuments, upsert, increment/decrement, transactions
Appwrite.Services.FunctionsExecutions (create, get, list)
Appwrite.Services.GraphQLGraphQL query and mutation
Appwrite.Services.HealthServer health checks
Appwrite.Services.LocaleCountries, currencies, languages
Appwrite.Services.MessagingPush/SMS/email topic subscribers
Appwrite.Services.SitesHosted site deployments and variables
Appwrite.Services.StorageFiles, chunked upload, preview/view/download URLs
Appwrite.Services.TablesDBTables, columns, rows
Appwrite.Services.TeamsTeams and memberships
Appwrite.Services.TokensFile access tokens

Utilities

ModulePurpose
Appwrite.Utils.QueryBuild filter/sort/pagination query strings
Appwrite.Utils.PermissionGenerate read(), write(), create() … strings
Appwrite.Utils.RoleGenerate any, user:id, team:id/role … strings
Appwrite.Utils.IdId.unique() / Id.custom("my-id")

Permission + Role example

alias Appwrite.Utils.{Permission, Role}

permissions = [
  Permission.read(Role.any()),               # public read
  Permission.create(Role.users()),           # any logged-in user can create
  Permission.update(Role.user("alice-id")),  # only alice can update
  Permission.delete(Role.team("admins"))     # admins can delete
]

Error handling

All service functions return {:ok, map()} or {:error, reason}. API errors are Appwrite.Exceptions.AppwriteException structs:

alias Appwrite.Exceptions.AppwriteException

case Accounts.get() do
  {:ok, user} ->
    IO.puts("Hello, #{user["name"]}")

  {:error, %AppwriteException{code: 401}} ->
    IO.puts("Not authenticated")

  {:error, %AppwriteException{code: code, message: msg}} ->
    IO.puts("Appwrite error #{code}: #{msg}")

  {:error, reason} ->
    IO.inspect(reason, label: "Unexpected error")
end

Requirements

  • Elixir ~> 1.18
  • Erlang/OTP 26+

License

Apache 2.0 — see LICENSE.