All notable changes to this project are documented in this file. Format based on Keep a Changelog.

[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.