AI Model Versioning and Licensing on a Marketplace
Consider this: when an AI model marketplace processes thousands of requests daily and releases updates weekly, manual version and license management becomes a bottleneck. We encountered a situation: a client released a new major version of an anomaly detector without notifying consumers. Production pipelines collapsed due to format incompatibility — recovery took two days and cost $50,000 in losses. After that, we developed a systematic approach that eliminates such incidents: over 5 years of operation across three marketplaces, we achieved 99.9% successful migrations, and the client saved over $100,000 in the first year.
The core issue is that SemVer, borrowed from software development, doesn't account for ML specifics: changing weights can radically alter model behavior. Therefore, we adapted semantic versioning for ML, tying it to benchmarks and compatibility. Alongside versioning, licensing must be thought through: who can use the model, what restrictions apply, and how compliance is tracked. Without this, providers risk losing control over model distribution.
Why SemVer Needs Adaptation for ML
Standard SemVer (major.minor.patch) is insufficient for AI models. Changing weights or architecture can drastically affect behavior, so we use ML-specific semantics that account for benchmarks and compatibility. In practice, this reduces incidents by an order of magnitude — from 12 to 1 per year per marketplace.
- Major (2.0.0): fundamentally different architecture, incompatible input/output formats, significantly different behavior. Example: switching backbone from ResNet to ViT.
- Minor (1.3.0): fine-tuning on new data, metric improvements, backward-compatible changes. For instance, detection accuracy increased by 2.3% with the same latency p99.
- Patch (1.2.1): fixing specific bugs, micro-optimizations, no API changes.
| Change | Impact on Accuracy | Impact on Latency p99 | Backward Compatibility |
|---|---|---|---|
| Major | >5% | >20% | ❌ |
| Minor | 1-5% | 5-20% | ✅ |
| Patch | <1% | <5% | ✅ |
The code below shows a version structure and manager that automatically compares benchmarks on each release:
from dataclasses import dataclass
from enum import Enum
class ChangeType(Enum):
MAJOR = "major"
MINOR = "minor"
PATCH = "patch"
@dataclass
class ModelVersion:
major: int
minor: int
patch: int
release_notes: str
breaking_changes: list[str]
improvements: list[str]
benchmark_deltas: dict # {"accuracy": +0.02, "latency_ms": -5}
compatibility: dict # {"backward": True, "api_version": "v2"}
def __str__(self):
return f"{self.major}.{self.minor}.{self.patch}"
@property
def is_stable(self):
return self.major > 0 and not self.is_prerelease
class ModelVersionManager:
def create_version(self, model_id: str, artifacts: ModelArtifacts,
change_type: ChangeType) -> ModelVersion:
current = self.get_latest(model_id)
if change_type == ChangeType.MAJOR:
new = ModelVersion(current.major + 1, 0, 0, ...)
elif change_type == ChangeType.MINOR:
new = ModelVersion(current.major, current.minor + 1, 0, ...)
else:
new = ModelVersion(current.major, current.minor, current.patch + 1, ...)
# Automatic benchmark comparison
new.benchmark_deltas = self.compare_benchmarks(current, artifacts)
return new
License Types and Their Parameters
Each model on the marketplace is tied to one of four licenses. We implemented a flexible system that allows providers to set rights and restrictions.
| License Type | Commercial Use | Attribution | Modification | Max Requests/Month | On-Premise |
|---|---|---|---|---|---|
| Community | ❌ | ✅ | ✅ | 10,000 | ❌ |
| Developer | ✅ | ❌ | ✅ | up to 100,000 | ❌ |
| Professional | ✅ | ❌ | ✅ | unlimited | ❌ |
| Enterprise | ✅ | ❌ | ✅ | unlimited | ✅ |
class LicenseType(Enum):
COMMUNITY = "community" # Free, non-commercial use
DEVELOPER = "developer" # Commercial, up to N req/month
PROFESSIONAL = "professional" # Unlimited, SLA 99.9%
ENTERPRISE = "enterprise" # On-premise, custom terms
@dataclass
class License:
type: LicenseType
commercial_use: bool
attribution_required: bool
modification_allowed: bool
redistribution_allowed: bool
derivative_models_allowed: bool
on_premise_allowed: bool
max_monthly_requests: int = None # None = unlimited
geographic_restrictions: list[str] = None
STANDARD_LICENSES = {
LicenseType.COMMUNITY: License(
type=LicenseType.COMMUNITY,
commercial_use=False,
attribution_required=True,
modification_allowed=True,
redistribution_allowed=False,
derivative_models_allowed=False,
on_premise_allowed=False,
max_monthly_requests=10_000
),
LicenseType.ENTERPRISE: License(
type=LicenseType.ENTERPRISE,
commercial_use=True,
attribution_required=False,
modification_allowed=True,
redistribution_allowed=False,
derivative_models_allowed=True,
on_premise_allowed=True,
max_monthly_requests=None
)
}
Providers can additionally restrict geography (e.g., EU/US only), device type (cloud/on-premise), and prohibit derivative models. For Enterprise licenses, we support custom terms with dedicated SLA 99.95% and 24/7 support. All licenses are enforced at the API gateway before each inference.
How the Deprecation Window Works
The lifecycle policy includes several stages:
- Publication of a new major version — the previous one is marked deprecated.
- Notifications sent to all consumers (email + in-app) 6 months before sunset.
- A migration guide with a checklist of breaking changes is provided.
- Automated compatibility testing of old requests against the new version (98% coverage).
- The old version is disabled after 12 months (with extension possible upon mutual agreement).
Detailed notification and migration process
We send automatic notifications at 6, 3, and 1 month before sunset, attaching a migration guide and recommending alternatives. If a consumer needs more time, extension is negotiated individually. This approach provides predictability: consumers know they have at least a year to migrate, while providers can evolve models without breaking downstream systems.Specifying Version in API Requests
We implemented a URL template /v1/models/{model_id}@{version}/predict. Consumers can specify an exact version (1.2.3) or an alias: latest, stable, 2.x (latest major). The resolver under the hood transforms the alias into a concrete number, and when a deprecated version is requested, a warning is returned.
# Consumer explicitly specifies version in API request
@app.post("/v1/models/{model_id}@{version}/predict")
async def predict_versioned(model_id: str, version: str, request: PredictRequest):
# Support aliases: "latest", "stable", "2.x" (latest 2.x version)
resolved_version = version_resolver.resolve(model_id, version)
return await inference_gateway.run(model_id, resolved_version, request)
# Deprecation notifications
async def check_deprecated_version_usage(model_id: str, version: str):
version_info = await version_registry.get(model_id, version)
if version_info.deprecated_at:
sunset_date = version_info.sunset_date
days_left = (sunset_date - datetime.utcnow()).days
return {
"deprecated": True,
"message": f"Version {version} deprecated. Sunset in {days_left} days.",
"recommended_version": version_info.replacement
}
Scope of Work
We deliver a turnkey solution:
- Documentation: description of versioning scheme, API, instructions for providers and consumers.
- Version registry with benchmarks and release notes.
- License key generator and integration with the API gateway.
- Usage and royalty monitoring dashboard (request count, tokens, errors, latency p99).
- CI/CD integration: automatic version creation on Git tag push.
- Team training and support during deployment (2 weeks of handholding).
Automating versioning and licensing dramatically reduces the time to release new versions and virtually eliminates compatibility incidents. Consumers get a predictable migration schedule, and providers get transparent royalty tracking.
Our Competencies and Guarantees
We have over 10 years of experience in ML production: we built the system for three AI marketplaces processing up to 10 million requests daily. Our solution reduced version compatibility incidents by 95% compared to manual management. We guarantee licensing transparency and API stability even under 99.9% load. Contact us for a consultation — we will prepare an architecture and timeline (4 to 12 weeks) based on your specifics. Order the system implementation and get a first draft of the architecture within a week.







