Primeros pasos
Paso 1 – Instala Go
Instala Go antes de usar el SDK. El SDK declara Go 1.26 engo.mod. Su API pública usa iter.Seq2 y log/slog.
1
Ve al sitio web oficial de Go.
2
Descarga el instalador para tu sistema operativo (Windows, macOS o Linux).
Paso 2 – Crea o usa un proyecto de Go existente
Crea un proyecto de Go: Para crear un proyecto de Go, usa el siguiente comando:go.mod en la raíz. Si no lo hay, ejecuta el siguiente comando para crear uno:
Paso 3 – Agrega el SDK de Midaz
Dentro del directorio de tu proyecto, ejecuta el siguiente comando para agregar el SDK a tus archivosgo.mod y go.sum:
Paso 4 – Importa el SDK
Crea o abre un archivomain.go y agrega el siguiente contenido. El ejemplo crea un cliente para tu stack local de Midaz con autenticación anónima, lista las organizaciones y después crea una nueva.
El ejemplo de abajo apunta a un stack local de Midaz con la autenticación desactivada. Si todavía no tienes uno en ejecución, consulta Primeros pasos con Midaz para levantarlo antes de ejecutar el fragmento.
- El cliente de Midaz para llamar a cada servicio de la API.
- Modelos de datos incluidos (como
CreateOrganizationInput). - Autenticación mediante Access Manager (producción) o Anonymous (desarrollo local).
- Un sistema de configuración tipado que falla en el momento de la construcción.
Paso 5 – Ejecuta el proyecto
Ejecuta el siguiente comando:Arquitectura del SDK
Diseño en capas
Servicios
Midaz atiende dos versiones de la API del ledger:/v1, que está obsoleta, y /v2. El SDK agrupa los servicios del ledger por la versión que los atiende. Desarrolla sobre c.V2. Un recurso que una versión no atiende produce un error de compilación, no un 404.
Transactions tiene un contrato distinto en cada versión. En /v1, creas una transacción mediante uno de seis métodos de creación con un cuerpo send anidado. En /v2, c.V2.Transactions crea transacciones con un cuerpo plano mediante CreateDirect, CreateHold, CreateBlock y CreateUnblock. Devuelve models.TransactionV2.
Para publicar varias transacciones direct y hold como un lote ordenado, usa c.V2.Transactions.CreateBatch. Midaz aplica todos los ítems, en orden, o ninguno. Cada ítem es un models.TransactionBatchItemV2 con una Action (direct o hold) y un Order (empieza en uno y es consecutivo). La llamada devuelve las transacciones en ese orden. El lote tiene una sola clave de idempotencia, que defines con sdkctx.WithIdempotencyKey. Se rechaza un ítem que define su propia IdempotencyKey.
Una respuesta
201 significa que Midaz aplicó la transacción a los saldos.Lee la versión del servidor
c.ServerVersion lee la versión del ledger de Midaz con el que se comunica el cliente. Devuelve un error cuando el ledger no responde con una versión.
midaz.SupportsRulesOnly indica si el Tracer de esa versión acepta la validación solo por reglas. c.Validations.EvaluateRulesOnly juzga una transacción solo por sus reglas: no revisa ningún límite de gasto y no cuenta nada contra uno.
Modelos
Cada tipo de modelo representa un concepto de negocio. Los usas en cada llamada de servicio. Los tipos de modelo más comunes se reexportan en el paquetemidaz. midaz.Account y models.Account son el mismo tipo, así que la mayor parte del código necesita solo un import.
midaz.Account incluye ClosedAt, el momento en que Midaz cerró la cuenta. Es nil mientras la cuenta está abierta. Cerrar una cuenta no cambia Status.
Tipos de modelo comunes
Paquetes de utilidades
La carpetapkg del SDK contiene paquetes de utilidades. Los paquetes Core atienden aspectos que aplican a todo el SDK. Los paquetes Helper ofrecen utilidades específicas de dominio o de bajo nivel.
Paquetes Core
Paquetes Helper
Autenticación
El SDK requiere exactamente una fuente de autenticación en el momento de la construcción. Si llamas a
midaz.New(...) sin ninguna de las dos, devuelve un error de configuración tipado.
Tienes dos opciones:
midaz.WithAccessManager(...): OAuth mediante Lerian Access Manager. Úsalo en cualquier stack que no sea local.midaz.WithAnonymous(): sin autenticación. Úsalo solo en un stack local de Midaz con la autenticación desactivada.
Producción: Access Manager
Coloca tus credenciales de Access Manager enmidaz.WithAccessManager. El SDK solicita un token a tu Access Manager, lo adjunta a cada llamada a la API y lo renueva cuando vence.
Desarrollo local: Anonymous
Para un stack local de Midaz con la autenticación desactivada, desactívala de forma explícita:Configura mediante variables de entorno
También puedes apuntar el SDK a tu Access Manager con variables de entorno. Expórtalas en tu shell o en tu gestor de procesos:config.FromEnvironment() lee el entorno del proceso, no un archivo .env. Si guardas variables en un archivo .env durante el desarrollo, cárgalas con una biblioteca como godotenv antes de llamar a config.NewConfig(config.FromEnvironment()).La carga desde el entorno es explícita. Coloca
config.FromEnvironment() en la cadena de opciones. Sin ella, el SDK no lee variables de entorno durante la construcción.Alcance del tenant
El alcance del tenant viene de Access Manager / de los claims del JWT que se usan para obtener el token. El SDK no tiene configuración de tenant y no envía un header de tenant. Para ejecutar llamadas con un alcance de tenant distinto, usa un conjunto separado de credenciales de Access Manager o crea un segundo cliente con su propio contexto de token.
Listado e iteración
La mayoría de los endpoints de listado viene en tres métodos. Elige el que corresponde a tu caso de uso.
Opciones de listado tipadas
Cada método de listado recibe un struct de opciones tipado. El struct incorpora uno de dos structs base, según cómo pagina el endpoint:
Algunos endpoints también exponen un sub-struct
Filters tipado. Si defines un campo de la forma incorrecta (por ejemplo, Page en un endpoint basado en cursor), el código no compila.
Itera cada elemento con All
La forma más simple es un bucle range sobre cada elemento de cada página. El SDK obtiene las páginas internamente.
Itera los sobres de página con Pages
Cuando necesitas metadatos en el nivel de página (para checkpoints, procesamiento por lotes o detenerte a mitad de página), itera sobre Pages. Cada entrada es un *models.ListResponse[T] con su bloque Pagination.
NextCursor y la tabla de decisión entre página y cursor.
Manejo de errores
La capa de servicios del SDK devuelve los errores como
*pkg/errors.Error con campos estructurados:
Puedes ramificar la lógica con predicados tipados, leer campos con
errors.As o usar el método Retryable() para guiar la política de reintentos.
Ramifica la lógica con predicados tipados
El SDK tiene un conjunto de predicadosIs*, para que identifiques errores sin leer detalles internos:
Guía las decisiones de reintento con Retryable()
El método Error.Retryable() deriva de Category. Úsalo en lugar de tu propia clasificación.
Envuelve errores de transporte sin procesar
Si llamas a código HTTP de bajo nivel fuera del SDK y quieres la misma forma de error estructurado, usaClassifyTransportError:
Validación local: FieldErrors
La validación local de entrada devuelve*pkg/validation.FieldErrors, una colección de errores por campo que el SDK encuentra antes de cualquier llamada HTTP. Usa errors.As para leerlos.
Reintentos
La política predeterminada reintenta 3 veces con backoff exponencial y 25% de jitter. Reintenta los errores de transporte y los estados
408, 425, 429, 500, 502, 503 y 504. El SDK reintenta un POST, PUT, PATCH o DELETE cuando la solicitud tiene un header X-Idempotency, o cuando es la creación de una transacción, de un titular o de un instrumento, que Midaz responde con el primer resultado cuando llega de nuevo la misma solicitud. Envía una sola vez cualquier otra escritura.
Después de que una escritura falla, el SDK deja de reintentar cuando la ventana de idempotencia ya pasó desde el inicio de la llamada. La ventana es el valor de X-TTL de la solicitud, o 300 segundos cuando el header no existe. Un 409 con el código 0084 bajo una clave que definiste tú vuelve como error. El SDK solo reintenta un 0084 bajo su propia clave aleatoria o en una creación sin clave.
midaz.WithCustomRetryPolicy para tu propio predicado de reintento. Para desactivar los reintentos, usa midaz.WithoutRetries().
Registro
*slog.Logger es la superficie de logger del SDK. Conéctalo con midaz.WithLogger(...). El SDK es silencioso de forma predeterminada: usa slog.DiscardHandler hasta que lo activas.
Tú decides el handler, el nivel y el destino.
slog.Handler.
Observabilidad
Un proveedor de observabilidad te da spans, métricas y registros correlacionados con OpenTelemetry. Pasa un proveedor que construyes tú, o pasa opciones que el SDK arma por ti.
Conecta un proveedor
O pasa opciones en línea
observability.WithCollectorEndpoint, el SDK usa los proveedores de OpenTelemetry de tu aplicación y no los reemplaza. c.Shutdown cierra solo un proveedor que el SDK construyó. Si pasas tu propio proveedor, ciérralo después del último cliente que lo usa.
Llamadas como c.V2.Accounts.Get no crean ningún span ni envían el header traceparent por sí solas. Para trazarlas, envuelve el transporte del cliente con el middleware de observabilidad:
WithHTTPTransport conserva el cliente HTTP propio del SDK, con su timeout, autenticación y reintentos, y envuelve su transporte.
También puedes envolver un bloque de lógica de negocio en un span con Client.Trace:
Idempotencia
El SDK no genera una clave
X-Idempotency aleatoria a menos que la actives. Sin una clave tuya, Midaz trata una creación de transacción idéntica dentro de la ventana de idempotencia (300 segundos por defecto) como una repetición y devuelve la primera transacción. Una segunda transacción intencional con la misma solicitud no se publica. Para ver cómo trata Midaz la falta de clave, consulta Reintentos e idempotencia.
Define una clave distinta para cada transacción que quieres publicar. Esto es habitual en pasos de saga, filas de outbox o envíos de UI.
Define una clave estable por solicitud
sdkctx.WithoutAutoIdempotency.
Activa una clave aleatoria de forma global
Para enviar una claveX-Idempotency aleatoria en cada creación, actualización y eliminación, actívala en el nivel del cliente:
MIDAZ_IDEMPOTENCY=true cuando usas config.FromEnvironment(). Cada llamada lleva entonces su propia clave, así que dos transacciones intencionales con la misma solicitud se publican por separado. Un reintento de una llamada reutiliza la clave de esa llamada.
Detén la clave aleatoria en una llamada
Cuando el cliente tiene la clave aleatoria activada, puedes detenerla en una llamada:Variables de entorno
El SDK lee estas variables solo cuando
config.FromEnvironment() está en tu cadena de opciones de configuración.
Para la matriz completa de opciones de
midaz, pkg/config y pkg/sdkctx, consulta la guía de configuración en el repositorio del SDK.
Proyectos de ejemplo
concurrency, configuration, context, tracing, tracing-server, pkg-validation-demo, mass-demo-generator y workflow-with-entities.
Explora las API
Para obtener más información sobre las API, consulta los siguientes enlaces:

