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 theinstallation 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

👍

Tip

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.

👍

Tip

Want to learn more about Access Manager? Check out the Access Manager section for details.

Step 5 - Run the project

Run the following command:

go run main.go

👍

Tip

Want to dive deeper? Check out the Midaz Go SDK Examples page for practical code snippets to help you get started.


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.

👍

Tip

Want to dive deeper? Check out the Midaz Go SDK Architecture page for more information.


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.

👍

Tip

Want to dive deeper? Check the Environment Variables in the Midaz Go SDK page for more information.


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
	}
}

👍

Tip

Want to dive deeper? Check the Pagination in the Midaz Go SDK page for more information.


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.

👍

Tip

Want to dive deeper? Check out the Error Handling in the Midaz Go SDK page for more information.


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