[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-appwrite-appwrite-ruby":3,"mdc--s10ost-key":33,"related-repo-appwrite-appwrite-ruby":3105,"related-org-appwrite-appwrite-ruby":3218},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":31,"mdContent":32},"appwrite-ruby","build applications with Appwrite Ruby SDK","Appwrite Ruby SDK skill. Use when building server-side Ruby applications with Appwrite, including Rails and Sinatra integrations. Covers user management, database\u002Ftable CRUD, file storage, and functions via API keys.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"appwrite","Appwrite","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fappwrite.png",[12,16,17,20],{"name":13,"slug":14,"type":15},"Backend","backend","tag",{"name":9,"slug":8,"type":15},{"name":18,"slug":19,"type":15},"API Development","api-development",{"name":21,"slug":22,"type":15},"Ruby","ruby",23,"https:\u002F\u002Fgithub.com\u002Fappwrite\u002Fskills","2026-07-12T08:45:34.567568",null,0,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":26},[],"https:\u002F\u002Fgithub.com\u002Fappwrite\u002Fskills\u002Ftree\u002FHEAD\u002Fskills\u002Fappwrite-ruby","---\nname: appwrite-ruby\ndescription: Appwrite Ruby SDK skill. Use when building server-side Ruby applications with Appwrite, including Rails and Sinatra integrations. Covers user management, database\u002Ftable CRUD, file storage, and functions via API keys.\n---\n\n\n# Appwrite Ruby SDK\n\n## Installation\n\n```bash\ngem install appwrite\n```\n\n## Setting Up the Client\n\n```ruby\nrequire 'appwrite'\n\ninclude Appwrite\n\nclient = Client.new\n    .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n    .set_project(ENV['APPWRITE_PROJECT_ID'])\n    .set_key(ENV['APPWRITE_API_KEY'])\n```\n\n## Code Examples\n\n### User Management\n\n```ruby\nusers = Users.new(client)\n\n# Create user\nuser = users.create(user_id: ID.unique, email: 'user@example.com', password: 'password123', name: 'User Name')\n\n# List users\nlist = users.list(queries: [Query.limit(25)])\n\n# Get user\nfetched = users.get(user_id: '[USER_ID]')\n\n# Delete user\nusers.delete(user_id: '[USER_ID]')\n```\n\n### Database Operations\n\n> **Note:** Use `TablesDB` (not the deprecated `Databases` class) for all new code. Only use `Databases` if the existing codebase already relies on it or the user explicitly requests it.\n>\n> **Tip:** Prefer keyword arguments (e.g., `database_id: '...'`) for all SDK method calls. Only use positional arguments if the existing codebase already uses them or the user explicitly requests it.\n\n```ruby\ntables_db = TablesDB.new(client)\n\n# Create database\ndb = tables_db.create(database_id: ID.unique, name: 'My Database')\n\n# Create row\ndoc = tables_db.create_row(\n    database_id: '[DATABASE_ID]',\n    table_id: '[TABLE_ID]',\n    row_id: ID.unique,\n    data: { title: 'Hello World' }\n)\n\n# Query rows\nresults = tables_db.list_rows(\n    database_id: '[DATABASE_ID]',\n    table_id: '[TABLE_ID]',\n    queries: [Query.equal('title', 'Hello World'), Query.limit(10)]\n)\n\n# Get row\nrow = tables_db.get_row(database_id: '[DATABASE_ID]', table_id: '[TABLE_ID]', row_id: '[ROW_ID]')\n\n# Update row\ntables_db.update_row(\n    database_id: '[DATABASE_ID]',\n    table_id: '[TABLE_ID]',\n    row_id: '[ROW_ID]',\n    data: { title: 'Updated' }\n)\n\n# Delete row\ntables_db.delete_row(database_id: '[DATABASE_ID]', table_id: '[TABLE_ID]', row_id: '[ROW_ID]')\n```\n\n#### String Column Types\n\n> **Note:** The legacy `string` type is deprecated. Use explicit column types for all new columns.\n\n| Type | Max characters | Indexing | Storage |\n|------|---------------|----------|---------|\n| `varchar` | 16,383 | Full index (if size ≤ 768) | Inline in row |\n| `text` | 16,383 | Prefix only | Off-page |\n| `mediumtext` | 4,194,303 | Prefix only | Off-page |\n| `longtext` | 1,073,741,823 | Prefix only | Off-page |\n\n- `varchar` is stored inline and counts towards the 64 KB row size limit. Prefer for short, indexed fields like names, slugs, or identifiers.\n- `text`, `mediumtext`, and `longtext` are stored off-page (only a 20-byte pointer lives in the row), so they don't consume the row size budget. `size` is not required for these types.\n\n```ruby\n# Create table with explicit string column types\ntables_db.create_table(\n    database_id: '[DATABASE_ID]',\n    table_id: ID.unique,\n    name: 'articles',\n    columns: [\n        { key: 'title',    type: 'varchar',    size: 255, required: true  },  # inline, fully indexable\n        { key: 'summary',  type: 'text',                  required: false },  # off-page, prefix index only\n        { key: 'body',     type: 'mediumtext',            required: false },  # up to ~4 M chars\n        { key: 'raw_data', type: 'longtext',              required: false },  # up to ~1 B chars\n    ]\n)\n```\n\n### Query Methods\n\n```ruby\n# Filtering\nQuery.equal('field', 'value')             # == (or pass array for IN)\nQuery.not_equal('field', 'value')         # !=\nQuery.less_than('field', 100)             # \u003C\nQuery.less_than_equal('field', 100)       # \u003C=\nQuery.greater_than('field', 100)          # >\nQuery.greater_than_equal('field', 100)    # >=\nQuery.between('field', 1, 100)            # 1 \u003C= field \u003C= 100\nQuery.is_null('field')                    # is null\nQuery.is_not_null('field')                # is not null\nQuery.starts_with('field', 'prefix')      # starts with\nQuery.ends_with('field', 'suffix')        # ends with\nQuery.contains('field', 'sub')            # contains\nQuery.search('field', 'keywords')         # full-text search (requires index)\n\n# Sorting\nQuery.order_asc('field')\nQuery.order_desc('field')\n\n# Pagination\nQuery.limit(25)                           # max rows (default 25, max 100)\nQuery.offset(0)                           # skip N rows\nQuery.cursor_after('[ROW_ID]')            # cursor pagination (preferred)\nQuery.cursor_before('[ROW_ID]')\n\n# Selection & Logic\nQuery.select(['field1', 'field2'])        # return only specified fields\nQuery.or([Query.equal('a', 1), Query.equal('b', 2)])   # OR\nQuery.and([Query.greater_than('age', 18), Query.less_than('age', 65)])  # AND (default)\n```\n\n### File Storage\n\n```ruby\nstorage = Storage.new(client)\n\n# Upload file\nfile = storage.create_file(bucket_id: '[BUCKET_ID]', file_id: ID.unique, file: InputFile.from_path('\u002Fpath\u002Fto\u002Ffile.png'))\n\n# List files\nfiles = storage.list_files(bucket_id: '[BUCKET_ID]')\n\n# Delete file\nstorage.delete_file(bucket_id: '[BUCKET_ID]', file_id: '[FILE_ID]')\n```\n\n#### InputFile Factory Methods\n\n```ruby\nInputFile.from_path('\u002Fpath\u002Fto\u002Ffile.png')             # from filesystem path\nInputFile.from_string('Hello world', 'hello.txt')    # from string content\n```\n\n### Teams\n\n```ruby\nteams = Teams.new(client)\n\n# Create team\nteam = teams.create(team_id: ID.unique, name: 'Engineering')\n\n# List teams\nlist = teams.list\n\n# Create membership (invite user by email)\nmembership = teams.create_membership(\n    team_id: '[TEAM_ID]',\n    roles: ['editor'],\n    email: 'user@example.com'\n)\n\n# List memberships\nmembers = teams.list_memberships(team_id: '[TEAM_ID]')\n\n# Update membership roles\nteams.update_membership(team_id: '[TEAM_ID]', membership_id: '[MEMBERSHIP_ID]', roles: ['admin'])\n\n# Delete team\nteams.delete(team_id: '[TEAM_ID]')\n```\n\n> **Role-based access:** Use `Role.team('[TEAM_ID]')` for all team members or `Role.team('[TEAM_ID]', 'editor')` for a specific team role when setting permissions.\n\n### Serverless Functions\n\n```ruby\nfunctions = Functions.new(client)\n\n# Execute function\nexecution = functions.create_execution(function_id: '[FUNCTION_ID]', body: '{\"key\": \"value\"}')\n\n# List executions\nexecutions = functions.list_executions(function_id: '[FUNCTION_ID]')\n```\n\n#### Writing a Function Handler (Ruby runtime)\n\n```ruby\n# src\u002Fmain.rb — Appwrite Function entry point\ndef main(context)\n    # context.req.body         — raw body (String)\n    # context.req.body_json    — parsed JSON (Hash or nil)\n    # context.req.headers      — headers (Hash)\n    # context.req.method       — HTTP method\n    # context.req.path         — URL path\n    # context.req.query        — query params (Hash)\n\n    context.log(\"Processing: #{context.req.method} #{context.req.path}\")\n\n    if context.req.method == 'GET'\n        return context.res.json({ message: 'Hello from Appwrite Function!' })\n    end\n\n    context.res.json({ success: true })          # JSON\n    # context.res.text('Hello')                  # plain text\n    # context.res.empty                          # 204\n    # context.res.redirect('https:\u002F\u002F...')         # 302\nend\n```\n\n### Server-Side Rendering (SSR) Authentication\n\nSSR apps using Ruby frameworks (Rails, Sinatra, etc.) use the **server SDK** to handle auth. You need two clients:\n\n- **Admin client** — uses an API key, creates sessions, bypasses rate limits (reusable singleton)\n- **Session client** — uses a session cookie, acts on behalf of a user (create per-request, never share)\n\n```ruby\nrequire 'appwrite'\ninclude Appwrite\n\n# Admin client (reusable)\nadmin_client = Client.new\n    .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n    .set_project('[PROJECT_ID]')\n    .set_key(ENV['APPWRITE_API_KEY'])\n\n# Session client (create per-request)\nsession_client = Client.new\n    .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n    .set_project('[PROJECT_ID]')\n\nsession = cookies['a_session_[PROJECT_ID]']\nsession_client.set_session(session) if session\n```\n\n#### Email\u002FPassword Login (Sinatra)\n\n```ruby\npost '\u002Flogin' do\n    account = Account.new(admin_client)\n    session = account.create_email_password_session(\n        email: params[:email],\n        password: params[:password]\n    )\n\n    # Cookie name must be a_session_\u003CPROJECT_ID>\n    response.set_cookie('a_session_[PROJECT_ID]', {\n        value: session.secret,\n        httponly: true,\n        secure: true,\n        same_site: :strict,\n        path: '\u002F',\n    })\n\n    content_type :json\n    { success: true }.to_json\nend\n```\n\n#### Authenticated Requests\n\n```ruby\nget '\u002Fuser' do\n    session = request.cookies['a_session_[PROJECT_ID]']\n    halt 401, { error: 'Unauthorized' }.to_json unless session\n\n    session_client = Client.new\n        .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n        .set_project('[PROJECT_ID]')\n        .set_session(session)\n\n    account = Account.new(session_client)\n    user = account.get\n\n    content_type :json\n    user.to_json\nend\n```\n\n#### OAuth2 SSR Flow\n\n```ruby\n# Step 1: Redirect to OAuth provider\nget '\u002Foauth' do\n    account = Account.new(admin_client)\n    redirect_url = account.create_o_auth2_token(\n        provider: OAuthProvider::GITHUB,\n        success: 'https:\u002F\u002Fexample.com\u002Foauth\u002Fsuccess',\n        failure: 'https:\u002F\u002Fexample.com\u002Foauth\u002Ffailure'\n    )\n    redirect redirect_url\nend\n\n# Step 2: Handle callback — exchange token for session\nget '\u002Foauth\u002Fsuccess' do\n    account = Account.new(admin_client)\n    session = account.create_session(\n        user_id: params[:userId],\n        secret: params[:secret]\n    )\n\n    response.set_cookie('a_session_[PROJECT_ID]', {\n        value: session.secret,\n        httponly: true, secure: true, same_site: :strict, path: '\u002F',\n    })\n\n    content_type :json\n    { success: true }.to_json\nend\n```\n\n> **Cookie security:** Always use `httponly`, `secure`, and `same_site: :strict` to prevent XSS. The cookie name must be `a_session_\u003CPROJECT_ID>`.\n\n> **Forwarding user agent:** Call `session_client.set_forwarded_user_agent(request.user_agent)` to record the end-user's browser info for debugging and security.\n\n## Error Handling\n\n```ruby\nrequire 'appwrite'\ninclude Appwrite\n\nbegin\n    row = tables_db.get_row(database_id: '[DATABASE_ID]', table_id: '[TABLE_ID]', row_id: '[ROW_ID]')\nrescue Appwrite::Exception => e\n    puts e.message    # human-readable message\n    puts e.code       # HTTP status code (Integer)\n    puts e.type       # error type (e.g. 'document_not_found')\n    puts e.response   # full response body (Hash)\nend\n```\n\n**Common error codes:**\n\n| Code | Meaning |\n|------|---------|\n| `401` | Unauthorized — missing or invalid session\u002FAPI key |\n| `403` | Forbidden — insufficient permissions |\n| `404` | Not found — resource does not exist |\n| `409` | Conflict — duplicate ID or unique constraint |\n| `429` | Rate limited — too many requests |\n\n## Permissions & Roles (Critical)\n\nAppwrite 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\u002Ffile level or inherited from the table\u002Fbucket settings. Permissions are arrays of strings built with the `Permission` and `Role` helpers.\n\n```ruby\n# Permission and Role are included in the main require\nrequire 'appwrite'\ninclude Appwrite\n```\n\n### Database Row with Permissions\n\n```ruby\ndoc = tables_db.create_row(\n    database_id: '[DATABASE_ID]',\n    table_id: '[TABLE_ID]',\n    row_id: ID.unique,\n    data: { title: 'Hello World' },\n    permissions: [\n        Permission.read(Role.user('[USER_ID]')),     # specific user can read\n        Permission.update(Role.user('[USER_ID]')),   # specific user can update\n        Permission.read(Role.team('[TEAM_ID]')),     # all team members can read\n        Permission.read(Role.any),                   # anyone (including guests) can read\n    ]\n)\n```\n\n### File Upload with Permissions\n\n```ruby\nfile = storage.create_file(\n    bucket_id: '[BUCKET_ID]',\n    file_id: ID.unique,\n    file: InputFile.from_path('\u002Fpath\u002Fto\u002Ffile.png'),\n    permissions: [\n        Permission.read(Role.any),\n        Permission.update(Role.user('[USER_ID]')),\n        Permission.delete(Role.user('[USER_ID]')),\n    ]\n)\n```\n\n> **When to set permissions:** Set row\u002Ffile-level permissions when you need per-resource access control. If all rows in a table share the same rules, configure permissions at the table\u002Fbucket level and leave row permissions empty.\n\n> **Common mistakes:**\n> - **Forgetting permissions** — the resource becomes inaccessible to all users (including the creator)\n> - **`Role.any` with `write`\u002F`update`\u002F`delete`** — allows any user, including unauthenticated guests, to modify or remove the resource\n> - **`Permission.read(Role.any)` on sensitive data** — makes the resource publicly readable\n\n",{"data":34,"body":35},{"name":4,"description":6},{"type":36,"children":37},"root",[38,47,54,89,95,174,180,187,299,305,362,640,647,667,807,854,955,961,1197,1203,1287,1293,1316,1322,1506,1534,1540,1601,1607,1771,1777,1789,1812,1938,1944,2100,2106,2228,2234,2443,2486,2507,2513,2604,2612,2719,2725,2790,2819,2825,2922,2928,3012,3025,3099],{"type":39,"tag":40,"props":41,"children":43},"element","h1",{"id":42},"appwrite-ruby-sdk",[44],{"type":45,"value":46},"text","Appwrite Ruby SDK",{"type":39,"tag":48,"props":49,"children":51},"h2",{"id":50},"installation",[52],{"type":45,"value":53},"Installation",{"type":39,"tag":55,"props":56,"children":61},"pre",{"className":57,"code":58,"language":59,"meta":60,"style":60},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","gem install appwrite\n","bash","",[62],{"type":39,"tag":63,"props":64,"children":65},"code",{"__ignoreMap":60},[66],{"type":39,"tag":67,"props":68,"children":71},"span",{"class":69,"line":70},"line",1,[72,78,84],{"type":39,"tag":67,"props":73,"children":75},{"style":74},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[76],{"type":45,"value":77},"gem",{"type":39,"tag":67,"props":79,"children":81},{"style":80},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[82],{"type":45,"value":83}," install",{"type":39,"tag":67,"props":85,"children":86},{"style":80},[87],{"type":45,"value":88}," appwrite\n",{"type":39,"tag":48,"props":90,"children":92},{"id":91},"setting-up-the-client",[93],{"type":45,"value":94},"Setting Up the Client",{"type":39,"tag":55,"props":96,"children":99},{"className":97,"code":98,"language":22,"meta":60,"style":60},"language-ruby shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","require 'appwrite'\n\ninclude Appwrite\n\nclient = Client.new\n    .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n    .set_project(ENV['APPWRITE_PROJECT_ID'])\n    .set_key(ENV['APPWRITE_API_KEY'])\n",[100],{"type":39,"tag":63,"props":101,"children":102},{"__ignoreMap":60},[103,111,121,130,138,147,156,165],{"type":39,"tag":67,"props":104,"children":105},{"class":69,"line":70},[106],{"type":39,"tag":67,"props":107,"children":108},{},[109],{"type":45,"value":110},"require 'appwrite'\n",{"type":39,"tag":67,"props":112,"children":114},{"class":69,"line":113},2,[115],{"type":39,"tag":67,"props":116,"children":118},{"emptyLinePlaceholder":117},true,[119],{"type":45,"value":120},"\n",{"type":39,"tag":67,"props":122,"children":124},{"class":69,"line":123},3,[125],{"type":39,"tag":67,"props":126,"children":127},{},[128],{"type":45,"value":129},"include Appwrite\n",{"type":39,"tag":67,"props":131,"children":133},{"class":69,"line":132},4,[134],{"type":39,"tag":67,"props":135,"children":136},{"emptyLinePlaceholder":117},[137],{"type":45,"value":120},{"type":39,"tag":67,"props":139,"children":141},{"class":69,"line":140},5,[142],{"type":39,"tag":67,"props":143,"children":144},{},[145],{"type":45,"value":146},"client = Client.new\n",{"type":39,"tag":67,"props":148,"children":150},{"class":69,"line":149},6,[151],{"type":39,"tag":67,"props":152,"children":153},{},[154],{"type":45,"value":155},"    .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n",{"type":39,"tag":67,"props":157,"children":159},{"class":69,"line":158},7,[160],{"type":39,"tag":67,"props":161,"children":162},{},[163],{"type":45,"value":164},"    .set_project(ENV['APPWRITE_PROJECT_ID'])\n",{"type":39,"tag":67,"props":166,"children":168},{"class":69,"line":167},8,[169],{"type":39,"tag":67,"props":170,"children":171},{},[172],{"type":45,"value":173},"    .set_key(ENV['APPWRITE_API_KEY'])\n",{"type":39,"tag":48,"props":175,"children":177},{"id":176},"code-examples",[178],{"type":45,"value":179},"Code Examples",{"type":39,"tag":181,"props":182,"children":184},"h3",{"id":183},"user-management",[185],{"type":45,"value":186},"User Management",{"type":39,"tag":55,"props":188,"children":190},{"className":97,"code":189,"language":22,"meta":60,"style":60},"users = Users.new(client)\n\n# Create user\nuser = users.create(user_id: ID.unique, email: 'user@example.com', password: 'password123', name: 'User Name')\n\n# List users\nlist = users.list(queries: [Query.limit(25)])\n\n# Get user\nfetched = users.get(user_id: '[USER_ID]')\n\n# Delete user\nusers.delete(user_id: '[USER_ID]')\n",[191],{"type":39,"tag":63,"props":192,"children":193},{"__ignoreMap":60},[194,202,209,217,225,232,240,248,255,264,273,281,290],{"type":39,"tag":67,"props":195,"children":196},{"class":69,"line":70},[197],{"type":39,"tag":67,"props":198,"children":199},{},[200],{"type":45,"value":201},"users = Users.new(client)\n",{"type":39,"tag":67,"props":203,"children":204},{"class":69,"line":113},[205],{"type":39,"tag":67,"props":206,"children":207},{"emptyLinePlaceholder":117},[208],{"type":45,"value":120},{"type":39,"tag":67,"props":210,"children":211},{"class":69,"line":123},[212],{"type":39,"tag":67,"props":213,"children":214},{},[215],{"type":45,"value":216},"# Create user\n",{"type":39,"tag":67,"props":218,"children":219},{"class":69,"line":132},[220],{"type":39,"tag":67,"props":221,"children":222},{},[223],{"type":45,"value":224},"user = users.create(user_id: ID.unique, email: 'user@example.com', password: 'password123', name: 'User Name')\n",{"type":39,"tag":67,"props":226,"children":227},{"class":69,"line":140},[228],{"type":39,"tag":67,"props":229,"children":230},{"emptyLinePlaceholder":117},[231],{"type":45,"value":120},{"type":39,"tag":67,"props":233,"children":234},{"class":69,"line":149},[235],{"type":39,"tag":67,"props":236,"children":237},{},[238],{"type":45,"value":239},"# List users\n",{"type":39,"tag":67,"props":241,"children":242},{"class":69,"line":158},[243],{"type":39,"tag":67,"props":244,"children":245},{},[246],{"type":45,"value":247},"list = users.list(queries: [Query.limit(25)])\n",{"type":39,"tag":67,"props":249,"children":250},{"class":69,"line":167},[251],{"type":39,"tag":67,"props":252,"children":253},{"emptyLinePlaceholder":117},[254],{"type":45,"value":120},{"type":39,"tag":67,"props":256,"children":258},{"class":69,"line":257},9,[259],{"type":39,"tag":67,"props":260,"children":261},{},[262],{"type":45,"value":263},"# Get user\n",{"type":39,"tag":67,"props":265,"children":267},{"class":69,"line":266},10,[268],{"type":39,"tag":67,"props":269,"children":270},{},[271],{"type":45,"value":272},"fetched = users.get(user_id: '[USER_ID]')\n",{"type":39,"tag":67,"props":274,"children":276},{"class":69,"line":275},11,[277],{"type":39,"tag":67,"props":278,"children":279},{"emptyLinePlaceholder":117},[280],{"type":45,"value":120},{"type":39,"tag":67,"props":282,"children":284},{"class":69,"line":283},12,[285],{"type":39,"tag":67,"props":286,"children":287},{},[288],{"type":45,"value":289},"# Delete user\n",{"type":39,"tag":67,"props":291,"children":293},{"class":69,"line":292},13,[294],{"type":39,"tag":67,"props":295,"children":296},{},[297],{"type":45,"value":298},"users.delete(user_id: '[USER_ID]')\n",{"type":39,"tag":181,"props":300,"children":302},{"id":301},"database-operations",[303],{"type":45,"value":304},"Database Operations",{"type":39,"tag":306,"props":307,"children":308},"blockquote",{},[309,344],{"type":39,"tag":310,"props":311,"children":312},"p",{},[313,319,321,327,329,335,337,342],{"type":39,"tag":314,"props":315,"children":316},"strong",{},[317],{"type":45,"value":318},"Note:",{"type":45,"value":320}," Use ",{"type":39,"tag":63,"props":322,"children":324},{"className":323},[],[325],{"type":45,"value":326},"TablesDB",{"type":45,"value":328}," (not the deprecated ",{"type":39,"tag":63,"props":330,"children":332},{"className":331},[],[333],{"type":45,"value":334},"Databases",{"type":45,"value":336}," class) for all new code. Only use ",{"type":39,"tag":63,"props":338,"children":340},{"className":339},[],[341],{"type":45,"value":334},{"type":45,"value":343}," if the existing codebase already relies on it or the user explicitly requests it.",{"type":39,"tag":310,"props":345,"children":346},{},[347,352,354,360],{"type":39,"tag":314,"props":348,"children":349},{},[350],{"type":45,"value":351},"Tip:",{"type":45,"value":353}," Prefer keyword arguments (e.g., ",{"type":39,"tag":63,"props":355,"children":357},{"className":356},[],[358],{"type":45,"value":359},"database_id: '...'",{"type":45,"value":361},") for all SDK method calls. Only use positional arguments if the existing codebase already uses them or the user explicitly requests it.",{"type":39,"tag":55,"props":363,"children":365},{"className":97,"code":364,"language":22,"meta":60,"style":60},"tables_db = TablesDB.new(client)\n\n# Create database\ndb = tables_db.create(database_id: ID.unique, name: 'My Database')\n\n# Create row\ndoc = tables_db.create_row(\n    database_id: '[DATABASE_ID]',\n    table_id: '[TABLE_ID]',\n    row_id: ID.unique,\n    data: { title: 'Hello World' }\n)\n\n# Query rows\nresults = tables_db.list_rows(\n    database_id: '[DATABASE_ID]',\n    table_id: '[TABLE_ID]',\n    queries: [Query.equal('title', 'Hello World'), Query.limit(10)]\n)\n\n# Get row\nrow = tables_db.get_row(database_id: '[DATABASE_ID]', table_id: '[TABLE_ID]', row_id: '[ROW_ID]')\n\n# Update row\ntables_db.update_row(\n    database_id: '[DATABASE_ID]',\n    table_id: '[TABLE_ID]',\n    row_id: '[ROW_ID]',\n    data: { title: 'Updated' }\n)\n\n# Delete row\ntables_db.delete_row(database_id: '[DATABASE_ID]', table_id: '[TABLE_ID]', row_id: '[ROW_ID]')\n",[366],{"type":39,"tag":63,"props":367,"children":368},{"__ignoreMap":60},[369,377,384,392,400,407,415,423,431,439,447,455,463,470,479,488,496,504,513,521,529,538,547,554,563,572,580,588,597,606,614,622,631],{"type":39,"tag":67,"props":370,"children":371},{"class":69,"line":70},[372],{"type":39,"tag":67,"props":373,"children":374},{},[375],{"type":45,"value":376},"tables_db = TablesDB.new(client)\n",{"type":39,"tag":67,"props":378,"children":379},{"class":69,"line":113},[380],{"type":39,"tag":67,"props":381,"children":382},{"emptyLinePlaceholder":117},[383],{"type":45,"value":120},{"type":39,"tag":67,"props":385,"children":386},{"class":69,"line":123},[387],{"type":39,"tag":67,"props":388,"children":389},{},[390],{"type":45,"value":391},"# Create database\n",{"type":39,"tag":67,"props":393,"children":394},{"class":69,"line":132},[395],{"type":39,"tag":67,"props":396,"children":397},{},[398],{"type":45,"value":399},"db = tables_db.create(database_id: ID.unique, name: 'My Database')\n",{"type":39,"tag":67,"props":401,"children":402},{"class":69,"line":140},[403],{"type":39,"tag":67,"props":404,"children":405},{"emptyLinePlaceholder":117},[406],{"type":45,"value":120},{"type":39,"tag":67,"props":408,"children":409},{"class":69,"line":149},[410],{"type":39,"tag":67,"props":411,"children":412},{},[413],{"type":45,"value":414},"# Create row\n",{"type":39,"tag":67,"props":416,"children":417},{"class":69,"line":158},[418],{"type":39,"tag":67,"props":419,"children":420},{},[421],{"type":45,"value":422},"doc = tables_db.create_row(\n",{"type":39,"tag":67,"props":424,"children":425},{"class":69,"line":167},[426],{"type":39,"tag":67,"props":427,"children":428},{},[429],{"type":45,"value":430},"    database_id: '[DATABASE_ID]',\n",{"type":39,"tag":67,"props":432,"children":433},{"class":69,"line":257},[434],{"type":39,"tag":67,"props":435,"children":436},{},[437],{"type":45,"value":438},"    table_id: '[TABLE_ID]',\n",{"type":39,"tag":67,"props":440,"children":441},{"class":69,"line":266},[442],{"type":39,"tag":67,"props":443,"children":444},{},[445],{"type":45,"value":446},"    row_id: ID.unique,\n",{"type":39,"tag":67,"props":448,"children":449},{"class":69,"line":275},[450],{"type":39,"tag":67,"props":451,"children":452},{},[453],{"type":45,"value":454},"    data: { title: 'Hello World' }\n",{"type":39,"tag":67,"props":456,"children":457},{"class":69,"line":283},[458],{"type":39,"tag":67,"props":459,"children":460},{},[461],{"type":45,"value":462},")\n",{"type":39,"tag":67,"props":464,"children":465},{"class":69,"line":292},[466],{"type":39,"tag":67,"props":467,"children":468},{"emptyLinePlaceholder":117},[469],{"type":45,"value":120},{"type":39,"tag":67,"props":471,"children":473},{"class":69,"line":472},14,[474],{"type":39,"tag":67,"props":475,"children":476},{},[477],{"type":45,"value":478},"# Query rows\n",{"type":39,"tag":67,"props":480,"children":482},{"class":69,"line":481},15,[483],{"type":39,"tag":67,"props":484,"children":485},{},[486],{"type":45,"value":487},"results = tables_db.list_rows(\n",{"type":39,"tag":67,"props":489,"children":491},{"class":69,"line":490},16,[492],{"type":39,"tag":67,"props":493,"children":494},{},[495],{"type":45,"value":430},{"type":39,"tag":67,"props":497,"children":499},{"class":69,"line":498},17,[500],{"type":39,"tag":67,"props":501,"children":502},{},[503],{"type":45,"value":438},{"type":39,"tag":67,"props":505,"children":507},{"class":69,"line":506},18,[508],{"type":39,"tag":67,"props":509,"children":510},{},[511],{"type":45,"value":512},"    queries: [Query.equal('title', 'Hello World'), Query.limit(10)]\n",{"type":39,"tag":67,"props":514,"children":516},{"class":69,"line":515},19,[517],{"type":39,"tag":67,"props":518,"children":519},{},[520],{"type":45,"value":462},{"type":39,"tag":67,"props":522,"children":524},{"class":69,"line":523},20,[525],{"type":39,"tag":67,"props":526,"children":527},{"emptyLinePlaceholder":117},[528],{"type":45,"value":120},{"type":39,"tag":67,"props":530,"children":532},{"class":69,"line":531},21,[533],{"type":39,"tag":67,"props":534,"children":535},{},[536],{"type":45,"value":537},"# Get row\n",{"type":39,"tag":67,"props":539,"children":541},{"class":69,"line":540},22,[542],{"type":39,"tag":67,"props":543,"children":544},{},[545],{"type":45,"value":546},"row = tables_db.get_row(database_id: '[DATABASE_ID]', table_id: '[TABLE_ID]', row_id: '[ROW_ID]')\n",{"type":39,"tag":67,"props":548,"children":549},{"class":69,"line":23},[550],{"type":39,"tag":67,"props":551,"children":552},{"emptyLinePlaceholder":117},[553],{"type":45,"value":120},{"type":39,"tag":67,"props":555,"children":557},{"class":69,"line":556},24,[558],{"type":39,"tag":67,"props":559,"children":560},{},[561],{"type":45,"value":562},"# Update row\n",{"type":39,"tag":67,"props":564,"children":566},{"class":69,"line":565},25,[567],{"type":39,"tag":67,"props":568,"children":569},{},[570],{"type":45,"value":571},"tables_db.update_row(\n",{"type":39,"tag":67,"props":573,"children":575},{"class":69,"line":574},26,[576],{"type":39,"tag":67,"props":577,"children":578},{},[579],{"type":45,"value":430},{"type":39,"tag":67,"props":581,"children":583},{"class":69,"line":582},27,[584],{"type":39,"tag":67,"props":585,"children":586},{},[587],{"type":45,"value":438},{"type":39,"tag":67,"props":589,"children":591},{"class":69,"line":590},28,[592],{"type":39,"tag":67,"props":593,"children":594},{},[595],{"type":45,"value":596},"    row_id: '[ROW_ID]',\n",{"type":39,"tag":67,"props":598,"children":600},{"class":69,"line":599},29,[601],{"type":39,"tag":67,"props":602,"children":603},{},[604],{"type":45,"value":605},"    data: { title: 'Updated' }\n",{"type":39,"tag":67,"props":607,"children":609},{"class":69,"line":608},30,[610],{"type":39,"tag":67,"props":611,"children":612},{},[613],{"type":45,"value":462},{"type":39,"tag":67,"props":615,"children":617},{"class":69,"line":616},31,[618],{"type":39,"tag":67,"props":619,"children":620},{"emptyLinePlaceholder":117},[621],{"type":45,"value":120},{"type":39,"tag":67,"props":623,"children":625},{"class":69,"line":624},32,[626],{"type":39,"tag":67,"props":627,"children":628},{},[629],{"type":45,"value":630},"# Delete row\n",{"type":39,"tag":67,"props":632,"children":634},{"class":69,"line":633},33,[635],{"type":39,"tag":67,"props":636,"children":637},{},[638],{"type":45,"value":639},"tables_db.delete_row(database_id: '[DATABASE_ID]', table_id: '[TABLE_ID]', row_id: '[ROW_ID]')\n",{"type":39,"tag":641,"props":642,"children":644},"h4",{"id":643},"string-column-types",[645],{"type":45,"value":646},"String Column Types",{"type":39,"tag":306,"props":648,"children":649},{},[650],{"type":39,"tag":310,"props":651,"children":652},{},[653,657,659,665],{"type":39,"tag":314,"props":654,"children":655},{},[656],{"type":45,"value":318},{"type":45,"value":658}," The legacy ",{"type":39,"tag":63,"props":660,"children":662},{"className":661},[],[663],{"type":45,"value":664},"string",{"type":45,"value":666}," type is deprecated. Use explicit column types for all new columns.",{"type":39,"tag":668,"props":669,"children":670},"table",{},[671,700],{"type":39,"tag":672,"props":673,"children":674},"thead",{},[675],{"type":39,"tag":676,"props":677,"children":678},"tr",{},[679,685,690,695],{"type":39,"tag":680,"props":681,"children":682},"th",{},[683],{"type":45,"value":684},"Type",{"type":39,"tag":680,"props":686,"children":687},{},[688],{"type":45,"value":689},"Max characters",{"type":39,"tag":680,"props":691,"children":692},{},[693],{"type":45,"value":694},"Indexing",{"type":39,"tag":680,"props":696,"children":697},{},[698],{"type":45,"value":699},"Storage",{"type":39,"tag":701,"props":702,"children":703},"tbody",{},[704,732,757,782],{"type":39,"tag":676,"props":705,"children":706},{},[707,717,722,727],{"type":39,"tag":708,"props":709,"children":710},"td",{},[711],{"type":39,"tag":63,"props":712,"children":714},{"className":713},[],[715],{"type":45,"value":716},"varchar",{"type":39,"tag":708,"props":718,"children":719},{},[720],{"type":45,"value":721},"16,383",{"type":39,"tag":708,"props":723,"children":724},{},[725],{"type":45,"value":726},"Full index (if size ≤ 768)",{"type":39,"tag":708,"props":728,"children":729},{},[730],{"type":45,"value":731},"Inline in row",{"type":39,"tag":676,"props":733,"children":734},{},[735,743,747,752],{"type":39,"tag":708,"props":736,"children":737},{},[738],{"type":39,"tag":63,"props":739,"children":741},{"className":740},[],[742],{"type":45,"value":45},{"type":39,"tag":708,"props":744,"children":745},{},[746],{"type":45,"value":721},{"type":39,"tag":708,"props":748,"children":749},{},[750],{"type":45,"value":751},"Prefix only",{"type":39,"tag":708,"props":753,"children":754},{},[755],{"type":45,"value":756},"Off-page",{"type":39,"tag":676,"props":758,"children":759},{},[760,769,774,778],{"type":39,"tag":708,"props":761,"children":762},{},[763],{"type":39,"tag":63,"props":764,"children":766},{"className":765},[],[767],{"type":45,"value":768},"mediumtext",{"type":39,"tag":708,"props":770,"children":771},{},[772],{"type":45,"value":773},"4,194,303",{"type":39,"tag":708,"props":775,"children":776},{},[777],{"type":45,"value":751},{"type":39,"tag":708,"props":779,"children":780},{},[781],{"type":45,"value":756},{"type":39,"tag":676,"props":783,"children":784},{},[785,794,799,803],{"type":39,"tag":708,"props":786,"children":787},{},[788],{"type":39,"tag":63,"props":789,"children":791},{"className":790},[],[792],{"type":45,"value":793},"longtext",{"type":39,"tag":708,"props":795,"children":796},{},[797],{"type":45,"value":798},"1,073,741,823",{"type":39,"tag":708,"props":800,"children":801},{},[802],{"type":45,"value":751},{"type":39,"tag":708,"props":804,"children":805},{},[806],{"type":45,"value":756},{"type":39,"tag":808,"props":809,"children":810},"ul",{},[811,822],{"type":39,"tag":812,"props":813,"children":814},"li",{},[815,820],{"type":39,"tag":63,"props":816,"children":818},{"className":817},[],[819],{"type":45,"value":716},{"type":45,"value":821}," is stored inline and counts towards the 64 KB row size limit. Prefer for short, indexed fields like names, slugs, or identifiers.",{"type":39,"tag":812,"props":823,"children":824},{},[825,830,832,837,839,844,846,852],{"type":39,"tag":63,"props":826,"children":828},{"className":827},[],[829],{"type":45,"value":45},{"type":45,"value":831},", ",{"type":39,"tag":63,"props":833,"children":835},{"className":834},[],[836],{"type":45,"value":768},{"type":45,"value":838},", and ",{"type":39,"tag":63,"props":840,"children":842},{"className":841},[],[843],{"type":45,"value":793},{"type":45,"value":845}," are stored off-page (only a 20-byte pointer lives in the row), so they don't consume the row size budget. ",{"type":39,"tag":63,"props":847,"children":849},{"className":848},[],[850],{"type":45,"value":851},"size",{"type":45,"value":853}," is not required for these types.",{"type":39,"tag":55,"props":855,"children":857},{"className":97,"code":856,"language":22,"meta":60,"style":60},"# Create table with explicit string column types\ntables_db.create_table(\n    database_id: '[DATABASE_ID]',\n    table_id: ID.unique,\n    name: 'articles',\n    columns: [\n        { key: 'title',    type: 'varchar',    size: 255, required: true  },  # inline, fully indexable\n        { key: 'summary',  type: 'text',                  required: false },  # off-page, prefix index only\n        { key: 'body',     type: 'mediumtext',            required: false },  # up to ~4 M chars\n        { key: 'raw_data', type: 'longtext',              required: false },  # up to ~1 B chars\n    ]\n)\n",[858],{"type":39,"tag":63,"props":859,"children":860},{"__ignoreMap":60},[861,869,877,884,892,900,908,916,924,932,940,948],{"type":39,"tag":67,"props":862,"children":863},{"class":69,"line":70},[864],{"type":39,"tag":67,"props":865,"children":866},{},[867],{"type":45,"value":868},"# Create table with explicit string column types\n",{"type":39,"tag":67,"props":870,"children":871},{"class":69,"line":113},[872],{"type":39,"tag":67,"props":873,"children":874},{},[875],{"type":45,"value":876},"tables_db.create_table(\n",{"type":39,"tag":67,"props":878,"children":879},{"class":69,"line":123},[880],{"type":39,"tag":67,"props":881,"children":882},{},[883],{"type":45,"value":430},{"type":39,"tag":67,"props":885,"children":886},{"class":69,"line":132},[887],{"type":39,"tag":67,"props":888,"children":889},{},[890],{"type":45,"value":891},"    table_id: ID.unique,\n",{"type":39,"tag":67,"props":893,"children":894},{"class":69,"line":140},[895],{"type":39,"tag":67,"props":896,"children":897},{},[898],{"type":45,"value":899},"    name: 'articles',\n",{"type":39,"tag":67,"props":901,"children":902},{"class":69,"line":149},[903],{"type":39,"tag":67,"props":904,"children":905},{},[906],{"type":45,"value":907},"    columns: [\n",{"type":39,"tag":67,"props":909,"children":910},{"class":69,"line":158},[911],{"type":39,"tag":67,"props":912,"children":913},{},[914],{"type":45,"value":915},"        { key: 'title',    type: 'varchar',    size: 255, required: true  },  # inline, fully indexable\n",{"type":39,"tag":67,"props":917,"children":918},{"class":69,"line":167},[919],{"type":39,"tag":67,"props":920,"children":921},{},[922],{"type":45,"value":923},"        { key: 'summary',  type: 'text',                  required: false },  # off-page, prefix index only\n",{"type":39,"tag":67,"props":925,"children":926},{"class":69,"line":257},[927],{"type":39,"tag":67,"props":928,"children":929},{},[930],{"type":45,"value":931},"        { key: 'body',     type: 'mediumtext',            required: false },  # up to ~4 M chars\n",{"type":39,"tag":67,"props":933,"children":934},{"class":69,"line":266},[935],{"type":39,"tag":67,"props":936,"children":937},{},[938],{"type":45,"value":939},"        { key: 'raw_data', type: 'longtext',              required: false },  # up to ~1 B chars\n",{"type":39,"tag":67,"props":941,"children":942},{"class":69,"line":275},[943],{"type":39,"tag":67,"props":944,"children":945},{},[946],{"type":45,"value":947},"    ]\n",{"type":39,"tag":67,"props":949,"children":950},{"class":69,"line":283},[951],{"type":39,"tag":67,"props":952,"children":953},{},[954],{"type":45,"value":462},{"type":39,"tag":181,"props":956,"children":958},{"id":957},"query-methods",[959],{"type":45,"value":960},"Query Methods",{"type":39,"tag":55,"props":962,"children":964},{"className":97,"code":963,"language":22,"meta":60,"style":60},"# Filtering\nQuery.equal('field', 'value')             # == (or pass array for IN)\nQuery.not_equal('field', 'value')         # !=\nQuery.less_than('field', 100)             # \u003C\nQuery.less_than_equal('field', 100)       # \u003C=\nQuery.greater_than('field', 100)          # >\nQuery.greater_than_equal('field', 100)    # >=\nQuery.between('field', 1, 100)            # 1 \u003C= field \u003C= 100\nQuery.is_null('field')                    # is null\nQuery.is_not_null('field')                # is not null\nQuery.starts_with('field', 'prefix')      # starts with\nQuery.ends_with('field', 'suffix')        # ends with\nQuery.contains('field', 'sub')            # contains\nQuery.search('field', 'keywords')         # full-text search (requires index)\n\n# Sorting\nQuery.order_asc('field')\nQuery.order_desc('field')\n\n# Pagination\nQuery.limit(25)                           # max rows (default 25, max 100)\nQuery.offset(0)                           # skip N rows\nQuery.cursor_after('[ROW_ID]')            # cursor pagination (preferred)\nQuery.cursor_before('[ROW_ID]')\n\n# Selection & Logic\nQuery.select(['field1', 'field2'])        # return only specified fields\nQuery.or([Query.equal('a', 1), Query.equal('b', 2)])   # OR\nQuery.and([Query.greater_than('age', 18), Query.less_than('age', 65)])  # AND (default)\n",[965],{"type":39,"tag":63,"props":966,"children":967},{"__ignoreMap":60},[968,976,984,992,1000,1008,1016,1024,1032,1040,1048,1056,1064,1072,1080,1087,1095,1103,1111,1118,1126,1134,1142,1150,1158,1165,1173,1181,1189],{"type":39,"tag":67,"props":969,"children":970},{"class":69,"line":70},[971],{"type":39,"tag":67,"props":972,"children":973},{},[974],{"type":45,"value":975},"# Filtering\n",{"type":39,"tag":67,"props":977,"children":978},{"class":69,"line":113},[979],{"type":39,"tag":67,"props":980,"children":981},{},[982],{"type":45,"value":983},"Query.equal('field', 'value')             # == (or pass array for IN)\n",{"type":39,"tag":67,"props":985,"children":986},{"class":69,"line":123},[987],{"type":39,"tag":67,"props":988,"children":989},{},[990],{"type":45,"value":991},"Query.not_equal('field', 'value')         # !=\n",{"type":39,"tag":67,"props":993,"children":994},{"class":69,"line":132},[995],{"type":39,"tag":67,"props":996,"children":997},{},[998],{"type":45,"value":999},"Query.less_than('field', 100)             # \u003C\n",{"type":39,"tag":67,"props":1001,"children":1002},{"class":69,"line":140},[1003],{"type":39,"tag":67,"props":1004,"children":1005},{},[1006],{"type":45,"value":1007},"Query.less_than_equal('field', 100)       # \u003C=\n",{"type":39,"tag":67,"props":1009,"children":1010},{"class":69,"line":149},[1011],{"type":39,"tag":67,"props":1012,"children":1013},{},[1014],{"type":45,"value":1015},"Query.greater_than('field', 100)          # >\n",{"type":39,"tag":67,"props":1017,"children":1018},{"class":69,"line":158},[1019],{"type":39,"tag":67,"props":1020,"children":1021},{},[1022],{"type":45,"value":1023},"Query.greater_than_equal('field', 100)    # >=\n",{"type":39,"tag":67,"props":1025,"children":1026},{"class":69,"line":167},[1027],{"type":39,"tag":67,"props":1028,"children":1029},{},[1030],{"type":45,"value":1031},"Query.between('field', 1, 100)            # 1 \u003C= field \u003C= 100\n",{"type":39,"tag":67,"props":1033,"children":1034},{"class":69,"line":257},[1035],{"type":39,"tag":67,"props":1036,"children":1037},{},[1038],{"type":45,"value":1039},"Query.is_null('field')                    # is null\n",{"type":39,"tag":67,"props":1041,"children":1042},{"class":69,"line":266},[1043],{"type":39,"tag":67,"props":1044,"children":1045},{},[1046],{"type":45,"value":1047},"Query.is_not_null('field')                # is not null\n",{"type":39,"tag":67,"props":1049,"children":1050},{"class":69,"line":275},[1051],{"type":39,"tag":67,"props":1052,"children":1053},{},[1054],{"type":45,"value":1055},"Query.starts_with('field', 'prefix')      # starts with\n",{"type":39,"tag":67,"props":1057,"children":1058},{"class":69,"line":283},[1059],{"type":39,"tag":67,"props":1060,"children":1061},{},[1062],{"type":45,"value":1063},"Query.ends_with('field', 'suffix')        # ends with\n",{"type":39,"tag":67,"props":1065,"children":1066},{"class":69,"line":292},[1067],{"type":39,"tag":67,"props":1068,"children":1069},{},[1070],{"type":45,"value":1071},"Query.contains('field', 'sub')            # contains\n",{"type":39,"tag":67,"props":1073,"children":1074},{"class":69,"line":472},[1075],{"type":39,"tag":67,"props":1076,"children":1077},{},[1078],{"type":45,"value":1079},"Query.search('field', 'keywords')         # full-text search (requires index)\n",{"type":39,"tag":67,"props":1081,"children":1082},{"class":69,"line":481},[1083],{"type":39,"tag":67,"props":1084,"children":1085},{"emptyLinePlaceholder":117},[1086],{"type":45,"value":120},{"type":39,"tag":67,"props":1088,"children":1089},{"class":69,"line":490},[1090],{"type":39,"tag":67,"props":1091,"children":1092},{},[1093],{"type":45,"value":1094},"# Sorting\n",{"type":39,"tag":67,"props":1096,"children":1097},{"class":69,"line":498},[1098],{"type":39,"tag":67,"props":1099,"children":1100},{},[1101],{"type":45,"value":1102},"Query.order_asc('field')\n",{"type":39,"tag":67,"props":1104,"children":1105},{"class":69,"line":506},[1106],{"type":39,"tag":67,"props":1107,"children":1108},{},[1109],{"type":45,"value":1110},"Query.order_desc('field')\n",{"type":39,"tag":67,"props":1112,"children":1113},{"class":69,"line":515},[1114],{"type":39,"tag":67,"props":1115,"children":1116},{"emptyLinePlaceholder":117},[1117],{"type":45,"value":120},{"type":39,"tag":67,"props":1119,"children":1120},{"class":69,"line":523},[1121],{"type":39,"tag":67,"props":1122,"children":1123},{},[1124],{"type":45,"value":1125},"# Pagination\n",{"type":39,"tag":67,"props":1127,"children":1128},{"class":69,"line":531},[1129],{"type":39,"tag":67,"props":1130,"children":1131},{},[1132],{"type":45,"value":1133},"Query.limit(25)                           # max rows (default 25, max 100)\n",{"type":39,"tag":67,"props":1135,"children":1136},{"class":69,"line":540},[1137],{"type":39,"tag":67,"props":1138,"children":1139},{},[1140],{"type":45,"value":1141},"Query.offset(0)                           # skip N rows\n",{"type":39,"tag":67,"props":1143,"children":1144},{"class":69,"line":23},[1145],{"type":39,"tag":67,"props":1146,"children":1147},{},[1148],{"type":45,"value":1149},"Query.cursor_after('[ROW_ID]')            # cursor pagination (preferred)\n",{"type":39,"tag":67,"props":1151,"children":1152},{"class":69,"line":556},[1153],{"type":39,"tag":67,"props":1154,"children":1155},{},[1156],{"type":45,"value":1157},"Query.cursor_before('[ROW_ID]')\n",{"type":39,"tag":67,"props":1159,"children":1160},{"class":69,"line":565},[1161],{"type":39,"tag":67,"props":1162,"children":1163},{"emptyLinePlaceholder":117},[1164],{"type":45,"value":120},{"type":39,"tag":67,"props":1166,"children":1167},{"class":69,"line":574},[1168],{"type":39,"tag":67,"props":1169,"children":1170},{},[1171],{"type":45,"value":1172},"# Selection & Logic\n",{"type":39,"tag":67,"props":1174,"children":1175},{"class":69,"line":582},[1176],{"type":39,"tag":67,"props":1177,"children":1178},{},[1179],{"type":45,"value":1180},"Query.select(['field1', 'field2'])        # return only specified fields\n",{"type":39,"tag":67,"props":1182,"children":1183},{"class":69,"line":590},[1184],{"type":39,"tag":67,"props":1185,"children":1186},{},[1187],{"type":45,"value":1188},"Query.or([Query.equal('a', 1), Query.equal('b', 2)])   # OR\n",{"type":39,"tag":67,"props":1190,"children":1191},{"class":69,"line":599},[1192],{"type":39,"tag":67,"props":1193,"children":1194},{},[1195],{"type":45,"value":1196},"Query.and([Query.greater_than('age', 18), Query.less_than('age', 65)])  # AND (default)\n",{"type":39,"tag":181,"props":1198,"children":1200},{"id":1199},"file-storage",[1201],{"type":45,"value":1202},"File Storage",{"type":39,"tag":55,"props":1204,"children":1206},{"className":97,"code":1205,"language":22,"meta":60,"style":60},"storage = Storage.new(client)\n\n# Upload file\nfile = storage.create_file(bucket_id: '[BUCKET_ID]', file_id: ID.unique, file: InputFile.from_path('\u002Fpath\u002Fto\u002Ffile.png'))\n\n# List files\nfiles = storage.list_files(bucket_id: '[BUCKET_ID]')\n\n# Delete file\nstorage.delete_file(bucket_id: '[BUCKET_ID]', file_id: '[FILE_ID]')\n",[1207],{"type":39,"tag":63,"props":1208,"children":1209},{"__ignoreMap":60},[1210,1218,1225,1233,1241,1248,1256,1264,1271,1279],{"type":39,"tag":67,"props":1211,"children":1212},{"class":69,"line":70},[1213],{"type":39,"tag":67,"props":1214,"children":1215},{},[1216],{"type":45,"value":1217},"storage = Storage.new(client)\n",{"type":39,"tag":67,"props":1219,"children":1220},{"class":69,"line":113},[1221],{"type":39,"tag":67,"props":1222,"children":1223},{"emptyLinePlaceholder":117},[1224],{"type":45,"value":120},{"type":39,"tag":67,"props":1226,"children":1227},{"class":69,"line":123},[1228],{"type":39,"tag":67,"props":1229,"children":1230},{},[1231],{"type":45,"value":1232},"# Upload file\n",{"type":39,"tag":67,"props":1234,"children":1235},{"class":69,"line":132},[1236],{"type":39,"tag":67,"props":1237,"children":1238},{},[1239],{"type":45,"value":1240},"file = storage.create_file(bucket_id: '[BUCKET_ID]', file_id: ID.unique, file: InputFile.from_path('\u002Fpath\u002Fto\u002Ffile.png'))\n",{"type":39,"tag":67,"props":1242,"children":1243},{"class":69,"line":140},[1244],{"type":39,"tag":67,"props":1245,"children":1246},{"emptyLinePlaceholder":117},[1247],{"type":45,"value":120},{"type":39,"tag":67,"props":1249,"children":1250},{"class":69,"line":149},[1251],{"type":39,"tag":67,"props":1252,"children":1253},{},[1254],{"type":45,"value":1255},"# List files\n",{"type":39,"tag":67,"props":1257,"children":1258},{"class":69,"line":158},[1259],{"type":39,"tag":67,"props":1260,"children":1261},{},[1262],{"type":45,"value":1263},"files = storage.list_files(bucket_id: '[BUCKET_ID]')\n",{"type":39,"tag":67,"props":1265,"children":1266},{"class":69,"line":167},[1267],{"type":39,"tag":67,"props":1268,"children":1269},{"emptyLinePlaceholder":117},[1270],{"type":45,"value":120},{"type":39,"tag":67,"props":1272,"children":1273},{"class":69,"line":257},[1274],{"type":39,"tag":67,"props":1275,"children":1276},{},[1277],{"type":45,"value":1278},"# Delete file\n",{"type":39,"tag":67,"props":1280,"children":1281},{"class":69,"line":266},[1282],{"type":39,"tag":67,"props":1283,"children":1284},{},[1285],{"type":45,"value":1286},"storage.delete_file(bucket_id: '[BUCKET_ID]', file_id: '[FILE_ID]')\n",{"type":39,"tag":641,"props":1288,"children":1290},{"id":1289},"inputfile-factory-methods",[1291],{"type":45,"value":1292},"InputFile Factory Methods",{"type":39,"tag":55,"props":1294,"children":1296},{"className":97,"code":1295,"language":22,"meta":60,"style":60},"InputFile.from_path('\u002Fpath\u002Fto\u002Ffile.png')             # from filesystem path\nInputFile.from_string('Hello world', 'hello.txt')    # from string content\n",[1297],{"type":39,"tag":63,"props":1298,"children":1299},{"__ignoreMap":60},[1300,1308],{"type":39,"tag":67,"props":1301,"children":1302},{"class":69,"line":70},[1303],{"type":39,"tag":67,"props":1304,"children":1305},{},[1306],{"type":45,"value":1307},"InputFile.from_path('\u002Fpath\u002Fto\u002Ffile.png')             # from filesystem path\n",{"type":39,"tag":67,"props":1309,"children":1310},{"class":69,"line":113},[1311],{"type":39,"tag":67,"props":1312,"children":1313},{},[1314],{"type":45,"value":1315},"InputFile.from_string('Hello world', 'hello.txt')    # from string content\n",{"type":39,"tag":181,"props":1317,"children":1319},{"id":1318},"teams",[1320],{"type":45,"value":1321},"Teams",{"type":39,"tag":55,"props":1323,"children":1325},{"className":97,"code":1324,"language":22,"meta":60,"style":60},"teams = Teams.new(client)\n\n# Create team\nteam = teams.create(team_id: ID.unique, name: 'Engineering')\n\n# List teams\nlist = teams.list\n\n# Create membership (invite user by email)\nmembership = teams.create_membership(\n    team_id: '[TEAM_ID]',\n    roles: ['editor'],\n    email: 'user@example.com'\n)\n\n# List memberships\nmembers = teams.list_memberships(team_id: '[TEAM_ID]')\n\n# Update membership roles\nteams.update_membership(team_id: '[TEAM_ID]', membership_id: '[MEMBERSHIP_ID]', roles: ['admin'])\n\n# Delete team\nteams.delete(team_id: '[TEAM_ID]')\n",[1326],{"type":39,"tag":63,"props":1327,"children":1328},{"__ignoreMap":60},[1329,1337,1344,1352,1360,1367,1375,1383,1390,1398,1406,1414,1422,1430,1437,1444,1452,1460,1467,1475,1483,1490,1498],{"type":39,"tag":67,"props":1330,"children":1331},{"class":69,"line":70},[1332],{"type":39,"tag":67,"props":1333,"children":1334},{},[1335],{"type":45,"value":1336},"teams = Teams.new(client)\n",{"type":39,"tag":67,"props":1338,"children":1339},{"class":69,"line":113},[1340],{"type":39,"tag":67,"props":1341,"children":1342},{"emptyLinePlaceholder":117},[1343],{"type":45,"value":120},{"type":39,"tag":67,"props":1345,"children":1346},{"class":69,"line":123},[1347],{"type":39,"tag":67,"props":1348,"children":1349},{},[1350],{"type":45,"value":1351},"# Create team\n",{"type":39,"tag":67,"props":1353,"children":1354},{"class":69,"line":132},[1355],{"type":39,"tag":67,"props":1356,"children":1357},{},[1358],{"type":45,"value":1359},"team = teams.create(team_id: ID.unique, name: 'Engineering')\n",{"type":39,"tag":67,"props":1361,"children":1362},{"class":69,"line":140},[1363],{"type":39,"tag":67,"props":1364,"children":1365},{"emptyLinePlaceholder":117},[1366],{"type":45,"value":120},{"type":39,"tag":67,"props":1368,"children":1369},{"class":69,"line":149},[1370],{"type":39,"tag":67,"props":1371,"children":1372},{},[1373],{"type":45,"value":1374},"# List teams\n",{"type":39,"tag":67,"props":1376,"children":1377},{"class":69,"line":158},[1378],{"type":39,"tag":67,"props":1379,"children":1380},{},[1381],{"type":45,"value":1382},"list = teams.list\n",{"type":39,"tag":67,"props":1384,"children":1385},{"class":69,"line":167},[1386],{"type":39,"tag":67,"props":1387,"children":1388},{"emptyLinePlaceholder":117},[1389],{"type":45,"value":120},{"type":39,"tag":67,"props":1391,"children":1392},{"class":69,"line":257},[1393],{"type":39,"tag":67,"props":1394,"children":1395},{},[1396],{"type":45,"value":1397},"# Create membership (invite user by email)\n",{"type":39,"tag":67,"props":1399,"children":1400},{"class":69,"line":266},[1401],{"type":39,"tag":67,"props":1402,"children":1403},{},[1404],{"type":45,"value":1405},"membership = teams.create_membership(\n",{"type":39,"tag":67,"props":1407,"children":1408},{"class":69,"line":275},[1409],{"type":39,"tag":67,"props":1410,"children":1411},{},[1412],{"type":45,"value":1413},"    team_id: '[TEAM_ID]',\n",{"type":39,"tag":67,"props":1415,"children":1416},{"class":69,"line":283},[1417],{"type":39,"tag":67,"props":1418,"children":1419},{},[1420],{"type":45,"value":1421},"    roles: ['editor'],\n",{"type":39,"tag":67,"props":1423,"children":1424},{"class":69,"line":292},[1425],{"type":39,"tag":67,"props":1426,"children":1427},{},[1428],{"type":45,"value":1429},"    email: 'user@example.com'\n",{"type":39,"tag":67,"props":1431,"children":1432},{"class":69,"line":472},[1433],{"type":39,"tag":67,"props":1434,"children":1435},{},[1436],{"type":45,"value":462},{"type":39,"tag":67,"props":1438,"children":1439},{"class":69,"line":481},[1440],{"type":39,"tag":67,"props":1441,"children":1442},{"emptyLinePlaceholder":117},[1443],{"type":45,"value":120},{"type":39,"tag":67,"props":1445,"children":1446},{"class":69,"line":490},[1447],{"type":39,"tag":67,"props":1448,"children":1449},{},[1450],{"type":45,"value":1451},"# List memberships\n",{"type":39,"tag":67,"props":1453,"children":1454},{"class":69,"line":498},[1455],{"type":39,"tag":67,"props":1456,"children":1457},{},[1458],{"type":45,"value":1459},"members = teams.list_memberships(team_id: '[TEAM_ID]')\n",{"type":39,"tag":67,"props":1461,"children":1462},{"class":69,"line":506},[1463],{"type":39,"tag":67,"props":1464,"children":1465},{"emptyLinePlaceholder":117},[1466],{"type":45,"value":120},{"type":39,"tag":67,"props":1468,"children":1469},{"class":69,"line":515},[1470],{"type":39,"tag":67,"props":1471,"children":1472},{},[1473],{"type":45,"value":1474},"# Update membership roles\n",{"type":39,"tag":67,"props":1476,"children":1477},{"class":69,"line":523},[1478],{"type":39,"tag":67,"props":1479,"children":1480},{},[1481],{"type":45,"value":1482},"teams.update_membership(team_id: '[TEAM_ID]', membership_id: '[MEMBERSHIP_ID]', roles: ['admin'])\n",{"type":39,"tag":67,"props":1484,"children":1485},{"class":69,"line":531},[1486],{"type":39,"tag":67,"props":1487,"children":1488},{"emptyLinePlaceholder":117},[1489],{"type":45,"value":120},{"type":39,"tag":67,"props":1491,"children":1492},{"class":69,"line":540},[1493],{"type":39,"tag":67,"props":1494,"children":1495},{},[1496],{"type":45,"value":1497},"# Delete team\n",{"type":39,"tag":67,"props":1499,"children":1500},{"class":69,"line":23},[1501],{"type":39,"tag":67,"props":1502,"children":1503},{},[1504],{"type":45,"value":1505},"teams.delete(team_id: '[TEAM_ID]')\n",{"type":39,"tag":306,"props":1507,"children":1508},{},[1509],{"type":39,"tag":310,"props":1510,"children":1511},{},[1512,1517,1518,1524,1526,1532],{"type":39,"tag":314,"props":1513,"children":1514},{},[1515],{"type":45,"value":1516},"Role-based access:",{"type":45,"value":320},{"type":39,"tag":63,"props":1519,"children":1521},{"className":1520},[],[1522],{"type":45,"value":1523},"Role.team('[TEAM_ID]')",{"type":45,"value":1525}," for all team members or ",{"type":39,"tag":63,"props":1527,"children":1529},{"className":1528},[],[1530],{"type":45,"value":1531},"Role.team('[TEAM_ID]', 'editor')",{"type":45,"value":1533}," for a specific team role when setting permissions.",{"type":39,"tag":181,"props":1535,"children":1537},{"id":1536},"serverless-functions",[1538],{"type":45,"value":1539},"Serverless Functions",{"type":39,"tag":55,"props":1541,"children":1543},{"className":97,"code":1542,"language":22,"meta":60,"style":60},"functions = Functions.new(client)\n\n# Execute function\nexecution = functions.create_execution(function_id: '[FUNCTION_ID]', body: '{\"key\": \"value\"}')\n\n# List executions\nexecutions = functions.list_executions(function_id: '[FUNCTION_ID]')\n",[1544],{"type":39,"tag":63,"props":1545,"children":1546},{"__ignoreMap":60},[1547,1555,1562,1570,1578,1585,1593],{"type":39,"tag":67,"props":1548,"children":1549},{"class":69,"line":70},[1550],{"type":39,"tag":67,"props":1551,"children":1552},{},[1553],{"type":45,"value":1554},"functions = Functions.new(client)\n",{"type":39,"tag":67,"props":1556,"children":1557},{"class":69,"line":113},[1558],{"type":39,"tag":67,"props":1559,"children":1560},{"emptyLinePlaceholder":117},[1561],{"type":45,"value":120},{"type":39,"tag":67,"props":1563,"children":1564},{"class":69,"line":123},[1565],{"type":39,"tag":67,"props":1566,"children":1567},{},[1568],{"type":45,"value":1569},"# Execute function\n",{"type":39,"tag":67,"props":1571,"children":1572},{"class":69,"line":132},[1573],{"type":39,"tag":67,"props":1574,"children":1575},{},[1576],{"type":45,"value":1577},"execution = functions.create_execution(function_id: '[FUNCTION_ID]', body: '{\"key\": \"value\"}')\n",{"type":39,"tag":67,"props":1579,"children":1580},{"class":69,"line":140},[1581],{"type":39,"tag":67,"props":1582,"children":1583},{"emptyLinePlaceholder":117},[1584],{"type":45,"value":120},{"type":39,"tag":67,"props":1586,"children":1587},{"class":69,"line":149},[1588],{"type":39,"tag":67,"props":1589,"children":1590},{},[1591],{"type":45,"value":1592},"# List executions\n",{"type":39,"tag":67,"props":1594,"children":1595},{"class":69,"line":158},[1596],{"type":39,"tag":67,"props":1597,"children":1598},{},[1599],{"type":45,"value":1600},"executions = functions.list_executions(function_id: '[FUNCTION_ID]')\n",{"type":39,"tag":641,"props":1602,"children":1604},{"id":1603},"writing-a-function-handler-ruby-runtime",[1605],{"type":45,"value":1606},"Writing a Function Handler (Ruby runtime)",{"type":39,"tag":55,"props":1608,"children":1610},{"className":97,"code":1609,"language":22,"meta":60,"style":60},"# src\u002Fmain.rb — Appwrite Function entry point\ndef main(context)\n    # context.req.body         — raw body (String)\n    # context.req.body_json    — parsed JSON (Hash or nil)\n    # context.req.headers      — headers (Hash)\n    # context.req.method       — HTTP method\n    # context.req.path         — URL path\n    # context.req.query        — query params (Hash)\n\n    context.log(\"Processing: #{context.req.method} #{context.req.path}\")\n\n    if context.req.method == 'GET'\n        return context.res.json({ message: 'Hello from Appwrite Function!' })\n    end\n\n    context.res.json({ success: true })          # JSON\n    # context.res.text('Hello')                  # plain text\n    # context.res.empty                          # 204\n    # context.res.redirect('https:\u002F\u002F...')         # 302\nend\n",[1611],{"type":39,"tag":63,"props":1612,"children":1613},{"__ignoreMap":60},[1614,1622,1630,1638,1646,1654,1662,1670,1678,1685,1693,1700,1708,1716,1724,1731,1739,1747,1755,1763],{"type":39,"tag":67,"props":1615,"children":1616},{"class":69,"line":70},[1617],{"type":39,"tag":67,"props":1618,"children":1619},{},[1620],{"type":45,"value":1621},"# src\u002Fmain.rb — Appwrite Function entry point\n",{"type":39,"tag":67,"props":1623,"children":1624},{"class":69,"line":113},[1625],{"type":39,"tag":67,"props":1626,"children":1627},{},[1628],{"type":45,"value":1629},"def main(context)\n",{"type":39,"tag":67,"props":1631,"children":1632},{"class":69,"line":123},[1633],{"type":39,"tag":67,"props":1634,"children":1635},{},[1636],{"type":45,"value":1637},"    # context.req.body         — raw body (String)\n",{"type":39,"tag":67,"props":1639,"children":1640},{"class":69,"line":132},[1641],{"type":39,"tag":67,"props":1642,"children":1643},{},[1644],{"type":45,"value":1645},"    # context.req.body_json    — parsed JSON (Hash or nil)\n",{"type":39,"tag":67,"props":1647,"children":1648},{"class":69,"line":140},[1649],{"type":39,"tag":67,"props":1650,"children":1651},{},[1652],{"type":45,"value":1653},"    # context.req.headers      — headers (Hash)\n",{"type":39,"tag":67,"props":1655,"children":1656},{"class":69,"line":149},[1657],{"type":39,"tag":67,"props":1658,"children":1659},{},[1660],{"type":45,"value":1661},"    # context.req.method       — HTTP method\n",{"type":39,"tag":67,"props":1663,"children":1664},{"class":69,"line":158},[1665],{"type":39,"tag":67,"props":1666,"children":1667},{},[1668],{"type":45,"value":1669},"    # context.req.path         — URL path\n",{"type":39,"tag":67,"props":1671,"children":1672},{"class":69,"line":167},[1673],{"type":39,"tag":67,"props":1674,"children":1675},{},[1676],{"type":45,"value":1677},"    # context.req.query        — query params (Hash)\n",{"type":39,"tag":67,"props":1679,"children":1680},{"class":69,"line":257},[1681],{"type":39,"tag":67,"props":1682,"children":1683},{"emptyLinePlaceholder":117},[1684],{"type":45,"value":120},{"type":39,"tag":67,"props":1686,"children":1687},{"class":69,"line":266},[1688],{"type":39,"tag":67,"props":1689,"children":1690},{},[1691],{"type":45,"value":1692},"    context.log(\"Processing: #{context.req.method} #{context.req.path}\")\n",{"type":39,"tag":67,"props":1694,"children":1695},{"class":69,"line":275},[1696],{"type":39,"tag":67,"props":1697,"children":1698},{"emptyLinePlaceholder":117},[1699],{"type":45,"value":120},{"type":39,"tag":67,"props":1701,"children":1702},{"class":69,"line":283},[1703],{"type":39,"tag":67,"props":1704,"children":1705},{},[1706],{"type":45,"value":1707},"    if context.req.method == 'GET'\n",{"type":39,"tag":67,"props":1709,"children":1710},{"class":69,"line":292},[1711],{"type":39,"tag":67,"props":1712,"children":1713},{},[1714],{"type":45,"value":1715},"        return context.res.json({ message: 'Hello from Appwrite Function!' })\n",{"type":39,"tag":67,"props":1717,"children":1718},{"class":69,"line":472},[1719],{"type":39,"tag":67,"props":1720,"children":1721},{},[1722],{"type":45,"value":1723},"    end\n",{"type":39,"tag":67,"props":1725,"children":1726},{"class":69,"line":481},[1727],{"type":39,"tag":67,"props":1728,"children":1729},{"emptyLinePlaceholder":117},[1730],{"type":45,"value":120},{"type":39,"tag":67,"props":1732,"children":1733},{"class":69,"line":490},[1734],{"type":39,"tag":67,"props":1735,"children":1736},{},[1737],{"type":45,"value":1738},"    context.res.json({ success: true })          # JSON\n",{"type":39,"tag":67,"props":1740,"children":1741},{"class":69,"line":498},[1742],{"type":39,"tag":67,"props":1743,"children":1744},{},[1745],{"type":45,"value":1746},"    # context.res.text('Hello')                  # plain text\n",{"type":39,"tag":67,"props":1748,"children":1749},{"class":69,"line":506},[1750],{"type":39,"tag":67,"props":1751,"children":1752},{},[1753],{"type":45,"value":1754},"    # context.res.empty                          # 204\n",{"type":39,"tag":67,"props":1756,"children":1757},{"class":69,"line":515},[1758],{"type":39,"tag":67,"props":1759,"children":1760},{},[1761],{"type":45,"value":1762},"    # context.res.redirect('https:\u002F\u002F...')         # 302\n",{"type":39,"tag":67,"props":1764,"children":1765},{"class":69,"line":523},[1766],{"type":39,"tag":67,"props":1767,"children":1768},{},[1769],{"type":45,"value":1770},"end\n",{"type":39,"tag":181,"props":1772,"children":1774},{"id":1773},"server-side-rendering-ssr-authentication",[1775],{"type":45,"value":1776},"Server-Side Rendering (SSR) Authentication",{"type":39,"tag":310,"props":1778,"children":1779},{},[1780,1782,1787],{"type":45,"value":1781},"SSR apps using Ruby frameworks (Rails, Sinatra, etc.) use the ",{"type":39,"tag":314,"props":1783,"children":1784},{},[1785],{"type":45,"value":1786},"server SDK",{"type":45,"value":1788}," to handle auth. You need two clients:",{"type":39,"tag":808,"props":1790,"children":1791},{},[1792,1802],{"type":39,"tag":812,"props":1793,"children":1794},{},[1795,1800],{"type":39,"tag":314,"props":1796,"children":1797},{},[1798],{"type":45,"value":1799},"Admin client",{"type":45,"value":1801}," — uses an API key, creates sessions, bypasses rate limits (reusable singleton)",{"type":39,"tag":812,"props":1803,"children":1804},{},[1805,1810],{"type":39,"tag":314,"props":1806,"children":1807},{},[1808],{"type":45,"value":1809},"Session client",{"type":45,"value":1811}," — uses a session cookie, acts on behalf of a user (create per-request, never share)",{"type":39,"tag":55,"props":1813,"children":1815},{"className":97,"code":1814,"language":22,"meta":60,"style":60},"require 'appwrite'\ninclude Appwrite\n\n# Admin client (reusable)\nadmin_client = Client.new\n    .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n    .set_project('[PROJECT_ID]')\n    .set_key(ENV['APPWRITE_API_KEY'])\n\n# Session client (create per-request)\nsession_client = Client.new\n    .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n    .set_project('[PROJECT_ID]')\n\nsession = cookies['a_session_[PROJECT_ID]']\nsession_client.set_session(session) if session\n",[1816],{"type":39,"tag":63,"props":1817,"children":1818},{"__ignoreMap":60},[1819,1826,1833,1840,1848,1856,1863,1871,1878,1885,1893,1901,1908,1915,1922,1930],{"type":39,"tag":67,"props":1820,"children":1821},{"class":69,"line":70},[1822],{"type":39,"tag":67,"props":1823,"children":1824},{},[1825],{"type":45,"value":110},{"type":39,"tag":67,"props":1827,"children":1828},{"class":69,"line":113},[1829],{"type":39,"tag":67,"props":1830,"children":1831},{},[1832],{"type":45,"value":129},{"type":39,"tag":67,"props":1834,"children":1835},{"class":69,"line":123},[1836],{"type":39,"tag":67,"props":1837,"children":1838},{"emptyLinePlaceholder":117},[1839],{"type":45,"value":120},{"type":39,"tag":67,"props":1841,"children":1842},{"class":69,"line":132},[1843],{"type":39,"tag":67,"props":1844,"children":1845},{},[1846],{"type":45,"value":1847},"# Admin client (reusable)\n",{"type":39,"tag":67,"props":1849,"children":1850},{"class":69,"line":140},[1851],{"type":39,"tag":67,"props":1852,"children":1853},{},[1854],{"type":45,"value":1855},"admin_client = Client.new\n",{"type":39,"tag":67,"props":1857,"children":1858},{"class":69,"line":149},[1859],{"type":39,"tag":67,"props":1860,"children":1861},{},[1862],{"type":45,"value":155},{"type":39,"tag":67,"props":1864,"children":1865},{"class":69,"line":158},[1866],{"type":39,"tag":67,"props":1867,"children":1868},{},[1869],{"type":45,"value":1870},"    .set_project('[PROJECT_ID]')\n",{"type":39,"tag":67,"props":1872,"children":1873},{"class":69,"line":167},[1874],{"type":39,"tag":67,"props":1875,"children":1876},{},[1877],{"type":45,"value":173},{"type":39,"tag":67,"props":1879,"children":1880},{"class":69,"line":257},[1881],{"type":39,"tag":67,"props":1882,"children":1883},{"emptyLinePlaceholder":117},[1884],{"type":45,"value":120},{"type":39,"tag":67,"props":1886,"children":1887},{"class":69,"line":266},[1888],{"type":39,"tag":67,"props":1889,"children":1890},{},[1891],{"type":45,"value":1892},"# Session client (create per-request)\n",{"type":39,"tag":67,"props":1894,"children":1895},{"class":69,"line":275},[1896],{"type":39,"tag":67,"props":1897,"children":1898},{},[1899],{"type":45,"value":1900},"session_client = Client.new\n",{"type":39,"tag":67,"props":1902,"children":1903},{"class":69,"line":283},[1904],{"type":39,"tag":67,"props":1905,"children":1906},{},[1907],{"type":45,"value":155},{"type":39,"tag":67,"props":1909,"children":1910},{"class":69,"line":292},[1911],{"type":39,"tag":67,"props":1912,"children":1913},{},[1914],{"type":45,"value":1870},{"type":39,"tag":67,"props":1916,"children":1917},{"class":69,"line":472},[1918],{"type":39,"tag":67,"props":1919,"children":1920},{"emptyLinePlaceholder":117},[1921],{"type":45,"value":120},{"type":39,"tag":67,"props":1923,"children":1924},{"class":69,"line":481},[1925],{"type":39,"tag":67,"props":1926,"children":1927},{},[1928],{"type":45,"value":1929},"session = cookies['a_session_[PROJECT_ID]']\n",{"type":39,"tag":67,"props":1931,"children":1932},{"class":69,"line":490},[1933],{"type":39,"tag":67,"props":1934,"children":1935},{},[1936],{"type":45,"value":1937},"session_client.set_session(session) if session\n",{"type":39,"tag":641,"props":1939,"children":1941},{"id":1940},"emailpassword-login-sinatra",[1942],{"type":45,"value":1943},"Email\u002FPassword Login (Sinatra)",{"type":39,"tag":55,"props":1945,"children":1947},{"className":97,"code":1946,"language":22,"meta":60,"style":60},"post '\u002Flogin' do\n    account = Account.new(admin_client)\n    session = account.create_email_password_session(\n        email: params[:email],\n        password: params[:password]\n    )\n\n    # Cookie name must be a_session_\u003CPROJECT_ID>\n    response.set_cookie('a_session_[PROJECT_ID]', {\n        value: session.secret,\n        httponly: true,\n        secure: true,\n        same_site: :strict,\n        path: '\u002F',\n    })\n\n    content_type :json\n    { success: true }.to_json\nend\n",[1948],{"type":39,"tag":63,"props":1949,"children":1950},{"__ignoreMap":60},[1951,1959,1967,1975,1983,1991,1999,2006,2014,2022,2030,2038,2046,2054,2062,2070,2077,2085,2093],{"type":39,"tag":67,"props":1952,"children":1953},{"class":69,"line":70},[1954],{"type":39,"tag":67,"props":1955,"children":1956},{},[1957],{"type":45,"value":1958},"post '\u002Flogin' do\n",{"type":39,"tag":67,"props":1960,"children":1961},{"class":69,"line":113},[1962],{"type":39,"tag":67,"props":1963,"children":1964},{},[1965],{"type":45,"value":1966},"    account = Account.new(admin_client)\n",{"type":39,"tag":67,"props":1968,"children":1969},{"class":69,"line":123},[1970],{"type":39,"tag":67,"props":1971,"children":1972},{},[1973],{"type":45,"value":1974},"    session = account.create_email_password_session(\n",{"type":39,"tag":67,"props":1976,"children":1977},{"class":69,"line":132},[1978],{"type":39,"tag":67,"props":1979,"children":1980},{},[1981],{"type":45,"value":1982},"        email: params[:email],\n",{"type":39,"tag":67,"props":1984,"children":1985},{"class":69,"line":140},[1986],{"type":39,"tag":67,"props":1987,"children":1988},{},[1989],{"type":45,"value":1990},"        password: params[:password]\n",{"type":39,"tag":67,"props":1992,"children":1993},{"class":69,"line":149},[1994],{"type":39,"tag":67,"props":1995,"children":1996},{},[1997],{"type":45,"value":1998},"    )\n",{"type":39,"tag":67,"props":2000,"children":2001},{"class":69,"line":158},[2002],{"type":39,"tag":67,"props":2003,"children":2004},{"emptyLinePlaceholder":117},[2005],{"type":45,"value":120},{"type":39,"tag":67,"props":2007,"children":2008},{"class":69,"line":167},[2009],{"type":39,"tag":67,"props":2010,"children":2011},{},[2012],{"type":45,"value":2013},"    # Cookie name must be a_session_\u003CPROJECT_ID>\n",{"type":39,"tag":67,"props":2015,"children":2016},{"class":69,"line":257},[2017],{"type":39,"tag":67,"props":2018,"children":2019},{},[2020],{"type":45,"value":2021},"    response.set_cookie('a_session_[PROJECT_ID]', {\n",{"type":39,"tag":67,"props":2023,"children":2024},{"class":69,"line":266},[2025],{"type":39,"tag":67,"props":2026,"children":2027},{},[2028],{"type":45,"value":2029},"        value: session.secret,\n",{"type":39,"tag":67,"props":2031,"children":2032},{"class":69,"line":275},[2033],{"type":39,"tag":67,"props":2034,"children":2035},{},[2036],{"type":45,"value":2037},"        httponly: true,\n",{"type":39,"tag":67,"props":2039,"children":2040},{"class":69,"line":283},[2041],{"type":39,"tag":67,"props":2042,"children":2043},{},[2044],{"type":45,"value":2045},"        secure: true,\n",{"type":39,"tag":67,"props":2047,"children":2048},{"class":69,"line":292},[2049],{"type":39,"tag":67,"props":2050,"children":2051},{},[2052],{"type":45,"value":2053},"        same_site: :strict,\n",{"type":39,"tag":67,"props":2055,"children":2056},{"class":69,"line":472},[2057],{"type":39,"tag":67,"props":2058,"children":2059},{},[2060],{"type":45,"value":2061},"        path: '\u002F',\n",{"type":39,"tag":67,"props":2063,"children":2064},{"class":69,"line":481},[2065],{"type":39,"tag":67,"props":2066,"children":2067},{},[2068],{"type":45,"value":2069},"    })\n",{"type":39,"tag":67,"props":2071,"children":2072},{"class":69,"line":490},[2073],{"type":39,"tag":67,"props":2074,"children":2075},{"emptyLinePlaceholder":117},[2076],{"type":45,"value":120},{"type":39,"tag":67,"props":2078,"children":2079},{"class":69,"line":498},[2080],{"type":39,"tag":67,"props":2081,"children":2082},{},[2083],{"type":45,"value":2084},"    content_type :json\n",{"type":39,"tag":67,"props":2086,"children":2087},{"class":69,"line":506},[2088],{"type":39,"tag":67,"props":2089,"children":2090},{},[2091],{"type":45,"value":2092},"    { success: true }.to_json\n",{"type":39,"tag":67,"props":2094,"children":2095},{"class":69,"line":515},[2096],{"type":39,"tag":67,"props":2097,"children":2098},{},[2099],{"type":45,"value":1770},{"type":39,"tag":641,"props":2101,"children":2103},{"id":2102},"authenticated-requests",[2104],{"type":45,"value":2105},"Authenticated Requests",{"type":39,"tag":55,"props":2107,"children":2109},{"className":97,"code":2108,"language":22,"meta":60,"style":60},"get '\u002Fuser' do\n    session = request.cookies['a_session_[PROJECT_ID]']\n    halt 401, { error: 'Unauthorized' }.to_json unless session\n\n    session_client = Client.new\n        .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n        .set_project('[PROJECT_ID]')\n        .set_session(session)\n\n    account = Account.new(session_client)\n    user = account.get\n\n    content_type :json\n    user.to_json\nend\n",[2110],{"type":39,"tag":63,"props":2111,"children":2112},{"__ignoreMap":60},[2113,2121,2129,2137,2144,2152,2160,2168,2176,2183,2191,2199,2206,2213,2221],{"type":39,"tag":67,"props":2114,"children":2115},{"class":69,"line":70},[2116],{"type":39,"tag":67,"props":2117,"children":2118},{},[2119],{"type":45,"value":2120},"get '\u002Fuser' do\n",{"type":39,"tag":67,"props":2122,"children":2123},{"class":69,"line":113},[2124],{"type":39,"tag":67,"props":2125,"children":2126},{},[2127],{"type":45,"value":2128},"    session = request.cookies['a_session_[PROJECT_ID]']\n",{"type":39,"tag":67,"props":2130,"children":2131},{"class":69,"line":123},[2132],{"type":39,"tag":67,"props":2133,"children":2134},{},[2135],{"type":45,"value":2136},"    halt 401, { error: 'Unauthorized' }.to_json unless session\n",{"type":39,"tag":67,"props":2138,"children":2139},{"class":69,"line":132},[2140],{"type":39,"tag":67,"props":2141,"children":2142},{"emptyLinePlaceholder":117},[2143],{"type":45,"value":120},{"type":39,"tag":67,"props":2145,"children":2146},{"class":69,"line":140},[2147],{"type":39,"tag":67,"props":2148,"children":2149},{},[2150],{"type":45,"value":2151},"    session_client = Client.new\n",{"type":39,"tag":67,"props":2153,"children":2154},{"class":69,"line":149},[2155],{"type":39,"tag":67,"props":2156,"children":2157},{},[2158],{"type":45,"value":2159},"        .set_endpoint('https:\u002F\u002F\u003CREGION>.cloud.appwrite.io\u002Fv1')\n",{"type":39,"tag":67,"props":2161,"children":2162},{"class":69,"line":158},[2163],{"type":39,"tag":67,"props":2164,"children":2165},{},[2166],{"type":45,"value":2167},"        .set_project('[PROJECT_ID]')\n",{"type":39,"tag":67,"props":2169,"children":2170},{"class":69,"line":167},[2171],{"type":39,"tag":67,"props":2172,"children":2173},{},[2174],{"type":45,"value":2175},"        .set_session(session)\n",{"type":39,"tag":67,"props":2177,"children":2178},{"class":69,"line":257},[2179],{"type":39,"tag":67,"props":2180,"children":2181},{"emptyLinePlaceholder":117},[2182],{"type":45,"value":120},{"type":39,"tag":67,"props":2184,"children":2185},{"class":69,"line":266},[2186],{"type":39,"tag":67,"props":2187,"children":2188},{},[2189],{"type":45,"value":2190},"    account = Account.new(session_client)\n",{"type":39,"tag":67,"props":2192,"children":2193},{"class":69,"line":275},[2194],{"type":39,"tag":67,"props":2195,"children":2196},{},[2197],{"type":45,"value":2198},"    user = account.get\n",{"type":39,"tag":67,"props":2200,"children":2201},{"class":69,"line":283},[2202],{"type":39,"tag":67,"props":2203,"children":2204},{"emptyLinePlaceholder":117},[2205],{"type":45,"value":120},{"type":39,"tag":67,"props":2207,"children":2208},{"class":69,"line":292},[2209],{"type":39,"tag":67,"props":2210,"children":2211},{},[2212],{"type":45,"value":2084},{"type":39,"tag":67,"props":2214,"children":2215},{"class":69,"line":472},[2216],{"type":39,"tag":67,"props":2217,"children":2218},{},[2219],{"type":45,"value":2220},"    user.to_json\n",{"type":39,"tag":67,"props":2222,"children":2223},{"class":69,"line":481},[2224],{"type":39,"tag":67,"props":2225,"children":2226},{},[2227],{"type":45,"value":1770},{"type":39,"tag":641,"props":2229,"children":2231},{"id":2230},"oauth2-ssr-flow",[2232],{"type":45,"value":2233},"OAuth2 SSR Flow",{"type":39,"tag":55,"props":2235,"children":2237},{"className":97,"code":2236,"language":22,"meta":60,"style":60},"# Step 1: Redirect to OAuth provider\nget '\u002Foauth' do\n    account = Account.new(admin_client)\n    redirect_url = account.create_o_auth2_token(\n        provider: OAuthProvider::GITHUB,\n        success: 'https:\u002F\u002Fexample.com\u002Foauth\u002Fsuccess',\n        failure: 'https:\u002F\u002Fexample.com\u002Foauth\u002Ffailure'\n    )\n    redirect redirect_url\nend\n\n# Step 2: Handle callback — exchange token for session\nget '\u002Foauth\u002Fsuccess' do\n    account = Account.new(admin_client)\n    session = account.create_session(\n        user_id: params[:userId],\n        secret: params[:secret]\n    )\n\n    response.set_cookie('a_session_[PROJECT_ID]', {\n        value: session.secret,\n        httponly: true, secure: true, same_site: :strict, path: '\u002F',\n    })\n\n    content_type :json\n    { success: true }.to_json\nend\n",[2238],{"type":39,"tag":63,"props":2239,"children":2240},{"__ignoreMap":60},[2241,2249,2257,2264,2272,2280,2288,2296,2303,2311,2318,2325,2333,2341,2348,2356,2364,2372,2379,2386,2393,2400,2408,2415,2422,2429,2436],{"type":39,"tag":67,"props":2242,"children":2243},{"class":69,"line":70},[2244],{"type":39,"tag":67,"props":2245,"children":2246},{},[2247],{"type":45,"value":2248},"# Step 1: Redirect to OAuth provider\n",{"type":39,"tag":67,"props":2250,"children":2251},{"class":69,"line":113},[2252],{"type":39,"tag":67,"props":2253,"children":2254},{},[2255],{"type":45,"value":2256},"get '\u002Foauth' do\n",{"type":39,"tag":67,"props":2258,"children":2259},{"class":69,"line":123},[2260],{"type":39,"tag":67,"props":2261,"children":2262},{},[2263],{"type":45,"value":1966},{"type":39,"tag":67,"props":2265,"children":2266},{"class":69,"line":132},[2267],{"type":39,"tag":67,"props":2268,"children":2269},{},[2270],{"type":45,"value":2271},"    redirect_url = account.create_o_auth2_token(\n",{"type":39,"tag":67,"props":2273,"children":2274},{"class":69,"line":140},[2275],{"type":39,"tag":67,"props":2276,"children":2277},{},[2278],{"type":45,"value":2279},"        provider: OAuthProvider::GITHUB,\n",{"type":39,"tag":67,"props":2281,"children":2282},{"class":69,"line":149},[2283],{"type":39,"tag":67,"props":2284,"children":2285},{},[2286],{"type":45,"value":2287},"        success: 'https:\u002F\u002Fexample.com\u002Foauth\u002Fsuccess',\n",{"type":39,"tag":67,"props":2289,"children":2290},{"class":69,"line":158},[2291],{"type":39,"tag":67,"props":2292,"children":2293},{},[2294],{"type":45,"value":2295},"        failure: 'https:\u002F\u002Fexample.com\u002Foauth\u002Ffailure'\n",{"type":39,"tag":67,"props":2297,"children":2298},{"class":69,"line":167},[2299],{"type":39,"tag":67,"props":2300,"children":2301},{},[2302],{"type":45,"value":1998},{"type":39,"tag":67,"props":2304,"children":2305},{"class":69,"line":257},[2306],{"type":39,"tag":67,"props":2307,"children":2308},{},[2309],{"type":45,"value":2310},"    redirect redirect_url\n",{"type":39,"tag":67,"props":2312,"children":2313},{"class":69,"line":266},[2314],{"type":39,"tag":67,"props":2315,"children":2316},{},[2317],{"type":45,"value":1770},{"type":39,"tag":67,"props":2319,"children":2320},{"class":69,"line":275},[2321],{"type":39,"tag":67,"props":2322,"children":2323},{"emptyLinePlaceholder":117},[2324],{"type":45,"value":120},{"type":39,"tag":67,"props":2326,"children":2327},{"class":69,"line":283},[2328],{"type":39,"tag":67,"props":2329,"children":2330},{},[2331],{"type":45,"value":2332},"# Step 2: Handle callback — exchange token for session\n",{"type":39,"tag":67,"props":2334,"children":2335},{"class":69,"line":292},[2336],{"type":39,"tag":67,"props":2337,"children":2338},{},[2339],{"type":45,"value":2340},"get '\u002Foauth\u002Fsuccess' do\n",{"type":39,"tag":67,"props":2342,"children":2343},{"class":69,"line":472},[2344],{"type":39,"tag":67,"props":2345,"children":2346},{},[2347],{"type":45,"value":1966},{"type":39,"tag":67,"props":2349,"children":2350},{"class":69,"line":481},[2351],{"type":39,"tag":67,"props":2352,"children":2353},{},[2354],{"type":45,"value":2355},"    session = account.create_session(\n",{"type":39,"tag":67,"props":2357,"children":2358},{"class":69,"line":490},[2359],{"type":39,"tag":67,"props":2360,"children":2361},{},[2362],{"type":45,"value":2363},"        user_id: params[:userId],\n",{"type":39,"tag":67,"props":2365,"children":2366},{"class":69,"line":498},[2367],{"type":39,"tag":67,"props":2368,"children":2369},{},[2370],{"type":45,"value":2371},"        secret: params[:secret]\n",{"type":39,"tag":67,"props":2373,"children":2374},{"class":69,"line":506},[2375],{"type":39,"tag":67,"props":2376,"children":2377},{},[2378],{"type":45,"value":1998},{"type":39,"tag":67,"props":2380,"children":2381},{"class":69,"line":515},[2382],{"type":39,"tag":67,"props":2383,"children":2384},{"emptyLinePlaceholder":117},[2385],{"type":45,"value":120},{"type":39,"tag":67,"props":2387,"children":2388},{"class":69,"line":523},[2389],{"type":39,"tag":67,"props":2390,"children":2391},{},[2392],{"type":45,"value":2021},{"type":39,"tag":67,"props":2394,"children":2395},{"class":69,"line":531},[2396],{"type":39,"tag":67,"props":2397,"children":2398},{},[2399],{"type":45,"value":2029},{"type":39,"tag":67,"props":2401,"children":2402},{"class":69,"line":540},[2403],{"type":39,"tag":67,"props":2404,"children":2405},{},[2406],{"type":45,"value":2407},"        httponly: true, secure: true, same_site: :strict, path: '\u002F',\n",{"type":39,"tag":67,"props":2409,"children":2410},{"class":69,"line":23},[2411],{"type":39,"tag":67,"props":2412,"children":2413},{},[2414],{"type":45,"value":2069},{"type":39,"tag":67,"props":2416,"children":2417},{"class":69,"line":556},[2418],{"type":39,"tag":67,"props":2419,"children":2420},{"emptyLinePlaceholder":117},[2421],{"type":45,"value":120},{"type":39,"tag":67,"props":2423,"children":2424},{"class":69,"line":565},[2425],{"type":39,"tag":67,"props":2426,"children":2427},{},[2428],{"type":45,"value":2084},{"type":39,"tag":67,"props":2430,"children":2431},{"class":69,"line":574},[2432],{"type":39,"tag":67,"props":2433,"children":2434},{},[2435],{"type":45,"value":2092},{"type":39,"tag":67,"props":2437,"children":2438},{"class":69,"line":582},[2439],{"type":39,"tag":67,"props":2440,"children":2441},{},[2442],{"type":45,"value":1770},{"type":39,"tag":306,"props":2444,"children":2445},{},[2446],{"type":39,"tag":310,"props":2447,"children":2448},{},[2449,2454,2456,2462,2463,2469,2470,2476,2478,2484],{"type":39,"tag":314,"props":2450,"children":2451},{},[2452],{"type":45,"value":2453},"Cookie security:",{"type":45,"value":2455}," Always use ",{"type":39,"tag":63,"props":2457,"children":2459},{"className":2458},[],[2460],{"type":45,"value":2461},"httponly",{"type":45,"value":831},{"type":39,"tag":63,"props":2464,"children":2466},{"className":2465},[],[2467],{"type":45,"value":2468},"secure",{"type":45,"value":838},{"type":39,"tag":63,"props":2471,"children":2473},{"className":2472},[],[2474],{"type":45,"value":2475},"same_site: :strict",{"type":45,"value":2477}," to prevent XSS. The cookie name must be ",{"type":39,"tag":63,"props":2479,"children":2481},{"className":2480},[],[2482],{"type":45,"value":2483},"a_session_\u003CPROJECT_ID>",{"type":45,"value":2485},".",{"type":39,"tag":306,"props":2487,"children":2488},{},[2489],{"type":39,"tag":310,"props":2490,"children":2491},{},[2492,2497,2499,2505],{"type":39,"tag":314,"props":2493,"children":2494},{},[2495],{"type":45,"value":2496},"Forwarding user agent:",{"type":45,"value":2498}," Call ",{"type":39,"tag":63,"props":2500,"children":2502},{"className":2501},[],[2503],{"type":45,"value":2504},"session_client.set_forwarded_user_agent(request.user_agent)",{"type":45,"value":2506}," to record the end-user's browser info for debugging and security.",{"type":39,"tag":48,"props":2508,"children":2510},{"id":2509},"error-handling",[2511],{"type":45,"value":2512},"Error Handling",{"type":39,"tag":55,"props":2514,"children":2516},{"className":97,"code":2515,"language":22,"meta":60,"style":60},"require 'appwrite'\ninclude Appwrite\n\nbegin\n    row = tables_db.get_row(database_id: '[DATABASE_ID]', table_id: '[TABLE_ID]', row_id: '[ROW_ID]')\nrescue Appwrite::Exception => e\n    puts e.message    # human-readable message\n    puts e.code       # HTTP status code (Integer)\n    puts e.type       # error type (e.g. 'document_not_found')\n    puts e.response   # full response body (Hash)\nend\n",[2517],{"type":39,"tag":63,"props":2518,"children":2519},{"__ignoreMap":60},[2520,2527,2534,2541,2549,2557,2565,2573,2581,2589,2597],{"type":39,"tag":67,"props":2521,"children":2522},{"class":69,"line":70},[2523],{"type":39,"tag":67,"props":2524,"children":2525},{},[2526],{"type":45,"value":110},{"type":39,"tag":67,"props":2528,"children":2529},{"class":69,"line":113},[2530],{"type":39,"tag":67,"props":2531,"children":2532},{},[2533],{"type":45,"value":129},{"type":39,"tag":67,"props":2535,"children":2536},{"class":69,"line":123},[2537],{"type":39,"tag":67,"props":2538,"children":2539},{"emptyLinePlaceholder":117},[2540],{"type":45,"value":120},{"type":39,"tag":67,"props":2542,"children":2543},{"class":69,"line":132},[2544],{"type":39,"tag":67,"props":2545,"children":2546},{},[2547],{"type":45,"value":2548},"begin\n",{"type":39,"tag":67,"props":2550,"children":2551},{"class":69,"line":140},[2552],{"type":39,"tag":67,"props":2553,"children":2554},{},[2555],{"type":45,"value":2556},"    row = tables_db.get_row(database_id: '[DATABASE_ID]', table_id: '[TABLE_ID]', row_id: '[ROW_ID]')\n",{"type":39,"tag":67,"props":2558,"children":2559},{"class":69,"line":149},[2560],{"type":39,"tag":67,"props":2561,"children":2562},{},[2563],{"type":45,"value":2564},"rescue Appwrite::Exception => e\n",{"type":39,"tag":67,"props":2566,"children":2567},{"class":69,"line":158},[2568],{"type":39,"tag":67,"props":2569,"children":2570},{},[2571],{"type":45,"value":2572},"    puts e.message    # human-readable message\n",{"type":39,"tag":67,"props":2574,"children":2575},{"class":69,"line":167},[2576],{"type":39,"tag":67,"props":2577,"children":2578},{},[2579],{"type":45,"value":2580},"    puts e.code       # HTTP status code (Integer)\n",{"type":39,"tag":67,"props":2582,"children":2583},{"class":69,"line":257},[2584],{"type":39,"tag":67,"props":2585,"children":2586},{},[2587],{"type":45,"value":2588},"    puts e.type       # error type (e.g. 'document_not_found')\n",{"type":39,"tag":67,"props":2590,"children":2591},{"class":69,"line":266},[2592],{"type":39,"tag":67,"props":2593,"children":2594},{},[2595],{"type":45,"value":2596},"    puts e.response   # full response body (Hash)\n",{"type":39,"tag":67,"props":2598,"children":2599},{"class":69,"line":275},[2600],{"type":39,"tag":67,"props":2601,"children":2602},{},[2603],{"type":45,"value":1770},{"type":39,"tag":310,"props":2605,"children":2606},{},[2607],{"type":39,"tag":314,"props":2608,"children":2609},{},[2610],{"type":45,"value":2611},"Common error codes:",{"type":39,"tag":668,"props":2613,"children":2614},{},[2615,2631],{"type":39,"tag":672,"props":2616,"children":2617},{},[2618],{"type":39,"tag":676,"props":2619,"children":2620},{},[2621,2626],{"type":39,"tag":680,"props":2622,"children":2623},{},[2624],{"type":45,"value":2625},"Code",{"type":39,"tag":680,"props":2627,"children":2628},{},[2629],{"type":45,"value":2630},"Meaning",{"type":39,"tag":701,"props":2632,"children":2633},{},[2634,2651,2668,2685,2702],{"type":39,"tag":676,"props":2635,"children":2636},{},[2637,2646],{"type":39,"tag":708,"props":2638,"children":2639},{},[2640],{"type":39,"tag":63,"props":2641,"children":2643},{"className":2642},[],[2644],{"type":45,"value":2645},"401",{"type":39,"tag":708,"props":2647,"children":2648},{},[2649],{"type":45,"value":2650},"Unauthorized — missing or invalid session\u002FAPI key",{"type":39,"tag":676,"props":2652,"children":2653},{},[2654,2663],{"type":39,"tag":708,"props":2655,"children":2656},{},[2657],{"type":39,"tag":63,"props":2658,"children":2660},{"className":2659},[],[2661],{"type":45,"value":2662},"403",{"type":39,"tag":708,"props":2664,"children":2665},{},[2666],{"type":45,"value":2667},"Forbidden — insufficient permissions",{"type":39,"tag":676,"props":2669,"children":2670},{},[2671,2680],{"type":39,"tag":708,"props":2672,"children":2673},{},[2674],{"type":39,"tag":63,"props":2675,"children":2677},{"className":2676},[],[2678],{"type":45,"value":2679},"404",{"type":39,"tag":708,"props":2681,"children":2682},{},[2683],{"type":45,"value":2684},"Not found — resource does not exist",{"type":39,"tag":676,"props":2686,"children":2687},{},[2688,2697],{"type":39,"tag":708,"props":2689,"children":2690},{},[2691],{"type":39,"tag":63,"props":2692,"children":2694},{"className":2693},[],[2695],{"type":45,"value":2696},"409",{"type":39,"tag":708,"props":2698,"children":2699},{},[2700],{"type":45,"value":2701},"Conflict — duplicate ID or unique constraint",{"type":39,"tag":676,"props":2703,"children":2704},{},[2705,2714],{"type":39,"tag":708,"props":2706,"children":2707},{},[2708],{"type":39,"tag":63,"props":2709,"children":2711},{"className":2710},[],[2712],{"type":45,"value":2713},"429",{"type":39,"tag":708,"props":2715,"children":2716},{},[2717],{"type":45,"value":2718},"Rate limited — too many requests",{"type":39,"tag":48,"props":2720,"children":2722},{"id":2721},"permissions-roles-critical",[2723],{"type":45,"value":2724},"Permissions & Roles (Critical)",{"type":39,"tag":310,"props":2726,"children":2727},{},[2728,2730,2736,2737,2743,2744,2750,2751,2757,2759,2765,2767,2772,2774,2780,2782,2788],{"type":45,"value":2729},"Appwrite uses permission strings to control access to resources. Each permission pairs an action (",{"type":39,"tag":63,"props":2731,"children":2733},{"className":2732},[],[2734],{"type":45,"value":2735},"read",{"type":45,"value":831},{"type":39,"tag":63,"props":2738,"children":2740},{"className":2739},[],[2741],{"type":45,"value":2742},"update",{"type":45,"value":831},{"type":39,"tag":63,"props":2745,"children":2747},{"className":2746},[],[2748],{"type":45,"value":2749},"delete",{"type":45,"value":831},{"type":39,"tag":63,"props":2752,"children":2754},{"className":2753},[],[2755],{"type":45,"value":2756},"create",{"type":45,"value":2758},", or ",{"type":39,"tag":63,"props":2760,"children":2762},{"className":2761},[],[2763],{"type":45,"value":2764},"write",{"type":45,"value":2766}," which grants create + update + delete) with a role target. By default, ",{"type":39,"tag":314,"props":2768,"children":2769},{},[2770],{"type":45,"value":2771},"no user has access",{"type":45,"value":2773}," unless permissions are explicitly set at the row\u002Ffile level or inherited from the table\u002Fbucket settings. Permissions are arrays of strings built with the ",{"type":39,"tag":63,"props":2775,"children":2777},{"className":2776},[],[2778],{"type":45,"value":2779},"Permission",{"type":45,"value":2781}," and ",{"type":39,"tag":63,"props":2783,"children":2785},{"className":2784},[],[2786],{"type":45,"value":2787},"Role",{"type":45,"value":2789}," helpers.",{"type":39,"tag":55,"props":2791,"children":2793},{"className":97,"code":2792,"language":22,"meta":60,"style":60},"# Permission and Role are included in the main require\nrequire 'appwrite'\ninclude Appwrite\n",[2794],{"type":39,"tag":63,"props":2795,"children":2796},{"__ignoreMap":60},[2797,2805,2812],{"type":39,"tag":67,"props":2798,"children":2799},{"class":69,"line":70},[2800],{"type":39,"tag":67,"props":2801,"children":2802},{},[2803],{"type":45,"value":2804},"# Permission and Role are included in the main require\n",{"type":39,"tag":67,"props":2806,"children":2807},{"class":69,"line":113},[2808],{"type":39,"tag":67,"props":2809,"children":2810},{},[2811],{"type":45,"value":110},{"type":39,"tag":67,"props":2813,"children":2814},{"class":69,"line":123},[2815],{"type":39,"tag":67,"props":2816,"children":2817},{},[2818],{"type":45,"value":129},{"type":39,"tag":181,"props":2820,"children":2822},{"id":2821},"database-row-with-permissions",[2823],{"type":45,"value":2824},"Database Row with Permissions",{"type":39,"tag":55,"props":2826,"children":2828},{"className":97,"code":2827,"language":22,"meta":60,"style":60},"doc = tables_db.create_row(\n    database_id: '[DATABASE_ID]',\n    table_id: '[TABLE_ID]',\n    row_id: ID.unique,\n    data: { title: 'Hello World' },\n    permissions: [\n        Permission.read(Role.user('[USER_ID]')),     # specific user can read\n        Permission.update(Role.user('[USER_ID]')),   # specific user can update\n        Permission.read(Role.team('[TEAM_ID]')),     # all team members can read\n        Permission.read(Role.any),                   # anyone (including guests) can read\n    ]\n)\n",[2829],{"type":39,"tag":63,"props":2830,"children":2831},{"__ignoreMap":60},[2832,2839,2846,2853,2860,2868,2876,2884,2892,2900,2908,2915],{"type":39,"tag":67,"props":2833,"children":2834},{"class":69,"line":70},[2835],{"type":39,"tag":67,"props":2836,"children":2837},{},[2838],{"type":45,"value":422},{"type":39,"tag":67,"props":2840,"children":2841},{"class":69,"line":113},[2842],{"type":39,"tag":67,"props":2843,"children":2844},{},[2845],{"type":45,"value":430},{"type":39,"tag":67,"props":2847,"children":2848},{"class":69,"line":123},[2849],{"type":39,"tag":67,"props":2850,"children":2851},{},[2852],{"type":45,"value":438},{"type":39,"tag":67,"props":2854,"children":2855},{"class":69,"line":132},[2856],{"type":39,"tag":67,"props":2857,"children":2858},{},[2859],{"type":45,"value":446},{"type":39,"tag":67,"props":2861,"children":2862},{"class":69,"line":140},[2863],{"type":39,"tag":67,"props":2864,"children":2865},{},[2866],{"type":45,"value":2867},"    data: { title: 'Hello World' },\n",{"type":39,"tag":67,"props":2869,"children":2870},{"class":69,"line":149},[2871],{"type":39,"tag":67,"props":2872,"children":2873},{},[2874],{"type":45,"value":2875},"    permissions: [\n",{"type":39,"tag":67,"props":2877,"children":2878},{"class":69,"line":158},[2879],{"type":39,"tag":67,"props":2880,"children":2881},{},[2882],{"type":45,"value":2883},"        Permission.read(Role.user('[USER_ID]')),     # specific user can read\n",{"type":39,"tag":67,"props":2885,"children":2886},{"class":69,"line":167},[2887],{"type":39,"tag":67,"props":2888,"children":2889},{},[2890],{"type":45,"value":2891},"        Permission.update(Role.user('[USER_ID]')),   # specific user can update\n",{"type":39,"tag":67,"props":2893,"children":2894},{"class":69,"line":257},[2895],{"type":39,"tag":67,"props":2896,"children":2897},{},[2898],{"type":45,"value":2899},"        Permission.read(Role.team('[TEAM_ID]')),     # all team members can read\n",{"type":39,"tag":67,"props":2901,"children":2902},{"class":69,"line":266},[2903],{"type":39,"tag":67,"props":2904,"children":2905},{},[2906],{"type":45,"value":2907},"        Permission.read(Role.any),                   # anyone (including guests) can read\n",{"type":39,"tag":67,"props":2909,"children":2910},{"class":69,"line":275},[2911],{"type":39,"tag":67,"props":2912,"children":2913},{},[2914],{"type":45,"value":947},{"type":39,"tag":67,"props":2916,"children":2917},{"class":69,"line":283},[2918],{"type":39,"tag":67,"props":2919,"children":2920},{},[2921],{"type":45,"value":462},{"type":39,"tag":181,"props":2923,"children":2925},{"id":2924},"file-upload-with-permissions",[2926],{"type":45,"value":2927},"File Upload with Permissions",{"type":39,"tag":55,"props":2929,"children":2931},{"className":97,"code":2930,"language":22,"meta":60,"style":60},"file = storage.create_file(\n    bucket_id: '[BUCKET_ID]',\n    file_id: ID.unique,\n    file: InputFile.from_path('\u002Fpath\u002Fto\u002Ffile.png'),\n    permissions: [\n        Permission.read(Role.any),\n        Permission.update(Role.user('[USER_ID]')),\n        Permission.delete(Role.user('[USER_ID]')),\n    ]\n)\n",[2932],{"type":39,"tag":63,"props":2933,"children":2934},{"__ignoreMap":60},[2935,2943,2951,2959,2967,2974,2982,2990,2998,3005],{"type":39,"tag":67,"props":2936,"children":2937},{"class":69,"line":70},[2938],{"type":39,"tag":67,"props":2939,"children":2940},{},[2941],{"type":45,"value":2942},"file = storage.create_file(\n",{"type":39,"tag":67,"props":2944,"children":2945},{"class":69,"line":113},[2946],{"type":39,"tag":67,"props":2947,"children":2948},{},[2949],{"type":45,"value":2950},"    bucket_id: '[BUCKET_ID]',\n",{"type":39,"tag":67,"props":2952,"children":2953},{"class":69,"line":123},[2954],{"type":39,"tag":67,"props":2955,"children":2956},{},[2957],{"type":45,"value":2958},"    file_id: ID.unique,\n",{"type":39,"tag":67,"props":2960,"children":2961},{"class":69,"line":132},[2962],{"type":39,"tag":67,"props":2963,"children":2964},{},[2965],{"type":45,"value":2966},"    file: InputFile.from_path('\u002Fpath\u002Fto\u002Ffile.png'),\n",{"type":39,"tag":67,"props":2968,"children":2969},{"class":69,"line":140},[2970],{"type":39,"tag":67,"props":2971,"children":2972},{},[2973],{"type":45,"value":2875},{"type":39,"tag":67,"props":2975,"children":2976},{"class":69,"line":149},[2977],{"type":39,"tag":67,"props":2978,"children":2979},{},[2980],{"type":45,"value":2981},"        Permission.read(Role.any),\n",{"type":39,"tag":67,"props":2983,"children":2984},{"class":69,"line":158},[2985],{"type":39,"tag":67,"props":2986,"children":2987},{},[2988],{"type":45,"value":2989},"        Permission.update(Role.user('[USER_ID]')),\n",{"type":39,"tag":67,"props":2991,"children":2992},{"class":69,"line":167},[2993],{"type":39,"tag":67,"props":2994,"children":2995},{},[2996],{"type":45,"value":2997},"        Permission.delete(Role.user('[USER_ID]')),\n",{"type":39,"tag":67,"props":2999,"children":3000},{"class":69,"line":257},[3001],{"type":39,"tag":67,"props":3002,"children":3003},{},[3004],{"type":45,"value":947},{"type":39,"tag":67,"props":3006,"children":3007},{"class":69,"line":266},[3008],{"type":39,"tag":67,"props":3009,"children":3010},{},[3011],{"type":45,"value":462},{"type":39,"tag":306,"props":3013,"children":3014},{},[3015],{"type":39,"tag":310,"props":3016,"children":3017},{},[3018,3023],{"type":39,"tag":314,"props":3019,"children":3020},{},[3021],{"type":45,"value":3022},"When to set permissions:",{"type":45,"value":3024}," Set row\u002Ffile-level permissions when you need per-resource access control. If all rows in a table share the same rules, configure permissions at the table\u002Fbucket level and leave row permissions empty.",{"type":39,"tag":306,"props":3026,"children":3027},{},[3028,3036],{"type":39,"tag":310,"props":3029,"children":3030},{},[3031],{"type":39,"tag":314,"props":3032,"children":3033},{},[3034],{"type":45,"value":3035},"Common mistakes:",{"type":39,"tag":808,"props":3037,"children":3038},{},[3039,3049,3083],{"type":39,"tag":812,"props":3040,"children":3041},{},[3042,3047],{"type":39,"tag":314,"props":3043,"children":3044},{},[3045],{"type":45,"value":3046},"Forgetting permissions",{"type":45,"value":3048}," — the resource becomes inaccessible to all users (including the creator)",{"type":39,"tag":812,"props":3050,"children":3051},{},[3052,3081],{"type":39,"tag":314,"props":3053,"children":3054},{},[3055,3061,3063,3068,3070,3075,3076],{"type":39,"tag":63,"props":3056,"children":3058},{"className":3057},[],[3059],{"type":45,"value":3060},"Role.any",{"type":45,"value":3062}," with ",{"type":39,"tag":63,"props":3064,"children":3066},{"className":3065},[],[3067],{"type":45,"value":2764},{"type":45,"value":3069},"\u002F",{"type":39,"tag":63,"props":3071,"children":3073},{"className":3072},[],[3074],{"type":45,"value":2742},{"type":45,"value":3069},{"type":39,"tag":63,"props":3077,"children":3079},{"className":3078},[],[3080],{"type":45,"value":2749},{"type":45,"value":3082}," — allows any user, including unauthenticated guests, to modify or remove the resource",{"type":39,"tag":812,"props":3084,"children":3085},{},[3086,3097],{"type":39,"tag":314,"props":3087,"children":3088},{},[3089,3095],{"type":39,"tag":63,"props":3090,"children":3092},{"className":3091},[],[3093],{"type":45,"value":3094},"Permission.read(Role.any)",{"type":45,"value":3096}," on sensitive data",{"type":45,"value":3098}," — makes the resource publicly readable",{"type":39,"tag":3100,"props":3101,"children":3102},"style",{},[3103],{"type":45,"value":3104},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":3106,"total":275},[3107,3122,3140,3157,3171,3190,3204],{"slug":3108,"name":3108,"fn":3109,"description":3110,"org":3111,"tags":3112,"stars":23,"repoUrl":24,"updatedAt":3121},"appwrite-cli","manage Appwrite projects via CLI","Appwrite CLI skill. Use when managing Appwrite projects from the command line. Covers installation, login, project initialization, multi-file project configuration, deploying functions\u002Fsites\u002Ftables\u002Fbuckets\u002Fteams\u002Fwebhooks\u002Ftopics, flag-based list queries, non-interactive CI\u002FCD mode, and generating type-safe SDKs.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3113,3114,3115,3118],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3116,"slug":3117,"type":15},"CLI","cli",{"name":3119,"slug":3120,"type":15},"Deployment","deployment","2026-07-12T08:45:23.213081",{"slug":3123,"name":3123,"fn":3124,"description":3125,"org":3126,"tags":3127,"stars":23,"repoUrl":24,"updatedAt":3139},"appwrite-dart","build applications with Appwrite Dart SDK","Appwrite Dart SDK skill. Use when building Flutter apps (mobile, web, desktop) or server-side Dart applications with Appwrite. Covers client-side auth (email, OAuth), database queries, file uploads with native file handling, real-time subscriptions, and server-side admin via API keys for user management, database administration, storage, and functions.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3128,3129,3130,3133,3136],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3131,"slug":3132,"type":15},"Dart","dart",{"name":3134,"slug":3135,"type":15},"Flutter","flutter",{"name":3137,"slug":3138,"type":15},"Mobile","mobile","2026-07-12T08:45:33.336948",{"slug":3141,"name":3141,"fn":3142,"description":3143,"org":3144,"tags":3145,"stars":23,"repoUrl":24,"updatedAt":3156},"appwrite-dotnet","build .NET applications with Appwrite SDK","Appwrite .NET SDK skill. Use when building server-side C# or .NET applications with Appwrite, including ASP.NET and Blazor integrations. Covers user management, database\u002Ftable CRUD, file storage, and functions via API keys.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3146,3149,3150,3151,3154],{"name":3147,"slug":3148,"type":15},".NET","net",{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},"Database","database",{"name":699,"slug":3155,"type":15},"storage","2026-07-12T08:45:28.556413",{"slug":3158,"name":3158,"fn":3159,"description":3160,"org":3161,"tags":3162,"stars":23,"repoUrl":24,"updatedAt":3170},"appwrite-go","build Go applications with Appwrite SDK","Appwrite Go SDK skill. Use when building server-side Go applications with Appwrite. Covers user management, database\u002Ftable CRUD, file storage, and functions via API keys. Uses per-service packages and functional options pattern.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3163,3164,3165,3166,3169],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3167,"slug":3168,"type":15},"Go","go",{"name":699,"slug":3155,"type":15},"2026-07-12T08:45:19.875231",{"slug":3172,"name":3172,"fn":3173,"description":3174,"org":3175,"tags":3176,"stars":23,"repoUrl":24,"updatedAt":3189},"appwrite-kotlin","build applications with Appwrite Kotlin SDK","Appwrite Kotlin SDK skill. Use when building native Android apps or server-side Kotlin\u002FJVM backends with Appwrite. Covers client-side auth (email, OAuth with Activity integration), database queries, file uploads, real-time subscriptions with coroutine support, and server-side admin via API keys for user management, database administration, storage, and functions.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3177,3180,3181,3184,3185,3186],{"name":3178,"slug":3179,"type":15},"Android","android",{"name":9,"slug":8,"type":15},{"name":3182,"slug":3183,"type":15},"Auth","auth",{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3187,"slug":3188,"type":15},"Kotlin","kotlin","2026-07-12T08:45:40.750646",{"slug":3191,"name":3191,"fn":3192,"description":3193,"org":3194,"tags":3195,"stars":23,"repoUrl":24,"updatedAt":3203},"appwrite-php","build PHP applications with Appwrite","Appwrite PHP SDK skill. Use when building server-side PHP applications with Appwrite, including Laravel and Symfony integrations. Covers user management, database\u002Ftable CRUD, file storage, and functions via API keys.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3196,3197,3198,3199,3202],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3200,"slug":3201,"type":15},"PHP","php",{"name":699,"slug":3155,"type":15},"2026-07-12T08:45:21.794433",{"slug":3205,"name":3205,"fn":3206,"description":3207,"org":3208,"tags":3209,"stars":23,"repoUrl":24,"updatedAt":3217},"appwrite-python","build Python applications with Appwrite","Appwrite Python SDK skill. Use when building server-side Python applications with Appwrite, including Django, Flask, and FastAPI integrations. Covers user management, database\u002Ftable CRUD, file storage, and functions via API keys.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3210,3211,3212,3213,3216],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3214,"slug":3215,"type":15},"Python","python",{"name":699,"slug":3155,"type":15},"2026-07-12T08:45:37.768328",{"items":3219,"total":275},[3220,3227,3235,3243,3251,3260,3268,3276,3283,3297,3316],{"slug":3108,"name":3108,"fn":3109,"description":3110,"org":3221,"tags":3222,"stars":23,"repoUrl":24,"updatedAt":3121},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3223,3224,3225,3226],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3116,"slug":3117,"type":15},{"name":3119,"slug":3120,"type":15},{"slug":3123,"name":3123,"fn":3124,"description":3125,"org":3228,"tags":3229,"stars":23,"repoUrl":24,"updatedAt":3139},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3230,3231,3232,3233,3234],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3131,"slug":3132,"type":15},{"name":3134,"slug":3135,"type":15},{"name":3137,"slug":3138,"type":15},{"slug":3141,"name":3141,"fn":3142,"description":3143,"org":3236,"tags":3237,"stars":23,"repoUrl":24,"updatedAt":3156},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3238,3239,3240,3241,3242],{"name":3147,"slug":3148,"type":15},{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},{"name":699,"slug":3155,"type":15},{"slug":3158,"name":3158,"fn":3159,"description":3160,"org":3244,"tags":3245,"stars":23,"repoUrl":24,"updatedAt":3170},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3246,3247,3248,3249,3250],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3167,"slug":3168,"type":15},{"name":699,"slug":3155,"type":15},{"slug":3172,"name":3172,"fn":3173,"description":3174,"org":3252,"tags":3253,"stars":23,"repoUrl":24,"updatedAt":3189},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3254,3255,3256,3257,3258,3259],{"name":3178,"slug":3179,"type":15},{"name":9,"slug":8,"type":15},{"name":3182,"slug":3183,"type":15},{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3187,"slug":3188,"type":15},{"slug":3191,"name":3191,"fn":3192,"description":3193,"org":3261,"tags":3262,"stars":23,"repoUrl":24,"updatedAt":3203},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3263,3264,3265,3266,3267],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3200,"slug":3201,"type":15},{"name":699,"slug":3155,"type":15},{"slug":3205,"name":3205,"fn":3206,"description":3207,"org":3269,"tags":3270,"stars":23,"repoUrl":24,"updatedAt":3217},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3271,3272,3273,3274,3275],{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3214,"slug":3215,"type":15},{"name":699,"slug":3155,"type":15},{"slug":4,"name":4,"fn":5,"description":6,"org":3277,"tags":3278,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3279,3280,3281,3282],{"name":18,"slug":19,"type":15},{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"name":21,"slug":22,"type":15},{"slug":3284,"name":3284,"fn":3285,"description":3286,"org":3287,"tags":3288,"stars":23,"repoUrl":24,"updatedAt":3296},"appwrite-rust","build server-side applications with Appwrite","Appwrite Rust SDK skill. Use when building server-side Rust applications with Appwrite. Covers async client setup with API keys, user management, TablesDB database\u002Ftable\u002Frow operations, file storage, function executions, permissions, queries, and error handling. Uses the crates.io `appwrite` package and Tokio.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3289,3290,3291,3292,3293],{"name":18,"slug":19,"type":15},{"name":3182,"slug":3183,"type":15},{"name":3152,"slug":3153,"type":15},{"name":1202,"slug":1199,"type":15},{"name":3294,"slug":3295,"type":15},"Rust","rust","2026-07-12T08:45:25.167378",{"slug":3298,"name":3298,"fn":3299,"description":3300,"org":3301,"tags":3302,"stars":23,"repoUrl":24,"updatedAt":3315},"appwrite-swift","build applications with Appwrite Swift SDK","Appwrite Swift SDK skill. Use when building native iOS, macOS, watchOS, or tvOS apps, or server-side Swift applications with Appwrite. Covers client-side auth (email, OAuth), database queries, file uploads, real-time subscriptions with async\u002Fawait, and server-side admin via API keys for user management, database administration, storage, and functions.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3303,3304,3305,3306,3309,3312],{"name":9,"slug":8,"type":15},{"name":3182,"slug":3183,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3307,"slug":3308,"type":15},"iOS","ios",{"name":3310,"slug":3311,"type":15},"macOS","macos",{"name":3313,"slug":3314,"type":15},"Swift","swift","2026-07-12T08:45:26.722393",{"slug":3317,"name":3317,"fn":3318,"description":3319,"org":3320,"tags":3321,"stars":23,"repoUrl":24,"updatedAt":3334},"appwrite-typescript","build applications with Appwrite TypeScript SDK","Appwrite TypeScript SDK skill. Use when building browser-based JavaScript\u002FTypeScript apps, React Native mobile apps, or server-side Node.js\u002FDeno backends with Appwrite. Covers client-side auth (email, OAuth, anonymous), database queries, file uploads, real-time subscriptions, and server-side admin via API keys for user management, database administration, storage, and functions.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3322,3323,3324,3325,3328,3331],{"name":9,"slug":8,"type":15},{"name":3182,"slug":3183,"type":15},{"name":3152,"slug":3153,"type":15},{"name":3326,"slug":3327,"type":15},"JavaScript","javascript",{"name":3329,"slug":3330,"type":15},"Node.js","node-js",{"name":3332,"slug":3333,"type":15},"TypeScript","typescript","2026-07-12T08:45:31.181727"]