Authdog

Zig SDK

Last updated Sep 20, 2026
View as Markdown

authdog 0.1.0 is the official Zig client for the Authdog REST API. Add it from the authdog/sdk monorepo. It is a management and userinfo client, not a web-framework session binding.

Need to protect a web route? Use a backend SDK for your server framework, or call userinfo yourself with this client.

Install

Add the dependency to build.zig.zon:

.dependencies = .{
    .authdog = .{
        .url = "https://github.com/authdog/sdk/archive/refs/heads/main.tar.gz",
        .hash = "YOUR_PACKAGE_HASH",
    },
},

Then in build.zig:

const authdog_dep = b.dependency("authdog", .{
    .target = target,
    .optimize = optimize,
});
exe.root_module.addImport("authdog", authdog_dep.module("authdog"));

Pin a commit (or a tagged archive) and put the matching package hash in build.zig.zon. Requires Zig 0.16.0+. The SDK uses only the Zig standard library. Source: `zig/` in authdog/sdk.

Configure

Construct one client with the public API base URL. Pass a management Bearer credential (ad_…) when you call privileged endpoints:

const std = @import("std");
const authdog = @import("authdog");

var client = try authdog.AuthdogClient.init(allocator, .{
    .base_url = "https://api.authdog.com",
    .api_key = std.posix.getenv("AUTHDOG_API_TOKEN"),
    .timeout_ms = 10_000,
});
defer client.deinit();

Keep the token server-side. getUserInfo still uses the caller access token, not the management key.

health() is public and works without an API key:

const probe = try client.health();

Optional constructor fields environment_secret (adenv_), scim_token (adscim_), and hris_token (adhris_) are the AuthZEN/MCP runtime, SCIM, and HRIS Bearers.

Resolve a user from an access token

const user_info = client.getUserInfo(access_token) catch |err| {
    if (authdog.isAuthenticationError(err)) {
        // 401: missing, invalid, or expired access token
        return err;
    }
    if (authdog.isApiError(err)) {
        // transport or non-401 HTTP failure
        return err;
    }
    return err;
};
defer user_info.deinit();

_ = user_info.user.display_name;
if (user_info.user.emails.len > 0) {
    _ = user_info.user.emails[0].value;
}

GET /v1/userinfo always sends Authorization: Bearer <access-token>. A constructor API key does not replace that header.

UserInfoResponse uses snake_case fields (user.display_name, session.remaining_seconds).

Call the management API

Namespaces wrap Waves 1–3 of the public /v1 surface:

Attribute Resources
organizations Organizations, invitations, members, keys
tenants Tenants, domains, seats
projects Applications under a tenant
environments Environment records
users Directory users in a tenant + environment
groups Groups and membership
rbac Roles, permissions, resources, mappings, ABAC
audit Administrative audit logs
events Identity event stream
webhooks Webhook subscriptions
notificationChannels SIEM / notification channels
serviceAccounts Service accounts
personalAccessTokens PATs
apiSecrets Environment API secrets
authzen AuthZEN evaluate, search, and discovery
scim SCIM 2.0 directory
hris HRIS employees and departments
mcp MCP runtime
otel OpenTelemetry exporters
oidcClients OIDC clients
actions Environment actions
addons Add-ons
billing Billing
settings Environment settings
elevate Elevate
emailProviders Email providers
featureFlags Feature flags
forms Forms
provisioningTokens Provisioning tokens
impersonation Impersonation
portal Account portal
security Security settings
threats Threats
vanityDomains Vanity domains
widgets Widgets
const orgs = try client.organizations.list();
defer orgs.deinit();

const users = try client.users.list("ten_123", "env_456", .{ .limit = 25 });
defer users.deinit();

Directory calls take tenant_id then environment_id. OpenAPI at `/v1/openapi` is the field-level contract.

Errors

Error When
AuthenticationFailed HTTP 401
ApiError Other HTTP failures and transport errors
ParseError HTTP 200 with a body that is not valid user-info JSON

Use isAuthenticationError / isApiError to branch on type. Use client.lastErrorMessage() for the stable message text.

Next

Learn more