Skip to main content
Your organisation can license Player, Capture, Review and Report separately. One licence covers all installations of that SDK. Production and staging share licences and quota. Sandbox API keys cannot retrieve or issue licences. Every SDK accepts an API key and an optional licence JWT. Configure a production or staging key for your integration. The API key remains the credential for permitted inference and job requests. The licence JWT proves the right to use the specified SDK; it never replaces API key authentication. Configure key secrets at runtime rather than committing them to your source code. Licence scopes control API requests to retrieve, issue or renew proofs. If you supply a valid .jwt, local verification does not require a licence scope on the API key. Any inference, result or upload requests still require their own permissions.

Configure API key permissions in the Hub

An organisation owner or administrator can create keys and change their permissions.
1

Open API access

Select your organisation in the Hub. Open Api key & MCP, which displays the API access page. Click Create key, or click Permissions beside an existing key.
2

Choose the environment and SDK

For a new key, select Production or Staging. Choose the SDK licence profile as a starting point.This profile initially selects Manage licence for Capture only. Set the SDK you integrate to Manage licence and leave other SDKs at No access. Use Read licence instead when the SDK only needs to retrieve an already issued licence. Manage licence is the recommended setting for automatic creation and renewal.Replace {sdk} with player, capture, review or report.
3

Add inference access only when needed

If your integration calls CarHub models, select the required Inference endpoints. Search by endpoint name, slug or family to find them.Under Read results, choose Own jobs to read jobs created by this key and its rotation predecessors. Choose Organization jobs only if you need all jobs in the key’s live/test mode.Under Uploads & storage, enable Prepare inference inputs when you upload media for the selected endpoints. Leave Storage inventory at No inventory access unless your integration needs to inspect or delete stored uploads.Search filters do not remove your existing selections. Broad & legacy access also provides a family search when there are many families. General and family access grant wider permissions than individual endpoint selections.
4

Review and save

Check Access summary. When editing a key, review Changes to save, then click Save permissions. When creating a key, click Create key and copy its secret immediately.Permission changes apply to new API requests. Key rotation preserves the permissions. Removing a licence permission does not invalidate previously issued licence proofs.
A new key with no permissions has no business access. The general * permission grants no SDK licence access. Each SDK needs its own explicit licence scope. A licence permission alone does not guarantee a paid entitlement or an available quota slot.
You can inspect your backend key’s identity, organisation, environment, expiry and normalized permissions with GET /v1/api-keys/self. This endpoint is available to any valid key, even without business permissions. It never returns the secret and uses Cache-Control: no-store.

Download a licence from the Hub

Sign in with your Hub account and select the correct organisation. Downloading through the Hub uses your user session. You still configure an API key in the SDK; providing the downloaded .jwt skips automatic licence acquisition.
1

Open SDK licences

Open SDK licences in the sidebar. Check the selected SDK’s state, expiry and the organisation’s consumed and available slots.
2

Issue or renew if needed

If the SDK has no licence, an owner or administrator can click Issue. For an existing licence, click Renew for paid period after payment for the next period is confirmed, even if the previous proof is still active. A licence already covering the paid period is returned unchanged.Successful issuance or renewal downloads the signed file automatically. It consumes one slot for that distinct SDK in the paid period. Repeating a current attribution consumes no additional slot.
3

Download an active licence

Click Download licence to retrieve the current proof. For Capture, the downloaded file is capture.jwt.Organisation members can download an existing licence. Issuing, renewing and regenerating require an owner or administrator.
4

Provide the file to your SDK

Supply the original JWT text from the file, together with the API key, in your SDK configuration. Configure the expected SDK, organisation, issuer and trusted public keys separately.Licence loading and storage depend on your SDK implementation. The CarHub API defines the proof format; it does not provide an SDK-specific import method.
Regenerate signs and downloads the current attribution again. It does not extend its expiry or consume another slot. Use Renew for paid period for the next confirmed paid period. Downloading an expired licence does not reactivate it. Regeneration requires an active licence from the current paid period. If it returns 409 sdk_license_not_current, issue or renew the licence first.

Automatic acquisition by the SDK

