Packages
An unofficial, production-grade Elixir client for the Synctera Banking-as-a-Service API. Zero runtime dependencies, generated from Synctera's OpenAPI spec.
Current section
Files
Jump to
Current section
Files
CHANGELOG.md
# Changelog
All notable changes to this project are documented in this file.
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
### Fixed
- Generated `@doc` content (endpoint summaries/descriptions and the query-options list) could exceed Credo's default 120-character line-length limit for verbose OpenAPI descriptions. The generator now word-wraps doc text and uses a short `HTTP.path_segment/1` helper in place of the previous inline `URI.encode_www_form(to_string(...))`, which also shortened several multi-path-param generated lines below the limit.
### Verified
- **Dialyzer**: clean (`passed successfully`, zero warnings) against a full PLT covering `erts`, `kernel`, `stdlib`, `crypto`, `ssl`, `inets`, `public_key`, `compiler`, and the `elixir`/`logger`/`eex` OTP-style applications, both with plain defaults and with `-Werror_handling -Wunmatched_returns` enabled. Run via the raw `dialyzer` CLI (see `scripts/dialyzer.sh`) since `dialyxir` is a hex.pm package unavailable in this environment — `dialyzer` itself ships with Erlang/OTP and needed no such workaround.
- **Credo**: could not be installed — it and its own dependency (`file_system`) require hex.pm/repo.hex.pm access, unavailable in this build environment (confirmed the same way Jason was: even a git-sourced dependency hits the wall via Credo's *own* transitive hex.pm reference). Performed a manual audit against Credo's actual default check categories instead (line length, `@moduledoc`/`@doc` coverage, predicate naming, alias ordering, `unless`/`else` and negated-condition patterns, zero-arity parens, debug-statement leftovers, TODO comments) — see the project's development notes for the full list checked.
## [1.0.0] - 2026-07-26
### Added
- Initial release.
- Client covering 174 operations (348 functions counting `!` bang variants) across 27 resource modules, generated from Synctera's OpenAPI spec: persons, businesses, customers, relationships, disclosures, applications, KYC/KYB verification, watchlist monitoring, accounts (incl. templates, products, relationships), internal/external accounts, statements, cards, external cards, digital wallet tokens, card transaction/webhook simulations, ACH, wires, transactions, payment schedules, remote check deposit, reconciliations, documents, webhooks, and sandbox workspace reset.
- Zero dependencies — built entirely on Erlang/OTP's standard library, including a hand-written JSON codec (`Synctera.JSON`).
- Two-tier idempotency handling (`:standard` / `:ledger`) matching Synctera's documented behavior.
- Automatic retry with exponential backoff + jitter for 429/5xx responses, honoring `Retry-After`.
- HMAC-SHA256 webhook signature verification with secret-rotation, constant-time comparison, and replay-window support.
- `Stream`-based lazy pagination (`Synctera.Pagination`).
- `Synctera.DeviceInfo` / `Customer-Device-Info` header builder.
- `Synctera.Error` with predicate helpers (`not_found?/1`, `rate_limited?/1`, `conflict?/1`, ...).
- Codegen pipeline (`scripts/generate.py`) for regenerating the resource-module surface against updated specs.
### Design decisions worth knowing about
- **No hex.pm dependencies**, including Jason — not merely a preference but a hard constraint of the build environment (no `hex.pm`/`repo.hex.pm` network access, confirmed even transitively through a git-sourced dependency). Ships its own minimal, tested JSON encoder/decoder instead. See README "Design notes".
- **Plain string-keyed maps, not per-schema structs**, for decoded responses — see README "Design notes" for the reasoning.
- HTTP transport uses `:httpc` with explicit TLS peer verification via `:public_key.cacerts_get/0` (OTP 25+).
### Known limitations
- Generated from the most recent machine-readable OpenAPI spec available (114 paths / 174 operations) — does not yet cover Spend Controls, Evaluation Overrides, Merchants, Institutions, EDD, CRR, or Incoming Wires as a standalone resource, which appear in Synctera's live documentation but not in that snapshot. See README for how to regenerate against an updated spec.