Skip to content
novilDevelopersOpen Novil
Getting startedAuthentication

Authentication

Every request to the Novil API is authenticated with an API key sent as a bearer token:

Authorization: Bearer nvl_live_7Hq2mV9sKd3pL0aXbR8tYw4nZc6eFg1h

There are no sessions, cookies or OAuth flows. A key identifies the company it belongs to and carries the scopes it was created with.

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 by GET /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/me reports the key’s expiresAt, or null for 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.

Call GET /v1/me with a fresh key to confirm it works and to see what it can do:

Describe the current key
curl https://app.novilfleet.com/v1/me \
-H "Authorization: Bearer $NOVIL_API_KEY"
200 OK
{
"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.

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.

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.

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.

  • Send keys only in the Authorization header, 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.