Midaz SDK for Go

The Midaz SDK for Go simplifies the connection between your app and Lerian’s financial systems. Whether you’re developing Ledgers, managing Portfolios, or processing Transactions, this SDK provides clear abstractions and a dependable foundation for your development needs.


Getting started


Step 1 – Install Go

Before using the SDK, you must install Go on your machine.

  1. Go to the official Go website.
  2. Download the installer for your OS (Windows, macOS, or Linux).
  3. Follow the installation instructions.

Step 2 - Create or use an existing Go project

Create a Go project:

To create a Go project, use the following command:

mkdir my-midaz-app
cd my-midaz-app
go mod init my-midaz-app

Use an existing Go project:

If you're working in an existing project, make sure there's a go.mod file in the root. If not, run the following command to create one:

go mod init your-module-name

Step 3 – Add the Midaz SDK

Inside your project directory, run the following command to pull the Midaz SDK and add it to your go.mod and go.sum files:

go get github.com/LerianStudio/midaz-sdk-golang

📘

Using VS Code or GoLand?

Your IDE may automatically run go get when you import a new package.

Step 4 – Import the SDK

Create or open a main.go file and add the following content:

🚧

Attention

Remember to change the values in the // Configure plugin access manager section of the code with your own credentials before running it.

package main

import (
	"context"
	"fmt"
	"log"

	client "github.com/LerianStudio/midaz-sdk-golang"
	"github.com/LerianStudio/midaz-sdk-golang/models"
	auth "github.com/LerianStudio/midaz-sdk-golang/pkg/access-manager"
	"github.com/LerianStudio/midaz-sdk-golang/pkg/config"
)

func main() {
	// Configure plugin access manager
	AccessManager := auth.AccessManager{
		Enabled:      true,
		Address:      "https://your-auth-service.com",
		ClientID:     "your-client-id",
		ClientSecret: "your-client-secret",
	}

	// Create a configuration with plugin access manager
	cfg, err := config.NewConfig(
		config.WithAccessManager(AccessManager),
	)
	if err != nil {
		log.Fatalf("Failed to create config: %v", err)
	}

	// Create a client
	c, err := client.New(
		client.WithConfig(cfg),
		client.WithEnvironment(config.EnvironmentProduction),
		client.UseAllAPIs(),
	)
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	// Create an organization
	ctx := context.Background()
	org, err := c.Entity.Organizations.CreateOrganization(
		ctx,
		&models.CreateOrganizationInput{
			LegalName:       "Example Corporation",
			LegalDocument:   "123456789",
			DoingBusinessAs: "Example Inc.",
			Address: models.Address{
				Line1:   "123 Main St",
				City:    "New York",
				State:   "NY",
				ZipCode: "10001",
				Country: "US",
			},
		},
	)
	if err != nil {
		log.Fatalf("Failed to create organization: %v", err)
	}

	fmt.Printf("Organization created: %s\n", org.ID)
}

This gives you access to:

  • The Midaz client for calling APIs
  • Built-in data models (like CreateOrganizationInput)
  • Auth plugin support via Access Manager
  • A flexible configuration system

🚧

Access Manager

For more information about Access Manager, refer to the Access Manager section.

Step 5 - Run the project

Run the following command:

go run main.go

🔍

Dive deeper

For a few code examples that can help you use the Midaz SDK for Go, check out the Midaz Go SDK Examples page.


SDK architecture


The Midaz SDK for Go is designed for clarity and flexibility. Its layered architecture allows you to work confidently, whether you’re setting up accounts or processing thousands of transactions.

Layered design

LayerWhat it handles
ClientThe main entry point that wires everything together.
EntitiesHigh-level access to each Midaz service (Organizations, Ledgers, Accounts, and so on).
ModelsThe core data structures that mirror Midaz’s domain logic.
Utility PackagesModular helpers for config, observability, validation, concurrency, and more.

🔍

Dive deeper

For more information about the architecture, check out the Midaz Go SDK Architecture page.


Entities

The Entities layer serves as the access point to all Midaz services, providing you with simple and user-friendly interfaces. Each interface handles a particular resource and takes care of the details on your behalf. Everything connects smoothly via client.Entity, your central hub for SDK commands.

Available services

ServiceWhat it does
OrganizationsServiceManage organizations
LedgersServiceCreate and retrieve ledgers
AssetsServiceDefine and manage assets
AssetRatesServiceSet up and fetch asset exchange rates
AccountsServiceManage accounts and check balances
PortfoliosServiceGroup accounts under portfolios
SegmentsServiceCategorize accounts using segments
TransactionsServiceCreate and search financial transactions
OperationsServiceDrill into the atomic operations in a transaction
BalancesServiceGet real-time account balances

