GH GambleHub

Technology and Infrastructure → API Versioning

API versioning

1) Why do you need it

Versioning is a manageable way to change contracts between services and customers without breakdowns. In products with a large number of integrations (payments, KYC/AML, games, billing, reporting), "old" and "new" customers live simultaneously. Correct version policy:
  • reduces the risk of incidents during releases,
  • allows you to schedule improvements and safety,
  • gives businesses predictable timelines for partner migrations.

2) Classification of changes

PATCH (not breaking): corrections without changing the contract (adding optional fields, validation fixes).
MINOR: back-compatible extensions (new endpoints, fields with default).
MAJOR (breaking): changing the structure, semantics or deleting fields/endpoints.

SemVer'MAJOR is recommended. MINOR. PATCH 'for artifacts (SDK/schemas), while the "external" API number can be simplified (v1, v2).

3) REST versioning models

1. TO URI:

`GET /v1/payments/{id}`

Pros: transparent, cachable, easy to route. Cons: duplication of documentation, more difficult to subtly evolve.

2. In the headers (content negotiation):

`Accept: application/vnd. company. payments. v2+json`

Pros: flexibility, no "garbage" in the URL, convenient evolution of the media type. Cons: it is more difficult to debug in the browser, you need a disciplined client.

3. In custom header:

`X-API-Version: 2` (или `Api-Version: 2025-09-01`)

Pros: just on the sluice. Cons: no standardness, careful with cache.

4. Date-based version:

Good for fintech/reporting: predictable "cuts" of change (e.g. quarterly).

5. Resource/Model Versioning:

The same endpoint can return different views: 'fields =...' or 'profile = litefull`. This is an addition, not a replacement for versioning.

Recommendation: for external integrations - 'URI vN' + Rejection/Sunset headers; for internal - you can'Accept 'or the version header, if the gateway and platform support it.

4) GraphQL

Preference - no global versions. Evolution through addition of fields/types and depriction ('@ deprecated (reason:... "")').
Breaking changes - only in "large" windows (versioned schema namespace) with migration guide.
Watch for "n + 1" and do not change the meaning of existing fields.

5) gRPC / Protobuf

Field numbers are immutable. Mark the deleted fields as' reserved '.
Add fields as optional with safe default.
Use buf breaking/lint for automatic compatibility checking.
Version packages/modules: 'package payments. v1;` → `payments. v2`.

6) Event APIs (EDA)

The event scheme is the same contract. Store it in the Schema Registry (Avro/JSON-Schema/Protobuf).
Topics and versions: 'payments. v1. authorized`, `payments. v2. authorized`.
Breaking changes - a new type of event or a new topic.
Evolution guarantees: backward-compatible for consumers during the LTS period.

7) Depriction Policy and EOL

Implement transparent rules:
  • Deprecation: labels in changelog and in specifications (OpenAPI/GraphQL SDL), header
  • 'Depression: true'and when possible' Sunset: Tue, 31 Mar 2026 00:00:00 GMT '.
  • Communications: email/partner portal, webhooks notifications, release notes.
  • Terms: MINOR - 3-6 months of support, MAJOR - 9-18 months (depending on criticality).
  • Time windows: fix in the "API Versioning Policy."

8) Routing and Releases

Gateway API (Kong/Apigee/Nginx/Envoy): rules by prefix '/v1/', by header or mediatype.

Example route:

if ($http_accept ~ "vnd.company.payments.v2") { proxy_pass http://payments-v2; }

Canary/Blue-Green/Shadow: roll the new version on 1-5% of traffic, compare metrics and logs of contract errors.
Feature Flags: Hide behavior without changing contract.
Zero-downtime migration: with MAJOR, provide dual-write/read of the data schema.

9) Contract testing and compatibility control

OpenAPI Diff (or swagger-diff) - Check that MINOR/PATCH do not break schemas.
Spectral linting - style, required metadata (version, Deprecation).
Consumer-Driven Contracts (Pact) - ensures that the provider does not break customers.
buf breaking для protobuf.
CI should fall in breaking changes without raising MAJOR.

10) Documentation and SDK

Version the specs: '/docs/api/v1/openapi. json`, `/docs/api/v2/…`.
Generate SDK by version (npm/maven/pypi) with SemVer and changelog.
Mark deprecated methods in the SDK with/Deprecated annotations.

11) Observation by version

Collect metrics separately:
  • RPS/latency/errors per version ('api _ version' label).
  • Endpoint usage maps: Who else is on v1?
  • Alerts: "> 10% 4xx due to contract mismatch," "old customers> X% after T-date."

12) Caching and versions

The in-transit version improves CDN cachability.