If you do not supply a .jwt, the SDK obtains the licence itself. It can call GET /v1/api-keys/self to inspect the key’s organisation, environment and normalized permissions. General * access is insufficient for licence acquisition. For example, a Capture SDK configured with sdk:capture:write makes the equivalent of this request:
The SDK reads the signed JWT from license.proof, verifies it and retains it locally. It must not treat the complete JSON response as a JWT. The response also includes state, max_sdks, consumed and available. A successful GET can return an unassigned or expired licence; it does not guarantee a usable proof. Use GET /v1/sdk-licenses/capture with read or write permission to retrieve the stored licence without renewal. Send {"regenerate": true} to the POST endpoint only when you want to sign the current attribution again. All licence operations use the authenticated organisation. Do not supply an organisation identifier in the request. Licence proofs never authenticate calls to /v1/* or /mcp; use the API key for those calls.

What the SDK must implement

Load and retain the signed proof

Accept an API key in every SDK’s configuration. Accept an optional JWT as a file or string. These are configuration requirements, not an SDK-specific method signature. At initialization:
  1. If the user supplied a JWT, verify that proof locally. Report an invalid or expired supplied proof; do not silently replace an explicit user-supplied licence.
  2. If no JWT was supplied, reuse a valid locally cached proof for this SDK and organisation if one exists. Otherwise obtain the licence using the API key and the read/write behaviour above.
  3. Verify any acquired proof before enabling licensed SDK operations. Cache the proof and trusted verification keys according to the platform.
The SDK performs automatic acquisition itself; the user does not need to run curl or implement a separate licence request. Protect the configured API key in the application’s runtime and never include it in the downloaded .jwt file. When replacing a proof, verify the new one first. Retain the previous valid proof if retrieval or verification fails. Do not log a complete proof or an API key secret.

Verify locally before enabling licensed features

Retrieve public verification keys from GET /v1/sdk-licenses/jwks through a trusted connection before going offline. The response contains public Ed25519 keys with their kid. Select a trusted key by kid. Validate all of the following:
  • The JWT header uses alg: EdDSA, and the verification key uses Ed25519. Reject other algorithms.
  • The signature verifies against a trusted public key. Do not accept a key or verification URL supplied by the JWT itself.
  • iss exactly matches the issuer configured for your CarHub deployment.
  • aud matches carhub-sdk:{sdk}, for example carhub-sdk:capture.
  • version equals 1.
  • sdk matches the SDK you are running.
  • organization_id matches your application’s expected organisation.
  • license_id matches jti and identifies the stable licence.
  • nbf <= iat < exp, and the current time is within [nbf, exp). Do not accept the proof before nbf or extend its validity past exp.
Configure the expected organisation and issuer independently of the incoming proof. Decoding claims without verifying the signature does not establish trust. Use a reliable local clock and validate dates when the licence is used, including in an application that remains open past expiry.

Support verification key rotation

Keep trusted verification keys needed by unexpired proofs. When you receive an unknown kid, refresh keys through the trusted online path if available. If the required trusted key is unavailable offline, report that the licence cannot be verified. Never bypass verification.

Handle expiry and renewal explicitly

An offline SDK can use a valid proof until its exact paid expiry. No mandatory online licence check exists. At expiry, disable the licensed operation and provide a clear path to load a renewed proof. In automatic acquisition mode, the SDK can request renewal with the configured API key once the previous proof expires and payment for the next period is confirmed. Renewal requires sdk:{sdk}:write; read-only keys cannot renew. For a user-supplied .jwt, provide a clear way to load the renewed file downloaded from the Hub. The backend does not renew licences automatically. Use bounded retries for network failures; do not repeatedly retry invalid keys, missing scopes, unpaid subscriptions or quota refusals. Keep a still-valid cached proof usable during network failures. At expiry, network failure does not extend its validity. Report expired licences, missing trusted keys and API acquisition errors distinctly.

Quota and subscription changes

Check max_sdks in GET /v1/plans for the current catalogue; existing contracts retain their version’s terms. A licence covers every installation of its SDK. At paid expiry, the period’s consumed slots reset. Confirmed payment enables attribution for the new period. The first distinct SDKs requesting renewal obtain its slots. Cancellation preserves paid rights until expiry. A paid upgrade increases quota without resetting consumption. A scheduled downgrade applies to the next period’s quota. Revoking an API key blocks future requests through that key. It does not invalidate licence proofs already issued.

Troubleshooting