LatticeStripe 1.0.0 commits to API stability under standard semantic versioning. This guide documents exactly what is covered by that contract and what is explicitly excluded.

LatticeStripe follows Semantic Versioning 2.0.0 from v1.0.0 forward. Once you pin to ~> 1.0, you can expect additive changes within the 1.x line and never a silent break. The contract applies to the surface described below — anything outside it is an implementation detail and may change without a major bump.

What is public API

Every module documented in HexDocs (that is, every module without @moduledoc false) is public API. The semver contract covers:

  • Public module names and aliases — renaming or removing a public module is a major bump.
  • Public function signatures — name, arity, parameter shape, and return type of every @doc-annotated function.
  • Public struct field namesadding fields to a public struct is non-breaking; removing or renaming a field is breaking.
  • Error reason atoms in LatticeStripe.Error — the :type field's documented atom set is stable. New atoms may be added (minor bump); existing ones will not silently change meaning.
  • Telemetry event names and metadata keys in LatticeStripe.Telemetry — the documented event list and measurement keys are stable for the 1.x line.
  • NimbleOptions schema keys in LatticeStripe.Config — options accepted by LatticeStripe.Client.new!/1 and new/1 are stable within 1.x. Adding options is non-breaking; removing them is a major bump.

What is NOT public API

Modules with @moduledoc false are internal implementation details. They are visible in the source tree — this is Elixir, there is no privacy enforcement — but they are explicitly excluded from the semver contract. These modules may change in any patch release without notice:

  • LatticeStripe.FormEncoder
  • LatticeStripe.Resource
  • LatticeStripe.Transport.Finch
  • LatticeStripe.Json.Jason
  • LatticeStripe.RetryStrategy.Default
  • LatticeStripe.Webhook.CacheBodyReader
  • LatticeStripe.Billing.Guards

Note: LatticeStripe.Request was previously documented as internal but is retained as public API in 1.0 because LatticeStripe.Client.request/2 accepts a Request.t() struct — see Phase 19 Plan 01 summary for the Rule 1 deviation that kept Request public.

If your application depends on any of these modules, you are relying on an implementation detail and should expect breakage. Prefer the public behaviours listed below as extension points.

Extension points (public behaviours)

Three behaviours are public API precisely because they are designed for user implementation. Custom implementations of these behaviours are supported and will continue to be supported for the 1.x lifetime:

  • LatticeStripe.Transport — swap the HTTP client. LatticeStripe ships a Finch adapter by default, but any module implementing this behaviour can be plugged in via the :transport config.
  • LatticeStripe.Json — swap the JSON codec. Jason is the default; any codec implementing encode/1 and decode/1 works.
  • LatticeStripe.RetryStrategy — customize retry logic. The default strategy honours Stripe's Stripe-Should-Retry header and the idempotency-replayed response header, but platforms with exotic retry budgets can supply their own module.

These are the designed-in extension points. Building on top of them is safe across the 1.x line.

Versioning policy

After v1.0.0, LatticeStripe follows post-1.0 semver strictly:

  • Patch (1.0.x) — bug fixes, documentation corrections, internal refactors, dependency version bumps that do not change the public surface. No behaviour changes that a working application would notice.
  • Minor (1.x.0) — additive features only: new resource modules, new function arities, new optional fields on existing structs, new NimbleOptions schema keys, new Telemetry metadata keys, new LatticeStripe.Error reason atoms. Nothing that would break an existing correctly-typed call site.
  • Major (x.0.0) — breaking changes to the public API: removed or renamed functions, changed function signatures, removed struct fields, changed error type semantics, dropped Elixir/OTP version support.

This overrides the pre-1.0 rule from Phase 11 D-16. While the library was in 0.x, breaking changes were allowed in minor bumps. From v1.0.0 forward, that rule no longer applies — a breaking change requires a major bump, full stop. Pin to ~> 1.0 with confidence.

Deprecation policy

When a public API is scheduled for removal, LatticeStripe will mark the affected function or module with @deprecated in a minor release, accompanied by a CHANGELOG entry explaining the migration path. The deprecated surface continues to work normally until the next major release, at which point it may be removed.

Deprecation warnings are emitted by the Elixir compiler at call sites during mix compile. Treat them as a heads-up to plan migration before the next major — the deprecated call will not suddenly stop working inside the current major line.

See also