Licensing¶
Semvec ships as a single wheel gated by an Ed25519-signed JWT. Community tier works without a key but is rate-limited; Pro and Enterprise require a license issued by the Versino licensing server.
Tiers¶
| Tier | Rate limit | Backends | Retrieval modes |
|---|---|---|---|
| Community (no key) | 5 QPS sustained / 50 burst | In-memory only | Base retrieval |
| Pro | 200 / 2000 QPS | All | Extended |
| Enterprise | Unthrottled | All | All |
Rate limits are enforced in-process via a token-bucket algorithm backed by parking_lot::Mutex + DashMap (one bucket per license key, monotonic clock from std::time::Instant).
Activating a license¶
Set the environment variable before importing semvec:
Keys are Ed25519-signed JWTs with a 30-day TTL. The embedded public key is baked into the wheel at build time via include_bytes!.
Claims schema¶
products: array of strings naming the products this key unlocks.tier:"Community","Pro", or"Enterprise".exp: Unix timestamp (seconds) when the key expires.
Missing product, wrong signature, and expired timestamps all produce descriptive errors.
Error handling¶
from semvec import RateLimitError, LicenseExpiredError
try:
result = state.update(embedding, text)
except RateLimitError as e:
# e.retry_after is a datetime.timedelta
time.sleep(e.retry_after.total_seconds())
result = state.update(embedding, text)
except LicenseExpiredError as e:
logger.warning("semvec license expired — renew at %s", e.upgrade_url)
raise
Both exceptions inherit from LicenseError, which inherits from the base SemvecError. Every PSS-specific exception (ConfigurationError, EmbeddingError, StateCorruptionError, …) is preserved from the pss reference.
For regulated deployments¶
Need offline license validation or a custom public-key rotation schedule? Contact support@versino.de for Enterprise deployment options including:
- Air-gapped license issuance
- Custom TTL policies
- Hardware-backed signing
- SBOM + provenance attestations