Account

The account surface is everything about the calling identity — your own profile, your own sessions, your own linked accounts, your own audit feed. It's the per-user analogue of every other resource on this page, which operate on workspace-level data. The Go SDK exposes it behind client.Account. For the HTTP surface see API → Account; for the data model see Concepts → Account profile.

Field on the Client

client.Account — type *huudis.AccountResource. Carries two nested namespaces:

  • client.Account.Sessions — *AccountSessionsResource (browser sessions on this account)
  • client.Account.Linked — *AccountLinkedResource (external identities linked to this account)

Methods

Get

Signature. func (r *AccountResource) Get(ctx context.Context, auth RequestAuth) (*AccountProfile, error)

Fetches the calling user's profile. The single source of truth for "who am I?".

me, err := client.Account.Get(ctx, huudis.RequestAuth{})
if err != nil {
    return err
}
state := "MFA off"
if me.MfaEnrolled {
    state = "MFA on"
}
fmt.Println(me.ID, me.Email, state)

Update

Signature. func (r *AccountResource) Update(ctx context.Context, patch map[string]any, auth RequestAuth) (*AccountProfile, error)

PATCH — change your name or locale. Email changes go through a separate verified-change flow; see ChangeEmail below.

_, _ = client.Account.Update(ctx, map[string]any{
    "name":   "Alice T. Wijaya",
    "locale": "id-ID",
}, huudis.RequestAuth{})

ChangeEmail

Signature. func (r *AccountResource) ChangeEmail(ctx context.Context, in ChangeEmailInput, auth RequestAuth) (*ChangeEmailResult, error)

Begins an email change. Huudis sends a confirmation link to NewEmail; the change only takes effect after the user clicks it. Password is required as a fresh-actor check.

res, err := client.Account.ChangeEmail(ctx, huudis.ChangeEmailInput{
    NewEmail: "alice@new.example.com",
    Password: "••••••",
}, huudis.RequestAuth{})
// res.PendingVerification == true → "we sent you a link"
_ = res

ChangePassword

Signature. func (r *AccountResource) ChangePassword(ctx context.Context, in ChangePasswordInput, auth RequestAuth) error

In-place password change. The new password is validated against the workspace's password policy server-side; expect validation_error on weak inputs.

err := client.Account.ChangePassword(ctx, huudis.ChangePasswordInput{
    CurrentPassword: "••••••",
    NewPassword:     "••••••••••••",
}, huudis.RequestAuth{})

After changing, you usually want to revoke other sessions:

_, _ = client.Account.Sessions.RevokeAll(ctx, huudis.RequestAuth{})

Audit

Signature. func (r *AccountResource) Audit(ctx context.Context, p AuditParams, auth RequestAuth) ([]AuditEntry, error)

The audit feed scoped to actions taken by this user. EventType filters to a single slug; Since is ISO-8601; Limit caps at 200.

since := time.Now().Add(-7 * 24 * time.Hour).Format(time.RFC3339)
recent, _ := client.Account.Audit(ctx, huudis.AuditParams{
    Since: since,
    Limit: 100,
}, huudis.RequestAuth{})
for _, e := range recent {
    fmt.Println(e.Timestamp, e.Action, e.Outcome, e.Resource)
}

For workspace-wide audit, use the Authz namespace.

Sessions.List

Signature. func (r *AccountSessionsResource) List(ctx context.Context, auth RequestAuth) ([]BrowserSession, error)

Lists every browser session active on this account. The session backing the current request has Current: true.

sessions, _ := client.Account.Sessions.List(ctx, huudis.RequestAuth{})
for _, s := range sessions {
    marker := ""
    if s.Current {
        marker = " (this one)"
    }
    fmt.Println(s.ID, s.UserAgent, s.IPAddress, marker)
}

Sessions.Revoke

Signature. func (r *AccountSessionsResource) Revoke(ctx context.Context, id string, auth RequestAuth) error

Revokes one session by ID. The user is signed out on that device within ~1 minute.

_ = client.Account.Sessions.Revoke(ctx, "sess_01HX...", huudis.RequestAuth{})

Sessions.RevokeAll

Signature. func (r *AccountSessionsResource) RevokeAll(ctx context.Context, auth RequestAuth) (*SessionRevokeAllResult, error)

Revokes every session except the calling one. Returns {Revoked: <count>}. Pair with password change.

res, _ := client.Account.Sessions.RevokeAll(ctx, huudis.RequestAuth{})
fmt.Printf("Signed out of %d other devices\n", res.Revoked)