With header/media versions - carefully with Vary:
  • `Vary: Accept, X-API-Version`.
  • Do not change the semantics of the response in MINOR to break cache keys.

13) Safety

Do not encrypt or stitch the version into the JWT - the version is determined by the request, not the token.
Do not reveal internal assembly numbers. Use "v1/v2" for external messages.
In MAJOR, review validation, limits, PII masking.

14) Migrations and auto-helpers

Publish "Migration Guide v1 → v2": field mapping table, sample requests/responses, edge cases.
We offer linters for clients (CLI) that highlight outdated fields.
For large partners - sandbox with two versions and a test dataset.

15) Anti-patterns

"Eternal v1": lack of deadlines and usage metrics.
Hidden breaking changes in MINOR/PATCH.
"Version in query string" ('? v = 2') - breaks cache and readability.
"One endpoint is one hundred flag values": difficult to test/document.

16) Implementation checklist

1. Selected model (URI/Accept/Header) for external and internal clients.
2. SemVer for specifications and SDK, automatic breaking-check in CI.
3. Deprecation/Sunset policy and communication templates.
4. Gateway routing + canaries, dashboards by version.
5. CDC/Contract tests for critical integrations (payments, KYC, reporting).
6. The documentation/SDK/migration guide is published at the same time as the release.
7. EOL plan with dates and responsible.

17) Examples

17. 1 REST (URI + headers)

Request:

GET /v2/withdrawals/12345
Accept: application/json
Idempotency-Key: 4a1c-…-9f
Answer:
json
{
"id": "12345",
"status": "PENDING_REVIEW",
"amount": {"value": "100.00", "currency": "EUR"},
"limits": {"daily": "500.00"},
"created_at": "2025-10-02T10:00:00Z",
"links": [{"rel": "cancel", "href": "/v2/withdrawals/12345/cancel", "method": "POST"}]
}
Depriction headers (on v1):

Deprecation: true
Sunset: Tue, 31 Mar 2026 00:00:00 GMT
Link: </v2/docs>; rel="successor-version"

17. 2 Content Negotiation


GET /payments/987
Accept: application/vnd.company.payments.v2+json
Vary: Accept

17. 3 GraphQL (Field Depriction)

graphql type Payment {
id: ID!
amount: Money!
status: PaymentStatus!
method: PaymentMethod!
legacyCode: String @deprecated(reason: "Use field `method`")
}

17. 4 gRPC (protobuf)

proto package payments.v2;

message Withdrawal {
string id = 1;
Money amount = 2;
string status = 3; // previously enum, now string with documented values reserved 4; // legacy field removed in v1 -> v2
}

17. 5 Event model

Topics:
  • `wallet. v1. balance. updated`
  • `wallet. v2. balance. changed '(new event with extended schema)

Schemes are stored in Registry, the producer does not publish events with a scheme that violates compatibility.

18) Context iGaming/fintech (practice)

Payments: input v2 for new PSPs where 'status '/' decline _ reason' is extended; on the gateway, mapping v1 → v2 for reporting.
KYC: MINOR adds field 'pep _ screening', clients ignore v1, v2 - requires.
Responsible games/limits: MAJOR changes the limits model (daily/weekly). Double export to reporting before EOL v1.
Reporting to regulators: fixed versions-dates: 'reporting-2025-01'.

19) Mini-policy (example for wiki)

Model: for external APIs - 'URI/vN/'; for internal - 'Accept:... vN + json' or 'X-API-Version: N'.
SemVer: Specifications and SDKs are published as'N. minor. patch`. MAJOR requires RFC/ADR.
Compatibility: MINOR/PATCH - no breaking changes. Breaking → only through MAJOR.
Deprecation/EOL: ≥90-day announcement; Sunset-date in headlines; LTS branch for critical customers.
Control: OpenAPI diff/buf breaking in CI, CDC for key integrations.
Observability: metrics/logs with label 'api _ version'.
Releases: canary 5% ≥ 24h, then in stages to 100% with green metrics.


Result

Versioning is not about "/v2 in URL, "but about the process: explicit rules of evolution, automatic compatibility checks, managed releases and respect for integrations. Enter a clear policy, automate monitoring and observability - and changes will no longer be a threat to the product.

Contact

Get in Touch

Reach out with any questions or support needs.We are always ready to help!

Start Integration

Email is required. Telegram or WhatsApp — optional.

Your Name optional
Email optional
Subject optional
Message optional
Telegram optional
@
If you include Telegram — we will reply there as well, in addition to Email.
WhatsApp optional
Format: +country code and number (e.g., +380XXXXXXXXX).

By clicking this button, you agree to data processing.