Skip to content

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.

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.

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}/usage and /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}/plans and /sessions/{sessionId}/plans — the plans behind a license, for in-app display.

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:

  • filterField==Value for equality, Field@=text for contains; comma-separate terms and they are ANDed (name@=acme,status==Active).
  • sortOrderField ascending, -Field descending, 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.

  • PATCH <collection>/{id} is a merge: send only the fields you’re changing; absent or null fields stay untouched. Where a field must be explicitly cleared, the DTO documents a sentinel (e.g. clearExpirationDate).
  • PUT replaces the full editable representation — send everything.
  • Toggles and anything needing a payload on delete are POST .../{id}/<action> (e.g. enable-activations / disable-activations).
  • Activation is retry-safe: re-activating with the same code and fingerprint returns the existing session, never a duplicate seat.
  • Idempotency-Key header (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 with 409. 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 an idempotentKey query parameter — a retried commit with the same key returns the original decision instead of consuming twice.
  • Pass X-Correlation-Id on 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-id header — delivery is at-least-once.

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.