Linked.List

Signature. func (r *AccountLinkedResource) List(ctx context.Context, auth RequestAuth) ([]LinkedAccount, error)

Lists every external identity linked to this account (Google, GitHub, SAML, …). Each Provider slug matches an IdP ID or a built-in social provider.

linked, _ := client.Account.Linked.List(ctx, huudis.RequestAuth{})
for _, l := range linked {
    label := l.Email
    if label == "" {
        label = l.Subject
    }
    fmt.Println(l.Provider, label, l.LinkedAt)
}

Signature. func (r *AccountLinkedResource) Unlink(ctx context.Context, provider string, auth RequestAuth) error

Removes a linked account. The user must keep at least one signin method (password or another linked account) — Huudis returns state_conflict if unlinking would orphan the identity.

_ = client.Account.Linked.Unlink(ctx, "google", huudis.RequestAuth{})

Types

type AccountProfile struct {
    ID            string `json:"id"`            // "usr_..."
    Email         string `json:"email"`
    EmailVerified bool   `json:"emailVerified"`
    Name          string `json:"name,omitempty"`
    Locale        string `json:"locale,omitempty"`
    MfaEnrolled   bool   `json:"mfaEnrolled"`
    CreatedAt     string `json:"createdAt"`
}

type BrowserSession struct {
    ID         string `json:"id"`
    UserAgent  string `json:"userAgent,omitempty"`
    IPAddress  string `json:"ipAddress,omitempty"`
    CreatedAt  string `json:"createdAt"`
    LastSeenAt string `json:"lastSeenAt"`
    Current    bool   `json:"current,omitempty"`
}

type LinkedAccount struct {
    Provider string `json:"provider"`
    Subject  string `json:"subject"`
    Email    string `json:"email,omitempty"`
    LinkedAt string `json:"linkedAt"`
}

type AuditEntry struct {
    ID        string         `json:"id"`
    AccountID string         `json:"accountId"`
    Actor     string         `json:"actor"`
    Action    string         `json:"action"`
    Resource  string         `json:"resource,omitempty"`
    Outcome   string         `json:"outcome"`  // "success" | "failure"
    Details   map[string]any `json:"details,omitempty"`
    Timestamp string         `json:"timestamp"`
}

See API → Account for field-level rules.

Common patterns

Build a "Settings → Security" page

Wire every surface on this namespace:

type SecurityPageData struct {
    Profile    *huudis.AccountProfile
    Sessions   []huudis.BrowserSession
    Linked     []huudis.LinkedAccount
    MfaDevices []huudis.MfaDevice
}

func securityPageData(ctx context.Context, c *huudis.Client) (*SecurityPageData, error) {
    profile, err := c.Account.Get(ctx, huudis.RequestAuth{})
    if err != nil {
        return nil, err
    }
    sessions, _ := c.Account.Sessions.List(ctx, huudis.RequestAuth{})
    linked, _ := c.Account.Linked.List(ctx, huudis.RequestAuth{})
    devices, _ := c.MFA.ListDevices(ctx, huudis.RequestAuth{})
    return &SecurityPageData{Profile: profile, Sessions: sessions, Linked: linked, MfaDevices: devices}, nil
}

Sign out everywhere after password change

func changePasswordAndSignOutEverywhere(ctx context.Context, c *huudis.Client, current, next string) (int, error) {
    if err := c.Account.ChangePassword(ctx, huudis.ChangePasswordInput{
        CurrentPassword: current,
        NewPassword:     next,
    }, huudis.RequestAuth{}); err != nil {
        return 0, err
    }
    res, err := c.Account.Sessions.RevokeAll(ctx, huudis.RequestAuth{})
    if err != nil {
        return 0, err
    }
    return res.Revoked, nil
}

Recent activity feed

since := time.Now().Add(-7 * 24 * time.Hour).Format(time.RFC3339)
events, _ := client.Account.Audit(ctx, huudis.AuditParams{Since: since, Limit: 100}, huudis.RequestAuth{})
for _, e := range events {
    var ip string
    if v, ok := e.Details["ipAddress"]; ok {
        ip, _ = v.(string)
    }
    fmt.Println(e.Timestamp, e.Action, ip, e.Outcome == "success")
}

Errors

Code Status Cause
validation_error 400 Weak new password; bad email format.
bad_credentials 401 ChangePassword / ChangeEmail got the wrong current password.
state_conflict 409 Unlinking would orphan; changing email to one that already exists.
not_found 404 Session ID doesn't exist on this account.

Next