Skip to main content
Connect your automation to Speckle Server. Before your code can load model data or publish results, SpeckleSharp needs an Account (a token plus server and user metadata) and an IClient built from it. What this page covers: the three .NET ways to obtain an Account — personal access token, interactive browser login, and locally stored accounts. When to read it: before any server call in a new app. Read next: Build your first model analysis tool or Automate with scripts.
For how to create a personal access token or register an OAuth application, see Building with PATs and OAuth 2.0. This page covers the .NET-specific code that consumes them.
Speckle.Sdk exposes three ways to get an Account:
  • Personal access token — scripts, services, and CI (recommended default)
  • Interactive browser login — desktop and connector apps that should integrate with Speckle’s existing account store
  • Locally stored accounts — reuse a login from Speckle desktop connectors
Prefer a personal access token or your own OAuth flow over Accounts.db. IAccountManager.AuthenticateAccount (below) always writes the resulting account to a local SQLite database (Accounts.db) — there’s no way to opt out. That’s the right behavior for a desktop connector that should share login state with Rhino, Revit, Grasshopper, and other Speckle apps on the same machine. It’s very rarely what you want in a script, a server-side service, a CI pipeline, or a multi-user web backend, where a token you manage yourself (env var, secret manager, or your own OAuth exchange) is simpler and doesn’t leave credentials on disk outside your control.

Choosing an Authentication Method

  • A script, service, automation, or CI/CD pipeline — use a personal access token via IAccountFactory.CreateAccount. Doesn’t touch Accounts.db — in-memory only.
  • A multi-user server or web backend that already manages its own user tokens — perform your own OAuth exchange (see OAuth 2.0), then pass the resulting token to IAccountFactory.CreateAccount. Doesn’t touch Accounts.db — in-memory only.
  • A desktop connector or CLI tool meant to share login state with Speckle’s desktop ecosystem — use interactive login via IAccountManager.AuthenticateAccount. Always writes to Accounts.db, by design.
  • Any app reusing a login a user already created via a Speckle desktop connector or AuthenticateAccount — use locally stored accounts via GetAccounts/GetDefaultAccount. Read-only access to Accounts.db.
The recommended approach for most AEC automation scripts: build an Account from a personal access token using IAccountFactory.
https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251Example
using Microsoft.Extensions.DependencyInjection;
using Speckle.Sdk.Api;
using Speckle.Sdk.Credentials;

var accountFactory = provider.GetRequiredService<IAccountFactory>();
var account = await accountFactory.CreateAccount(
    new Uri("https://app.speckle.systems"),
    speckleToken: "your_token_here" // In production, use environment variables!
);

using var client = provider.GetRequiredService<IClientFactory>().Create(account);
Console.WriteLine($"Authenticated as: {account.userInfo.name}");
IAccountFactory.CreateAccount fetches user and server info from the token and returns an Account object. It does not write to the local account store — it’s a lightweight factory for in-memory use, ideal for scripts, services, and CI.
https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251Example
var token = Environment.GetEnvironmentVariable("SPECKLE_TOKEN")
    ?? throw new InvalidOperationException("SPECKLE_TOKEN environment variable not set");
var serverUrl = Environment.GetEnvironmentVariable("SPECKLE_SERVER") ?? "https://app.speckle.systems";

var account = await accountFactory.CreateAccount(new Uri(serverUrl), token);
export SPECKLE_TOKEN="your_token_here"
export SPECKLE_SERVER="https://app.speckle.systems"

Interactive login (connectors and desktop apps)

Avoid this section unless you are building a connector or desktop tool. For scripts, QA automations, and Grasshopper send/receive, use a PAT from the section above. For desktop or connector-style applications where a user should sign in through the browser and you want that login to be reusable across Speckle’s desktop ecosystem, use IAccountManager.AuthenticateAccount. This opens a browser window and completes an OAuth PKCE flow.
https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251Example
using Speckle.Sdk.Credentials;

var accountManager = provider.GetRequiredService<IAccountManager>();
var account = await accountManager.AuthenticateAccount(
    new Uri("https://app.speckle.systems"),
    TimeSpan.FromMinutes(1),
    CancellationToken.None
);
AuthenticateAccount unconditionally persists the resulting account to a local SQLite database file at the current user’s application data folder (.../Speckle/Accounts.db) — the same store used by Speckle’s desktop connectors. There is no in-memory-only mode for this method. If you need interactive OAuth login without writing to that shared store — for example, a web backend performing OAuth on behalf of many users — implement your own PKCE/authorization-code exchange (see OAuth 2.0) and build the Account from the resulting token with IAccountFactory.CreateAccount instead, which never touches disk.

Reusing Locally Stored Accounts

If a user has already signed in via a Speckle desktop connector, or via AuthenticateAccount above, retrieve their stored accounts instead of prompting again:
https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251Example
var accountManager = provider.GetRequiredService<IAccountManager>();

// All accounts for a specific server
var accounts = accountManager.GetAccounts(new Uri("https://app.speckle.systems"));

// Or the user's default account across all servers
var defaultAccount = accountManager.GetDefaultAccount();

if (defaultAccount is not null)
{
    using var client = provider.GetRequiredService<IClientFactory>().Create(defaultAccount);
}
Older AccountManager methods such as AddAccount and GetLocalAccounts are obsolete and throw at runtime. Use AuthenticateAccount, GetAccounts, and GetDefaultAccount instead.

Different Speckle Servers

https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251Example
// Public Speckle server
var account = await accountFactory.CreateAccount(new Uri("https://app.speckle.systems"), token);

// Self-hosted server
var account = await accountFactory.CreateAccount(new Uri("https://speckle.mycompany.com"), token);

Checking Authentication Status

https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251Example
if (!string.IsNullOrEmpty(account.token))
{
    Console.WriteLine("✓ Authenticated");
    Console.WriteLine($"Logged in as: {account.userInfo.name} ({account.userInfo.email})");
}

Common Authentication Errors

Cause: The token is invalid, expired, or has been revoked.Solution: Generate a new personal access token and verify there are no extra spaces when copying it.
Cause: No account has been authenticated on this machine yet.Solution: Use token-based authentication via IAccountFactory.CreateAccount, or call AuthenticateAccount to sign in interactively first.
Cause: The server URL is incorrect, or the server uses a self-signed certificate.Solution: Verify the server URL, check network/firewall settings, and ensure the certificate is trusted by the host machine — Speckle.Sdk does not expose a certificate-bypass option.

Security Best Practices

Do:
  • Store tokens in environment variables or a secret manager
  • Use scoped tokens with the minimum permissions your application needs
  • Revoke tokens when they’re no longer needed
Don’t:
  • Commit tokens to version control
  • Share tokens between team members or applications
  • Use personal access tokens in client-side or distributed desktop code — prefer OAuth for multi-user applications

Next Steps

Build your first model analysis tool

Load model data after authenticating

Automate with scripts

Bootstrap and Receive2

Core concepts

Platform map and mental model
Last modified on July 10, 2026