Models

The Models in the SDK reflect how Midaz thinks about finance, each tied closely to real-world business concepts. You’ll use them across services and operations, from onboarding accounts to recording complex financial events.

Common model types

ModelWhat it represents
OrganizationA business entity that owns ledgers and accounts.
LedgerA collection of accounts and transactions.
AssetA unit of value (currency, token, etc.) that can be stored or moved.
AccountRepresents an account for tracking assets and balances.
PortfolioA collection of accounts for grouping and management.
SegmentA categorization unit for a more granular organization.
TransactionA financial event with operations (debits and credits).
OperationAn individual accounting entry within a transaction.
BalanceThe current state of an account's holdings.

Utility packages

In the pkg folder of the SDK, you will find several utility packages that target common dev challenges, from config handling to retry logic.

Included Packages

PackageWhat it solves
configCentralized config handling, env overrides, and custom service URLs supported.
concurrentTools for batching, rate-limiting, and worker pools.
observabilityTracing, metrics, and logs to keep your integration visible and debuggable.
paginationPaginated responses.
validationInput validation with clear, structured error messages.
errorsRich error types, including field-level detail and error classification.
formatUtilities for formatting data the Midaz way (dates, times, etc.).
retryRetry logic with exponential backoff.
performanceHelpers for speeding up bulk operations or high-throughput tasks.

Access Manager


The Access Manager gives you a secure and flexible way to handle authentication through external identity providers. Instead of hardcoding tokens into your app, just plug in your auth service and let the SDK handle the rest.

Why use it

  • Secure: No hardcoded tokens.
  • Flexible: Works with any identity provider that supports client credentials.
  • Centralized: Manage auth settings in one place.
  • Automatic: Token refresh is fully handled by the SDK.

Configuration

You can configure the Access Manager in two ways:

  • Via code
  • Via environment variables

🚧

Attention

Remeber to change the values in the // Set up plugin-based authentication section of the code with your own credentials before running it.

Option 1: Configure via code

// Import the access manager package
import (
    auth "github.com/LerianStudio/midaz-sdk-golang/pkg/access-manager"
    "github.com/LerianStudio/midaz-sdk-golang/pkg/config"
)

// Set up plugin-based authentication
AccessManager := auth.AccessManager{
    Enabled:      true,
    Address:      "https://your-auth-service.com",
    ClientID:     "your-client-id",
    ClientSecret: "your-client-secret",
}

// Pass it to the SDK configuration
cfg, err := config.NewConfig(
    config.WithAccessManager(AccessManager),
)
if err != nil {
    log.Fatalf("Failed to create config: %v", err)
}

client, err := client.New(
    client.WithConfig(cfg),
    client.UseAllAPIs(),
)

Option 2: Configure via environment variables

Change the following variables in the .env file:

PLUGIN_AUTH_ENABLED=true
PLUGIN_AUTH_ADDRESS=https://your-auth-service.com
MIDAZ_CLIENT_ID=your-client-id
MIDAZ_CLIENT_SECRET=your-client-secret

Then load them in your app:

AccessManager := auth.AccessManager{
    Enabled:      os.Getenv("PLUGIN_AUTH_ENABLED") == "true",
    Address:      os.Getenv("PLUGIN_AUTH_ADDRESS"),
    ClientID:     os.Getenv("MIDAZ_CLIENT_ID"),
    ClientSecret: os.Getenv("MIDAZ_CLIENT_SECRET"),
}

What the SDK does for you

Once plugin-based auth is enabled, the SDK takes over:

  • Requests a token from your auth service using the client credentials
  • Authenticates all API calls using the token
  • Automatically refreshes the token when it expires

Environment variables


You can also configure the SDK using environment variables; no need to hardcode anything.

VariableDescription
MIDAZ_AUTH_TOKENAuthentication token (used when no plugin is set)
MIDAZ_ENVIRONMENTTarget environment (local, development, production)
MIDAZ_ONBOARDING_URLOverride the onboarding service base URL
MIDAZ_TRANSACTION_URLOverride the transaction service base URL
MIDAZ_DEBUGEnable debug logs (true or false)
MIDAZ_MAX_RETRIESSet the max number of retry attempts

🔍

Dive deeper

For more information about the Environment Varibles, check the Environment Variables in the Midaz Go SDK page.


