C# SDK

C# SDK Quick Start — WowSQL Docs

C# / .NET Quick Start

WowSQL · WOWSQL.SDK · PostgreSQL REST API

API keys: Copy Anonymous or Service role keys from the WowSQL project dashboard. Use the service role key only on servers (full DB, storage, schema). App data lives in the public schema via the REST API.

Installation

NuGet: WOWSQL.SDK on nuget.org →

.NET CLI:

dotnet add package WOWSQL.SDK

Package Manager:

Install-Package WOWSQL.SDK

PackageReference:

<PackageReference Include="WOWSQL.SDK" Version="2.0.0" />

Targets .NET Standard 2.0 (works with .NET Framework 4.6.1+ and .NET Core / 5+).

Namespace

All types are in using WOWSQL; — class names are WOWSQLClient, ProjectAuthClient, WOWSQLStorage, WOWSQLSchema.

Initialize database client

using WOWSQL;
using System.Collections.Generic;
using System.Threading.Tasks;

var client = new WOWSQLClient(
    projectUrl: "myproject",           // slug or full URL
    apiKey: "wowsql_anon_... or wowsql_service_...",
    baseDomain: "wowsqlconnect.com",
    secure: true,
    timeout: 30,
    verifySsl: true
);

// Query: always Select() before GetAsync() on the builder
var users = await client.Table("users").Select("*").GetAsync();

Query data

Basic

var all = await client.Table("users").Select("*").GetAsync();

var adults = await client.Table("users").Select("*").Gte("age", 18).GetAsync();

var names = await client.Table("users").Select("id", "name").GetAsync();

Chained filters & paging

var active = await client.Table("users")
    .Select("*")
    .Eq("status", "active")
    .Gt("age", 18)
    .Order("created_at", "desc")
    .Limit(20)
    .Offset(0)
    .GetAsync();

System.Console.WriteLine($"Count: {active.Count}");
foreach (var row in active.Data)
    System.Console.WriteLine(row["name"]);

GROUP BY / HAVING (POST when needed)

var stats = await client.Table("products")
    .Select("category", "COUNT(*) as count", "AVG(price) as avg_price")
    .GroupBy("category")
    .Having("COUNT(*)", "gt", 10)
    .GetAsync();

CRUD

var created = await client.Table("users").CreateAsync(new Dictionary<string, object> {
    ["name"] = "Jane",
    ["email"] = "jane@example.com"
});
// created.Id, created.Message

await client.Table("users").UpdateAsync(created.Id, new Dictionary<string, object> {
    ["email"] = "new@example.com"
});

await client.Table("users").DeleteAsync(created.Id);

var one = await client.Table("users").GetByIdAsync(123);

var first = await client.Table("users").Eq("status", "active").FirstAsync();

Error handling

try
{
    var res = await client.Table("users").Select("*").GetAsync();
}
catch (WOWSQLException ex)
{
    if (ex.StatusCode == 401) { /* bad API key */ }
}
finally { client.Dispose(); }

// or
using (var c = new WOWSQLClient("myproject", apiKey))
{
    var r = await c.Table("users").Select("*").GetAsync();
}

Authentication — ProjectAuthClient

using (var auth = new ProjectAuthClient(
    projectUrl: "myproject",
    apiKey: "wowsql_anon_...",
    baseDomain: "wowsqlconnect.com"))
{
    var session = await auth.SignUpAsync(
        "user@example.com",
        "SecurePassword123!",
        "Full Name",
        new Dictionary<string, object> { ["k"] = "v" });

    auth.SetSession(session.Session.AccessToken, session.Session.RefreshToken);

    var login = await auth.SignInAsync("user@example.com", "SecurePassword123!");
    await auth.ForgotPasswordAsync("user@example.com");
}

OAuth Authentication

Setup checklist — do this once per provider, per project:
1. Dashboard → Project → Auth → Providers: enable the provider, paste Client ID and Client Secret (no leading/trailing spaces).
2. Copy the Redirect URI shown: https://<slug>.wowsqlconnect.com/api/auth/oauth/<provider>/callback and register it in your provider's developer console.
3. The callback URL is handled entirely by WowSQL — your app does not send an API key on it. WowSQL exchanges the code and redirects to your frontend_redirect_uri with ?access_token=&refresh_token=.

using (var auth = new ProjectAuthClient(projectUrl: "myproject", apiKey: "wowsql_anon_..."))
{
    // ── Step 1: Get the authorization URL ────────────────────────────────────
    var oauth = await auth.GetOAuthAuthorizationUrlAsync(
        "google",
        "https://yourapp.com/auth/callback"
    );
    // Redirect the browser to oauth.AuthorizationUrl
    // Google calls: https://<slug>.wowsqlconnect.com/api/auth/oauth/google/callback
    // WowSQL exchanges the code and redirects to your frontend_redirect_uri.

    // ── Step 2: Read tokens from the redirect ────────────────────────────────
    // WowSQL redirects to: https://yourapp.com/auth/callback?access_token=...&refresh_token=...

    // ── (Advanced) Manual code exchange — only if you handle the callback yourself
    var result = await auth.ExchangeOAuthCallbackAsync(
        "google",
        "authorization_code_from_callback",
        "https://yourapp.com/auth/callback"  // must match step 1
    );
    Console.WriteLine($"OAuth login successful: {result.User.Id}");
}

Storage — WOWSQLStorage (buckets)

using (var storage = new WOWSQLStorage(
    projectUrl: "myproject",
    apiKey: "wowsql_service_...",
    baseDomain: "wowsqlconnect.com",
    timeout: 60))
{
    var bucket = await storage.CreateBucketAsync("uploads", isPublic: false);
    var file = await storage.UploadFromPathAsync(@".\doc.pdf", "uploads", path: "docs/doc.pdf");
    var files = await storage.ListFilesAsync("uploads", prefix: "docs/", limit: 100, offset: 0);
    var url = storage.GetPublicUrl("uploads", "docs/doc.pdf");
    var quota = await storage.GetQuotaAsync();
}

Schema — WOWSQLSchema (service key only)

UUID primary key: The API requires the primaryKey column to be type UUID (not SERIAL). Use ["type"] = "UUID" with ["auto_increment"] = true for DEFAULT gen_random_uuid(). Raw CREATE TABLE via ExecuteSQL must not use integer/SERIAL primary keys.

using (var schema = new WOWSQLSchema(
    projectUrl: "myproject",
    serviceKey: "wowsql_service_...",
    baseDomain: "wowsqlconnect.com"))
{
    await schema.CreateTableAsync("items", new List<Dictionary<string, object>> {
        new Dictionary<string, object> { ["name"] = "id", ["type"] = "UUID", ["auto_increment"] = true },
        new Dictionary<string, object> { ["name"] = "title", ["type"] = "TEXT" }
    }, primaryKey: "id");

    var tables = await schema.ListTablesAsync();
}

Catch SchemaPermissionException if a non-service key is used.

NuGet package readme

Recent packages embed README.md so the gallery shows documentation. Unsigned packages show NU3004 under dotnet nuget verify — that is normal; publishing still works.

← All SDK docs