Authentication
Every request to the Novil API is authenticated with an API key sent as a bearer token:
Authorization: Bearer nvl_live_7Hq2mV9sKd3pL0aXbR8tYw4nZc6eFg1hThere are no sessions, cookies or OAuth flows. A key identifies the company it belongs to and carries the scopes it was created with.
Creating a key
Section titled “Creating a key”Keys are created in the Novil app under Settings › API Keys (app.novilfleet.com/settings/api-keys). When you create one you choose:
- A name, such as the system that will use it (
McLeod dispatch). The name is for your benefit and is returned byGET /v1/me. - An environment: live or sandbox. This decides the key’s prefix and what it acts on; see below.
- Scopes: which endpoints the key may call.
- An optional expiry. An expired key is rejected with
401 unauthorized.GET /v1/mereports the key’sexpiresAt, ornullfor keys that do not expire.
The full key is shown once, at creation. Copy it into your secret store straight away; Novil keeps only a hash and cannot show it again. If a key is lost, revoke it and create a new one.
Each key also has a short prefix (the first characters of the key, for example nvl_live_7Hq2) that is safe to log and that GET /v1/me returns, so you can tell keys apart without exposing them.
Verifying a key
Section titled “Verifying a key”Call GET /v1/me with a fresh key to confirm it works and to see what it can do:
curl https://app.novilfleet.com/v1/me \ -H "Authorization: Bearer $NOVIL_API_KEY"{ "company": { "id": "titus_transportation", "name": "Titus Transportation", "timeZone": "America/Chicago" }, "key": { "id": "ak_7Hq2mV9sKd3pL0aX", "name": "McLeod dispatch", "prefix": "nvl_live_7Hq2", "environment": "live", "scopes": ["routes:write", "vehicles:read", "drivers:read"], "createdAt": "2026-09-02T15:04:11Z", "expiresAt": null }, "rateLimit": { "limit": 600, "window": "1m" }}GET /v1/me needs no particular scope; any valid key can call it.
Scopes
Section titled “Scopes”A key only reaches the endpoints its scopes allow. Calling an endpoint without the right scope returns 403 with the code insufficient_scope, and the detail names the scope that is missing.
| Scope | Allows |
|---|---|
routes:write |
POST /v1/routes and DELETE /v1/routes/{id}: pushing, updating and canceling routes. |
routes:read |
GET /v1/routes and GET /v1/routes/{id}: reading routes, including the fuel plan each one carries. |
vehicles:read |
GET /v1/vehicles: listing vehicles and checking unit numbers and VINs. |
drivers:read |
GET /v1/drivers: listing drivers and checking names. |
Give a key the smallest set of scopes that covers what its system does. A dispatch integration that pushes loads and polls for plans needs routes:write and routes:read; add vehicles:read and drivers:read if it checks unit numbers and driver names before pushing. A reporting job that only reads plans needs routes:read alone.
Live and sandbox keys
Section titled “Live and sandbox keys”The key’s environment is visible in its prefix and in the environment field of GET /v1/me:
| Prefix | Environment | Acts on |
|---|---|---|
nvl_live_ |
live |
Your fleet. Routes pushed with a live key are real: when the truck arrives at the first stop, the driver gets a fuel plan. |
nvl_test_ |
sandbox |
Your sandbox copy. Routes are created and can be read back, but nothing is ever sent to a driver. |
Both environments use the same base URL and the same endpoints; only the key differs. Routes carry an environment field so you can always tell which copy a route lives in. See Sandbox testing for a suggested workflow.
Failed authentication
Section titled “Failed authentication”| Status | Code | Cause |
|---|---|---|
401 |
unauthorized |
No Authorization header, a malformed one, or a key that has been revoked or has expired. |
403 |
insufficient_scope |
The key is valid but was not created with the scope the endpoint needs. |
Both are returned as problem details. A 401 is never a transient condition: do not retry it, check the key.
Keeping keys safe
Section titled “Keeping keys safe”- Send keys only in the
Authorizationheader, over HTTPS, never in a query string or a request body. - Store them in your secret manager, not in source control or in the TMS’s configuration UI where they can be read back.
- Create one key per integrating system so that revoking one does not break another.
- Revoke keys you no longer use under Settings › API Keys. Revocation takes effect immediately.