Advanced features


Take your integration further with built-in support for pagination, concurrency, and observability.

Pagination

Work with paginated results the easy way. The SDK gives you an iterator-style interface so you can focus on logic, not pagination math. No need to manage cursors manually, just iterate and go.

// Create a paginator for accounts
paginator := client.Entity.Accounts.GetAccountPaginator(ctx, "org-id", "ledger-id", &models.ListOptions{
	Limit: 10,
})

// Iterate through all pages
for paginator.HasNext() {
	accounts, err := paginator.Next()
	if err != nil {
		// Handle error
	}

	for _, account := range accounts.Items {
		// Process each account
	}
}

🔍

Dive deeper

For more information about Pagination, check the Pagination in the Midaz Go SDK page.


Concurrency utilities

Need to speed things up? The SDK ships with powerful helpers to run tasks in parallel or in batches. These helpers are ideal for high-throughput jobs like syncing accounts or processing bulk transactions.

Run in parallel with WorkerPool

// Process accounts in parallel
results := concurrent.WorkerPool(
	ctx,
	accountIDs,
	func(ctx context.Context, accountID string) (*models.Account, error) {
		// Fetch account details
		return client.Entity.Accounts.GetAccount(ctx, "org-id", "ledger-id", accountID)
	},
	concurrent.WithWorkers(5), // Use 5 workers
)

Process in batches with Batch

// Process items in batches
batchResults := concurrent.Batch(
	ctx,
	transactionIDs,
	10, // Process 10 items per batch
	func(ctx context.Context, batch []string) ([]string, error) {
		// Process the batch and return results
		return processedIDs, nil
	},
	concurrent.WithWorkers(3), // Process 3 batches concurrently
)

Observability

Get full visibility into what your code is doing, with zero extra wiring. Enable tracing, metrics, and structured logs in one line. Whether you're debugging or optimizing performance, observability gives you the edge.

// Create a client with observability enabled
client, err := client.New(
	client.WithPluginAccessManager("your-auth-token"),
	client.WithObservability(true, true, true), // Enable tracing, metrics, and logging
	client.UseAllAPIs(),
)

You can also trace specific blocks of logic:

// Trace an operation
err = client.Trace("create-organization", func(ctx context.Context) error {
	_, err := client.Entity.Organizations.CreateOrganization(ctx, input)
	return err
})

Error handling


The Midaz Go SDK offers a robust error-handling system to help you identify, classify, and respond to API errors effectively. It defines a set of error types such as ValidationError, AuthenticationError, ResourceNotFoundError, and others, allowing precise categorization of issues.

Each error includes structured data, including the error type, code, message, HTTP status, associated resource, and a request ID for debugging or support purposes.

To simplify error handling, the SDK provides helper functions that check for specific error types and HTTP status codes. This enables tailored responses to common scenarios like invalid input, rate limiting, or missing resources.

For transient failures, the SDK supports built-in retry mechanisms that handle network errors, rate limits, and server errors with configurable retry policies. These can be set programmatically or via environment variables.

🔍

Dive deeper

For more information about the Errors, check out the Error Handling in the Midaz Go SDK page.


Retry mechanism

The Midaz Go SDK helps you build resilient integrations by handling transient errors automatically. If a request fails because of a temporary issue, like network issues or rate limit, the SDK can retry the operation for you, so your app doesn’t have to.

By default, the SDK retries:

  • Temporary network issues
  • Rate-limiting responses (with smart backoff)
  • Server-side errors (HTTP 5xx)
  • API responses explicitly marked as retryable

There are two ways to configure the retry parameters:

  • In both examples, the SDK will retry up to 3 times, waiting at least 500ms and at most 5s between attempts.

Configure via client options

Use this approach to programmatically define how many times to retry, and how long to wait between attempts:

client, err := client.New(
    client.WithRetries(3, 500*time.Millisecond, 5*time.Second),
    // Other options...
)

Configure via environment variables

Use this approach to manage the retry behavior using the environment variables (in the .env file):

# Retry configuration
MIDAZ_MAX_RETRIES=3               # Maximum retry attempts for failed requests (default: 3)
MIDAZ_ENABLE_RETRIES=true         # Enable retry mechanism (default: true)
MIDAZ_RETRY_WAIT_MIN=500ms        # Minimum wait time between retries in ms (default: 1000ms)
MIDAZ_RETRY_WAIT_MAX=50000ms      # Maximum wait time between retries in ms (default: 30000ms)

Explore the APIs


For more information about the APIs, refer to the following links