Using the REST API
Every endpoint follows the same conventions, so learning them once covers the whole surface. Per-endpoint request and response schemas are in the generated REST API reference; this page is the contract around them.
URL structure and audiences
Section titled “URL structure and audiences”Routes are api/v1/provision/... and split by audience:
| Area | Audience | Credential |
|---|---|---|
admin/* |
Back-office: catalog authoring, entitlement management, reporting | Admin-scoped client credentials |
operational/* |
Your backend automating lifecycle operations — issue codes, renew, top up | Operational-scoped client credentials |
| unmarked | The runtime surface your shipped application calls | Anonymous (activation) or license session token |
The split is deliberate: runtime endpoints never require an API secret, so nothing secret ships inside your application.
The runtime surface
Section titled “The runtime surface”What a shipped application (or the .NET SDK on its behalf) calls:
Activation & sessions
POST /activations/jwt— activate, returns the license token only.POST /activations/license— activate, returns token plus metadata (provider info, legal notices, verification key).POST /activations/{sessionId}/renew— extend the lease without re-activating.POST /activations/{sessionId}/check-in//release— heartbeat and seat release for floating and inactivity-based licenses.
Usage & metering
POST /usage/sessions/{sessionId}/transactions— batch usage upload.POST /usage/try-preallocate/{sessionId}/{metric}and/usage/try-consume/{sessionId}/{metric}?amount=— ask, then commit metered consumption where overuse must be blocked. The first changes nothing and reserves nothing; the second is the decision that binds.GET /usage/{sessionId}/{metric}/usageand/consumption— current usage snapshot and remaining balance.GET /usage/sessions/{sessionId}/rating-prompt— the next feature-rating prompt to show, if any.
Signed-in user self-service (/consumer/me/..., user token)
GET /consumer/me/sessions— the user’s active license sessions.GET /consumer/me/activation-codes— codes issued to the user.GET /consumer/me/entitlements/{entitlementId}/plansand/sessions/{sessionId}/plans— the plans behind a license, for in-app display.
Collections and paging
Section titled “Collections and paging”Collection endpoints return a shared envelope:
{ "items": [ … ], "pageNumber": 1, "pageSize": 25, "totalCount": 112, "totalPages": 5, "hasNextPage": true, "hasPreviousPage": false}Page with pageNumber (1-based) and pageSize (max 100). A pageSize above
the maximum is silently clamped to it, not rejected.
filter and sortOrder take Sieve expressions:
filter—Field==Valuefor equality,Field@=textfor contains; comma-separate terms and they are ANDed (name@=acme,status==Active).sortOrder—Fieldascending,-Fielddescending, comma-separated (-createdAt,name).
Filterable and sortable fields are whitelisted per endpoint — see the
REST API reference. An expression that doesn’t parse or
names a non-whitelisted field returns 400 license.validation_error.
Updates: PATCH vs PUT
Section titled “Updates: PATCH vs PUT”PATCH <collection>/{id}is a merge: send only the fields you’re changing; absent ornullfields stay untouched. Where a field must be explicitly cleared, the DTO documents a sentinel (e.g.clearExpirationDate).PUTreplaces the full editable representation — send everything.- Toggles and anything needing a payload on delete are
POST .../{id}/<action>(e.g.enable-activations/disable-activations).
Retries and idempotency
Section titled “Retries and idempotency”- Activation is retry-safe: re-activating with the same code and fingerprint returns the existing session, never a duplicate seat.
Idempotency-Keyheader (up to 200 characters) — send one on any mutating request you might retry. On the activation endpoints the key is durable: it persists on the session, a replay of an identical request returns the same session, and reusing the key with different parameters is rejected with409. On the operational balance mutations and the consumer credit grant the key is honored for 24 hours — a retry returns the original response.- Usage transactions carry their own ids and timestamps; upload batches can be retried after a network failure.
- Metered consumption (
try-consume) accepts anidempotentKeyquery parameter — a retried commit with the same key returns the original decision instead of consuming twice. - Pass
X-Correlation-Idon any request to correlate it across your logs and Oclavex’s — echo one id through a whole business operation. - When consuming webhooks, dedupe on the
webhook-idheader — delivery is at-least-once.
Errors
Section titled “Errors”Failures return application/problem+json with a stable numeric code and
dotted codeName:
{ "status": 404, "title": "Not Found", "detail": "The activation code does not map to an entitlement.", "code": 2004, "codeName": "license.not_found"}Branch on code or codeName — never on detail, which is human-facing prose
and may change. The full catalog is in
Error codes.