How do I install the inventory agent?
Quick answer
Section titled “Quick answer”In the Discovery module, under Inventory agents, create an enrollment token
(shown exactly once), download the notory_agent.py script via “Download
agent”, and run it on the endpoint with the environment variables NOTORY_URL
and NOTORY_TOKEN — once as a test, then on a schedule (Task Scheduler / cron /
launchd). The agent reports the operating system and installed software, and creates or
updates the asset automatically.
Prerequisites
Section titled “Prerequisites”Discovery module, from the Pro plan onward. On the endpoint, Python 3.8+ is enough — the reference script requires no extra packages and runs on Windows, Linux, and macOS. New devices count against your license’s asset limit.
Instructions
Section titled “Instructions”-
Open the “Inventory agents” section. Choose Discovery and scroll to the Inventory agents card. Under Name, give the token a label (e.g. “Sales laptops”) and click “Create token”.
Screenshot pendingdiscovery-agent-01The 'Inventory agents' card in the Discovery module with a name field and the 'Create token' buttonThe 'Inventory agents' card — this is where you create enrollment tokens. -
Copy the token immediately. Notory displays the token exactly once (“Enrollment token — copy it now, it will not be shown again”). It starts with
invagt_. Keep it safe — afterward, it can only be revoked, not shown again.Screenshot pendingdiscovery-agent-02One-time display of the newly created enrollment token with a copy buttonThe enrollment token is shown exactly once — copy it immediately. -
Download the agent. Click “Download agent” — you receive the
notory_agent.pyscript (identical for Windows, Linux, and macOS). -
Run it on the endpoint. Set the two environment variables and run the script as a test:
Windows (PowerShell) $env:NOTORY_URL = "https://demo.notory.io/api/v1"$env:NOTORY_TOKEN = "invagt_dein_token"python notory_agent.pyLinux / macOS export NOTORY_URL="https://demo.notory.io/api/v1"export NOTORY_TOKEN="invagt_dein_token"python3 notory_agent.pyOn success, the script reports
OK: 200 …. -
Schedule it. To keep the data current, schedule the call to run regularly — Windows: Task Scheduler (e.g. daily), Linux: cron (e.g.
@daily), macOS: launchd or cron. In the agent list, you see “Last seen” for each token; use Revoke to permanently deactivate a token.
Create an enrollment token (administrator, user token with the write scope). The
token field appears only in this one response:
curl -X POST https://demo.notory.io/api/v1/discovery/agent/enrollments \ -H "Authorization: Bearer inv_dein_token" \ -H "Content-Type: application/json" \ -d '{ "name": "Notebooks Vertrieb" }'{ "id": "0190f3d0-4a10-7b20-8c30-1d40e50f6a70", "tenant_id": "3d9b0c12-4e5a-4f88-b1c7-2a9e6d4f0011", "name": "Notebooks Vertrieb", "active": true, "last_seen_at": null, "created_at": "2026-07-08T11:00:00Z", "token": "invagt_9hK2mQx7Lp4RwT8vZn3cYd6fBs1gAj5u"}Download the agent script (administrator; os = windows, linux, or macos):
curl -H "Authorization: Bearer inv_dein_token" \ "https://demo.notory.io/api/v1/discovery/agent/download?os=linux" \ --output notory_agent.pySend a report — this is normally done by the agent itself; the call authenticates
with the enrollment token (invagt_…), not a user token:
curl -X POST https://demo.notory.io/api/v1/discovery/agent/report \ -H "Authorization: Bearer invagt_9hK2mQx7Lp4RwT8vZn3cYd6fBs1gAj5u" \ -H "Content-Type: application/json" \ -d '{ "machine_id": "4c4c4544-0042-3510-8054-b7c04f4d3732", "hostname": "NB-VERTRIEB-07", "os": "Windows", "os_version": "10.0.26200", "manufacturer": "Lenovo", "model": "ThinkPad T14 Gen 4", "serial_number": "PF-3X9K2L", "software": [ { "name": "Mozilla Firefox", "version": "140.0" }, { "name": "7-Zip", "version": "24.08" } ] }'{ "asset_id": "0190f3d1-5b20-7c30-9d40-2e50f60a7b81", "created": true, "software_count": 2}Revoke a token: POST /api/v1/discovery/agent/enrollments/{id}/revoke
(administrator). Afterward, the report endpoint responds with 401 for this token.
Possible errors: 401 (token missing, invalid, or revoked), 403 (not an
administrator, module not included in the plan, or asset limit reached for a new
device), 400 (unknown os on download), 422 (validation — e.g. missing
machine_id).
What happens behind the scenes?
Section titled “What happens behind the scenes?”- Agent authentication: The token is stored server-side only as a hash — which
is why it can never be viewed again after creation. Every report authenticates via
Authorization: Bearer invagt_…; a revoked token is immediately rejected with401. The token is permanently bound to your tenant. - Upsert instead of duplicate: The agent sends a stable
machine_id(Windows: MachineGuid, Linux:/etc/machine-id, macOS: IOPlatformUUID). Notory looks for an asset with this identifier (external_id): if found → update, otherwise → create (type Hardware, status Active, name = hostname). Repeated reports therefore don’t create duplicates. - License check (gating): Only new devices count against the asset limit; if it
has been reached, Notory rejects the report with
403. Updates to existing assets are always possible. - Stored data: Manufacturer, model, and serial number land in the core fields; OS,
OS version, IP address, and the software list (max. 2000 entries) go into the
asset’s custom fields, together with
agent_last_report(timestamp of the last report). - “Last seen”: With every report, Notory updates the token’s
last_seen_at— so you can see in the agent list which device fleet is actively reporting.