Skip to content
Documentation
English
Open the app

Check the licence

Step-by-step use case to read the licence of a firm through the API, find out its caps and its monthly estimate, and activate an activation key.

The licence of a firm determines its plan, its caps on companies and users and its billing estimate. Your integration can read it to check that a company can still be created, or to display the consumption in a dashboard.

Prerequisites: a token with the read ability, held by a member of the firm, and the public_token of the firm. Activating a key additionally requires write and the administrator or manager role.

Step 1: read the licence

curl "https://api.novafisko.com/v1/firms/Fd7hQ2mN8sXa/licence?lang=fr" \
  -H "Authorization: Bearer $NOVAFISKO_TOKEN"
{
  "status": "active",
  "subscription": {
    "id": 31,
    "status": "active",
    "billing_interval": "monthly",
    "current_period_start": "2026-10-01",
    "current_period_end": "2026-10-31",
    "trial_ends_at": null,
    "source": "licence_key",
    "billed": true,
    "pilot": {"active": false, "until": null}
  },
  "plan": {
    "code": "firm",
    "name": "Cabinet",
    "kind": "firm",
    "features": ["peppol", "document_import", "bank"],
    "base_price_monthly": 49.0,
    "tiers": [{"from": 1, "to": 10, "unit_price": 9.0}, {"from": 11, "to": null, "unit_price": 7.0}],
    "max_companies": null,
    "peppol_fair_use_per_company": 200,
    "annual_discount_pct": 10.0
  },
  "usage": {
    "month": "2026-10",
    "companies": 12,
    "users": 4,
    "bank_accounts": 15,
    "rows": [
      {"company_id": 318, "token": "k3Jd9fPq2LmX", "name": "Le Comptoir Montois SRL", "code": "COMPTOIR", "bank_accounts": 2, "status": "active", "activated_at": "2026-01-06T09:00:00+00:00", "deactivated_at": null}
    ],
    "max_companies": 25,
    "over_limit": false,
    "suggestion": null
  },
  "estimate": {
    "month": "2026-10",
    "base": 49.0,
    "companies_breakdown": [
      {"from": 1, "to": 10, "quantity": 10, "unit_price": 9.0, "total": 90.0},
      {"from": 11, "to": null, "quantity": 2, "unit_price": 7.0, "total": 14.0}
    ],
    "options": [],
    "discount": 0.0,
    "subtotal": 153.0,
    "vat_rate": 21.0,
    "vat_amount": 32.13,
    "total_incl_vat": 185.13,
    "billed": true
  },
  "next_month_preview": {"companies": 12, "total": 153.0},
  "over_limit": false,
  "limits": {"max_users": 10, "max_companies": 25, "users_count": 4, "companies_count": 12},
  "expires_at": "2027-09-30",
  "warning": null,
  "activation": {
    "key_masked": "NF-••••-••••-••••-7K2Q",
    "activated_at": "2026-01-06T08:55:12+00:00",
    "valid_until": "2027-09-30",
    "services": ["peppol", "document_import"]
  },
  "statements": [
    {"id": 904, "reference": "NF-2026-09-0031", "kind": "monthly", "period": "2026-09", "subtotal": 146.0, "vat_amount": 30.66, "total": 176.66, "status": "paid", "issued_at": "2026-10-01", "paid_at": "2026-10-03"}
  ],
  "options_available": [
    {"code": "extra_bank_account", "name": "Compte bancaire supplémentaire", "price_monthly": 2.0, "unit": "par compte"}
  ],
  "can_manage": true
}

The response is abridged: it also contains entitlements, companies_detail, comparison and a few legacy fields kept for older versions of the applications. The figures above are examples: the actual price list is published by GET /v1/pricing.

Fields useful to an integration

Field Usage
status none if the firm has no usable subscription, otherwise the status of the subscription
limits.max_companies, limits.companies_count Find out whether there is room left for a new company. null means no cap
limits.max_users, limits.users_count Same logic for team members
over_limit The firm exceeds the cap of its plan
expires_at End of validity of the activation key, null without a key
warning Warning to display (approaching deadline, cap exceeded), null otherwise
estimate Estimate for the current month, exclusive and inclusive of VAT
can_manage The user can activate or release a key
Note

Licence amounts are JSON numbers and not strings. They are commercial amounts and not accounting entries. See Conventions.

A user who is not a member of the firm receives 404.

Step 2: check before creating a company

def can_add_company(licence):
    limits = licence["limits"]
    if limits["max_companies"] is None:
        return True  # no ceiling on this plan
    return limits["companies_count"] < limits["max_companies"]

If you create a company anyway while the cap is reached, POST /v1/companies responds 422 with the company_limit_reached code. In the same way, adding a team member beyond the cap responds 422 with user_limit_reached.

Step 3: activate a key

An activation key has the form NF-XXXX-XXXX-XXXX-XXXX. It grants a plan, options and caps for a given duration.

curl -X POST https://api.novafisko.com/v1/firms/Fd7hQ2mN8sXa/licence/activate \
  -H "Authorization: Bearer $NOVAFISKO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"key": "NF-8H2K-P4QM-7TZD-7K2Q"}'

On success, the 200 response is the updated licence, in the same shape as in step 1. On refusal, the response is 422:

{
  "message": "Cette clé d'activation a expiré.",
  "code": "expired_key",
  "errors": {"key": ["Cette clé d'activation a expiré."]}
}
code Meaning
invalid_key Key unknown or mistyped
expired_key Key expired
exhausted_key Allowed number of activations already reached
key_reserved Key reserved for another firm
already_active Key already active on this firm

The route is limited to 10 attempts per minute.

Release a key

curl -X DELETE https://api.novafisko.com/v1/firms/Fd7hQ2mN8sXa/licence/activation \
  -H "Authorization: Bearer $NOVAFISKO_TOKEN"

The key becomes available again and the subscription that depends on it is cancelled. The response is the updated licence.

Warning

Activating and releasing a key are blocked in the demo firm (403, code demo_mode).

Public price list

Two public routes, without authentication, feed a simulator:

curl https://api.novafisko.com/v1/pricing
curl "https://api.novafisko.com/v1/pricing/simulate?companies=12"

Their detailed schema is in the reference.

See also