{"id":213,"date":"2026-03-09T14:28:11","date_gmt":"2026-03-09T14:28:11","guid":{"rendered":"https:\/\/underwoodtechnologies.com\/?p=213"},"modified":"2026-03-21T13:53:45","modified_gmt":"2026-03-21T13:53:45","slug":"getting-started-with-truenas-api","status":"publish","type":"post","link":"https:\/\/underwoodtechnologies.com\/?p=213","title":{"rendered":"Getting started with TrueNAS API"},"content":{"rendered":"\n<p>I)Introduction and pre-requisites<br>One of the ambitions of my homelab is to start working with APIs more. I would like to start trying to integrate TrueNAS into my Proxmox Environment deeper than it is currently, perhaps even start dabbling with GUI elements at some point. <br><br>To be quite honest, I feel less than impressed with the documentation TrueNAS provides around their API and how to get started with it. I am admittedly not a developer, but it seems sparse at best. Google Gemini has been helpful with this gap as of now, especially around things like syntax. <br><br>I&#8217;ll start by linking some of the documentation:<br><a href=\"https:\/\/github.com\/truenas\/api_client\/tree\/master\/examples\">https:\/\/github.com\/truenas\/api_client\/tree\/master\/examples<\/a><br>If you have a TrueNAS machine the API is documented offline as well:<br><a href=\"http:\/\/yourip.server.local\/api\/docs\/current\/\">http:\/\/&lt;SERVERIP>\/api\/docs\/current\/<\/a><br>If you don&#8217;t have access to the machine, you can get it here:<br><a href=\"https:\/\/api.truenas.com\/\">https:\/\/api.truenas.com\/<\/a><br><br>A few words on versions of TrueNAS Software. The API has changed as of 25.04, and seems to have had some fixes included in the standard releases. If you&#8217;re using the API and your version is below 25.04 it is advised to understand the implications of upgrading as per the documentation <a href=\"https:\/\/www.truenas.com\/docs\/scale\/api\/\" data-type=\"link\" data-id=\"https:\/\/www.truenas.com\/docs\/scale\/api\/\">here.<\/a> If you are not running APIs and\/or are on a newer version than 25.04, upgrading is advised. This can be done easily from the GUI by going to System->Update. The screen shots in this post are from 25.10.2.1.<\/p>\n\n\n\n<p>II)Configuring TrueNAS<\/p>\n\n\n\n<p>To run API based commands, a user must have an API key created against it. truenas_admin can be used for this, however there are key reasons not to. The first reason is that it is better to create a key for every interaction source for logging reasons. The second is that access can be limited for certain functions. As an example, a monitoring system should not be provisioning storage and doesn&#8217;t need read-write access.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1023\" height=\"465\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/009_iscsi_portal_create-1.png\" alt=\"\" class=\"wp-image-215\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/009_iscsi_portal_create-1.png 1023w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/009_iscsi_portal_create-1-300x136.png 300w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/009_iscsi_portal_create-1-768x349.png 768w\" sizes=\"auto, (max-width: 1023px) 100vw, 1023px\" \/><\/figure>\n\n\n\n<p><br>One of the nice things I can say about the documentation is it includes the roles that are required for a method within the page of that method. The example above is for the iscsi.portal.create method. There is a lot of granularity, which more advanced users in production environments will appreciate.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"478\" height=\"544\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/010_grp_menu.png\" alt=\"\" class=\"wp-image-217\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/010_grp_menu.png 478w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/010_grp_menu-264x300.png 264w\" sizes=\"auto, (max-width: 478px) 100vw, 478px\" \/><\/figure>\n\n\n\n<p>To create a new privilege, go to Credentials-&gt;Groups.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"239\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/011_privileges-1024x239.png\" alt=\"\" class=\"wp-image-218\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/011_privileges-1024x239.png 1024w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/011_privileges-300x70.png 300w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/011_privileges-768x179.png 768w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/011_privileges-1536x358.png 1536w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/011_privileges.png 1921w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>From the Groups menu, click on Privileges. This will open the Privileges menu.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"237\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/012_priv_add-1024x237.png\" alt=\"\" class=\"wp-image-219\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/012_priv_add-1024x237.png 1024w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/012_priv_add-300x69.png 300w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/012_priv_add-768x178.png 768w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/012_priv_add-1536x355.png 1536w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/012_priv_add.png 1902w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Click add to add a new privilege.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"479\" height=\"909\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/013_new_privilege.png\" alt=\"\" class=\"wp-image-220\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/013_new_privilege.png 479w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/013_new_privilege-158x300.png 158w\" sizes=\"auto, (max-width: 479px) 100vw, 479px\" \/><\/figure>\n\n\n\n<p>Within the menu give a name. Assigning a local group is optional, and can be done from within the group later or done at user creation if a new group is created for that user. Check the desired roles, then confirm the selection. Due to this being a non-production system, a default administrator role will be used in this post.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"478\" height=\"544\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/001_user_menu.png\" alt=\"\" class=\"wp-image-221\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/001_user_menu.png 478w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/001_user_menu-264x300.png 264w\" sizes=\"auto, (max-width: 478px) 100vw, 478px\" \/><\/figure>\n\n\n\n<p>To create the API user, go to Credentails-&gt;Users.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"455\" height=\"965\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/002_create_user.png\" alt=\"\" class=\"wp-image-222\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/002_create_user.png 455w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/002_create_user-141x300.png 141w\" sizes=\"auto, (max-width: 455px) 100vw, 455px\" \/><\/figure>\n\n\n\n<p>Creation of a new user has multiple items. Shell access is required for API function, although it is noteworthy that this is not SSH access. TrueNAS will let you make an API key without shell access enabled for an account, and it won&#8217;t work. A password can be set, but it is advised to leave it disabled for security reasons. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"277\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/014_group_edit-1-1024x277.png\" alt=\"\" class=\"wp-image-225\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/014_group_edit-1-1024x277.png 1024w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/014_group_edit-1-300x81.png 300w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/014_group_edit-1-768x208.png 768w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/014_group_edit-1-1536x416.png 1536w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/014_group_edit-1.png 1648w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>If an existing group wasn&#8217;t used, or if the user&#8217;s group wasn&#8217;t added to the privilege on its creation, go to the Groups menu. Expand the group, and click Edit.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"471\" height=\"760\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/016_alter_privileges.png\" alt=\"\" class=\"wp-image-226\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/016_alter_privileges.png 471w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/016_alter_privileges-186x300.png 186w\" sizes=\"auto, (max-width: 471px) 100vw, 471px\" \/><\/figure>\n\n\n\n<p>Privileges can be altered from the menu. Select the desired level of access and save. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"670\" height=\"457\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/003_api_key_credentials.png\" alt=\"\" class=\"wp-image-227\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/003_api_key_credentials.png 670w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/003_api_key_credentials-300x205.png 300w\" sizes=\"auto, (max-width: 670px) 100vw, 670px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"729\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/015_APK_Key_menu-1024x729.png\" alt=\"\" class=\"wp-image-228\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/015_APK_Key_menu-1024x729.png 1024w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/015_APK_Key_menu-300x214.png 300w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/015_APK_Key_menu-768x547.png 768w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/015_APK_Key_menu.png 1197w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>After this is done it is time to create the API keys. There are a few ways to access the API key menu, the easiest is to probably just search for API and go to Credentials-&gt;Users-&gt;API Keys although you can click through to the menu by opening up a user then clicking on the &#8220;API Keys&#8221; option.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"133\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/005_add_api_keys-1-1024x133.png\" alt=\"\" class=\"wp-image-230\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/005_add_api_keys-1-1024x133.png 1024w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/005_add_api_keys-1-300x39.png 300w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/005_add_api_keys-1-768x100.png 768w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/005_add_api_keys-1-1536x199.png 1536w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/005_add_api_keys-1.png 1659w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Add a new API key.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"479\" height=\"562\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/006_add_api_key.png\" alt=\"\" class=\"wp-image-231\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/006_add_api_key.png 479w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/006_add_api_key-256x300.png 256w\" sizes=\"auto, (max-width: 479px) 100vw, 479px\" \/><\/figure>\n\n\n\n<p>Give the key a name, choose a user to associate the execution of API commands with then select okay. If a role is for a limited period of time, the API key can be set to expire. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"550\" height=\"352\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/007_api_key.png\" alt=\"\" class=\"wp-image-232\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/007_api_key.png 550w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/007_api_key-300x192.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/figure>\n\n\n\n<p>After confirming options, the key will be presented. <strong>As the notes say, this is the only time this key will be shown.<\/strong> If the key is lost, it will  have to be regenerated via the &#8220;Reset&#8221; option. The number at the beginning is the number of API keys that have been generated. <\/p>\n\n\n\n<p>III)Running Some API Commands<\/p>\n\n\n\n<p>Now that the keys have been made and permissions set, lets run some commands. <\/p>\n\n\n\n<p><em>midclt &#8211;uri wss:\/\/192.168.100.128\/api\/current &#8211;insecure -K \/home\/user\/Documents\/Homelab\/apikey6 call disk.temperatures &#8216;[&#8220;sda&#8221;,&#8221;sdb&#8221;,&#8221;sdc&#8221;,&#8221;sdd&#8221;,&#8221;sde&#8221;,&#8221;sdf&#8221;]&#8217; | jq<\/em><br><br>This doesn&#8217;t look like code! Yeah, I&#8217;m kind of cheating here. For a test this is more than good enough, and for a lot of sysadmins this will also be an adequate way of interacting with the API. Going into midclt it&#8217;s a wrapper for calling API functions. In my system this returns nulls, because I&#8217;m using passed through disks. jq is used to make the formating human readable instead of a jumbled mess.<br><br><em>midclt &#8211;uri wss:\/\/192.168.100.128\/api\/current &#8211;insecure -K \/home\/user\/Documents\/Homelab\/apikey6 call disk.details | jq<br>{<br>&#8220;used&#8221;: [<br>{<br>&#8220;name&#8221;: &#8220;sda&#8221;,<br>&#8220;sectorsize&#8221;: 512,<br>&#8220;number&#8221;: 2048,<br>&#8220;subsystem&#8221;: &#8220;scsi&#8221;,<br>&#8220;driver&#8221;: &#8220;sd&#8221;,<br>&#8220;hctl&#8221;: &#8220;0:0:0:0&#8221;,<br>&#8220;size&#8221;: 34359738368,<br>&#8220;mediasize&#8221;: 34359738368,<br>&#8220;vendor&#8221;: &#8220;QEMU&#8221;,<br>&#8220;ident&#8221;: &#8220;drive-scsi0&#8221;,<br>&#8220;serial&#8221;: &#8220;drive-scsi0&#8221;,<br>&#8220;model&#8221;: &#8220;QEMU_HARDDISK&#8221;,<br>&#8220;descr&#8221;: &#8220;QEMU_HARDDISK&#8221;,<br>&#8220;lunid&#8221;: null,<br>&#8220;bus&#8221;: &#8220;SCSI&#8221;,<br>&#8220;type&#8221;: &#8220;HDD&#8221;,<br>&#8220;blocks&#8221;: 67108864,<br>&#8220;serial_lunid&#8221;: null,<br>&#8220;rotationrate&#8221;: null,<br>&#8220;stripesize&#8221;: null,<br>&#8220;parts&#8221;: [],<br>&#8220;dif&#8221;: false,<br>&#8220;identifier&#8221;: &#8220;{serial}drive-scsi0&#8221;,<br>&#8220;enclosure&#8221;: {},<br>&#8220;partitions&#8221;: [],<br>&#8220;devname&#8221;: &#8220;sda&#8221;,<br>&#8220;exported_zpool&#8221;: null,<br>&#8220;imported_zpool&#8221;: &#8220;boot-pool&#8221;,<br>&#8220;duplicate_serial&#8221;: []<br>},<br>.<br>.<br>.<br>.<\/em><br><br>Without using jq, the output looks like:<br><em>midclt &#8211;uri wss:\/\/192.168.100.128\/api\/current &#8211;insecure -K \/home\/user\/Documents\/Homelab\/apikey6 call disk.details<br>{&#8220;used&#8221;: [{&#8220;name&#8221;: &#8220;sda&#8221;, &#8220;sectorsize&#8221;: 512, &#8220;number&#8221;: 2048, &#8220;subsystem&#8221;: &#8220;scsi&#8221;, &#8220;driver&#8221;: &#8220;sd&#8221;, &#8220;hctl&#8221;: &#8220;0:0:0:0&#8221;, &#8220;size&#8221;: 34359738368, &#8220;mediasize&#8221;: 34359738368, &#8220;vendor&#8221;: &#8220;QEMU&#8221;, &#8220;ident&#8221;: &#8220;drive-scsi0&#8221;, &#8220;serial&#8221;: &#8220;drive-scsi0&#8221;, &#8220;model&#8221;: &#8220;QEMU_HARDDISK&#8221;, &#8220;descr&#8221;: &#8220;QEMU_HARDDISK&#8221;, &#8220;lunid&#8221;: null, &#8220;bus&#8221;: &#8220;SCSI&#8221;, &#8220;type&#8221;: &#8220;HDD&#8221;, &#8220;blocks&#8221;: 67108864, &#8220;serial_lunid&#8221;: null, &#8220;rotationrate&#8221;: null, &#8220;stripesize&#8221;: null, &#8220;parts&#8221;: [], &#8220;dif&#8221;: false, &#8220;identifier&#8221;: &#8220;{serial}drive-scsi0&#8221;, &#8220;enclosure&#8221;: {}, &#8220;partitions&#8221;: [], &#8220;devname&#8221;: &#8220;sda&#8221;, &#8220;exported_zpool&#8221;: null, &#8220;imported_zpool&#8221;: &#8220;boot-pool&#8221;, &#8220;duplicate_serial&#8221;: []}, {&#8220;name&#8221;: &#8220;sdb&#8221;, &#8220;sectorsize&#8221;: 512, &#8220;number&#8221;: 2064, &#8220;subsystem&#8221;: &#8220;scsi&#8221;, &#8220;driver&#8221;: &#8220;sd&#8221;, &#8220;hctl&#8221;: &#8220;1:0:0:2&#8221;, &#8220;size&#8221;: 1199705161728, &#8220;mediasize&#8221;: 1199705161728, &#8220;vendor&#8221;: &#8220;QEMU&#8221;, &#8220;ident&#8221;: &#8220;0000-0000-0000&#8221;, &#8220;serial&#8221;: &#8220;0000-0000-0000&#8221;, &#8220;model&#8221;: &#8220;QEMU_HARDDISK&#8221;, &#8220;descr&#8221;: &#8220;QEMU_HARDDISK&#8221;, &#8220;lunid&#8221;: null, &#8220;bus&#8221;: &#8220;SCSI&#8221;, &#8220;type&#8221;: &#8220;HDD&#8221;, &#8220;blocks&#8221;: 2343174144, &#8220;serial_lunid&#8221;: null, &#8220;rotationrate&#8221;: null, &#8220;stripesize&#8221;: null, &#8220;parts&#8221;: [], &#8220;dif&#8221;: false, &#8220;identifier&#8221;: &#8220;{serial}0000-0000-0000&#8221;, &#8220;enclosure&#8221;: {}, &#8220;partitions&#8221;: [],&#8230;&#8230;&#8230;<\/em><br><br>Actions can be taken as well as examination of data from the TrueNAS System. An example swiped from the documentation:<br><br><em>midclt &#8211;uri wss:\/\/192.168.100.128\/api\/current &#8211;insecure -K \/home\/user\/Documents\/Homelab\/apikey3 call user.create &#8216;{&#8220;full_name&#8221;: &#8220;John Doe&#8221;, &#8220;username&#8221;: &#8220;user&#8221;, &#8220;password&#8221;: &#8220;pass&#8221;, &#8220;group_create&#8221;: true}&#8217; | jq<\/em><br><br>output:<br><em>{<br>&#8220;id&#8221;: 75,<br>&#8220;uid&#8221;: 3002,<br>&#8220;username&#8221;: &#8220;user&#8221;,<br>&#8220;unixhash&#8221;: &#8220;$6$rounds=656000$oabKO1rS\/8KCLY\/Q$.iWPMgbEdAJTFQLi1lSdXsap551imOU1FaVMFVcpIZXc9SgwaJ92gXVGsIJOknLxW.mOcKuPtRLFnFnSgArJh0&#8221;,<br>&#8220;smbhash&#8221;: &#8220;36AA83BDCAB3C9FDAF321CA42A31C3FC&#8221;,<br>&#8220;home&#8221;: &#8220;\/var\/empty&#8221;,<br>&#8220;shell&#8221;: &#8220;\/usr\/bin\/zsh&#8221;,<br>&#8220;full_name&#8221;: &#8220;John Doe&#8221;,<br>&#8220;builtin&#8221;: false,<br>&#8220;smb&#8221;: true,<br>&#8220;userns_idmap&#8221;: null,<br>&#8220;group&#8221;: {<br>&#8220;id&#8221;: 114,<br>&#8220;bsdgrp_gid&#8221;: 3002,<br>&#8220;bsdgrp_group&#8221;: &#8220;user&#8221;,<br>&#8220;bsdgrp_builtin&#8221;: false,<br>&#8220;bsdgrp_sudo_commands&#8221;: [],<br>&#8220;bsdgrp_sudo_commands_nopasswd&#8221;: [],<br>&#8220;bsdgrp_smb&#8221;: false,<br>&#8220;bsdgrp_userns_idmap&#8221;: 0<br>},<br>&#8220;groups&#8221;: [<br>91<br>],<br>&#8220;password_disabled&#8221;: false,<br>&#8220;ssh_password_enabled&#8221;: false,<br>&#8220;sshpubkey&#8221;: null,<br>&#8220;locked&#8221;: false,<br>&#8220;sudo_commands&#8221;: [],<br>&#8220;sudo_commands_nopasswd&#8221;: [],<br>&#8220;email&#8221;: null,<br>&#8220;local&#8221;: true,<br>&#8220;immutable&#8221;: false,<br>&#8220;twofactor_auth_configured&#8221;: false,<br>&#8220;sid&#8221;: &#8220;S-1-5-21-615739097-2431297770-4271785851-20075&#8221;,<br>&#8220;last_password_change&#8221;: {<br>&#8220;$date&#8221;: 1773026892000<br>},<br>&#8220;password_age&#8221;: 0,<br>&#8220;password_history&#8221;: [],<br>&#8220;password_change_required&#8221;: false,<br>&#8220;roles&#8221;: [],<br>&#8220;api_keys&#8221;: [],<br>&#8220;password&#8221;: &#8220;pass&#8221;<br>}<\/em> <br><br>And the newly created user can be seen in the GUI&#8217;s user menu.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"905\" height=\"586\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/016_created_user.png\" alt=\"\" class=\"wp-image-237\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/016_created_user.png 905w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/016_created_user-300x194.png 300w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/016_created_user-768x497.png 768w\" sizes=\"auto, (max-width: 905px) 100vw, 905px\" \/><\/figure>\n\n\n\n<p>Some of these items may be more familiar to programmers, but bear mentioning:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Arrays need to be enclosed with single quotes and brackets. As an example, a single drive would be &#8216;[&#8220;sda&#8221;]&#8217; but a set of drives would be &#8216;[&#8220;sda&#8221;,&#8221;sdb&#8221;]&#8221;<\/li>\n\n\n\n<li>Passing JSON through is similarly strict: EX &#8216;{<\/li>\n\n\n\n<li>In the file that contains the key, no formatting is used. It&#8217;s just the key as presented by TrueNAS.<\/li>\n\n\n\n<li>The formatting returned is JSON. As mentioned jq makes it human readable in BASH.<\/li>\n\n\n\n<li>Input is in JSON as well. The inputs are listed in the programming guide.<\/li>\n\n\n\n<li>As-is the midclt command does not seem to be friendly to taking a file as input. I&#8217;ve been messing around with it in BASH and haven&#8217;t had much luck. There does not seem to be a native way to ingest JSON via the CLI currently.<\/li>\n\n\n\n<li>It is <strong>critically important<\/strong> that any API keys in files have absolute minimum permissions. You are storing a password to your storage system on a server. I&#8217;ll say that I feel like this integration is taken for granted in a lot of systems, even at an enterprise level. An increase in the surface area available is unavoidable when automating. A robust set of user roles as above is a fantastic idea. I personally would strongly advise 600 permissions on the API key file which will restrict access to the explicit viewer.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"742\" src=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/008_api_key_success-1-1024x742.png\" alt=\"\" class=\"wp-image-236\" srcset=\"https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/008_api_key_success-1-1024x742.png 1024w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/008_api_key_success-1-300x217.png 300w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/008_api_key_success-1-768x556.png 768w, https:\/\/underwoodtechnologies.com\/wp-content\/uploads\/2026\/03\/008_api_key_success-1.png 1168w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The audit logs for the API user show that a login event happened. One thing I will say is that the logs don&#8217;t show the action taken on the system, nor is there a readily apparent way to enable it. \/var\/log\/nginx.log seems to have some of the calls in it in a limited aspect, but nothing clearly consistent that can be tailed.<\/p>\n\n\n\n<p>IV)Conclusion<\/p>\n\n\n\n<p>This is a high level guide on how to set up TrueNAS for API use and to run some basic commands against TrueNAS. It&#8217;s pretty cool, but the ecosystem (such as documentation) seems under cooked at this point unless you&#8217;re deep into code, and maybe even then. Better documentation and examples would greatly improve things which I suspect will come with time.<br><br>What&#8217;s next for me is likely getting a script together to actually do some setup on a TrueNAS Filer after the pool is created. This would be useful for storage automation around data store creation. With the difficulties passing data via CLI to midclt, I suspect going to Python would be a better way to use their API integration at this time.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I)Introduction and pre-requisitesOne of the ambitions of my homelab is to start working with APIs more. I would like to start trying to integrate TrueNAS into my Proxmox Environment deeper than it is currently, perhaps even start dabbling with GUI elements at some point. To be quite honest, I feel less than impressed with the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":243,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[10,11,12,13,9],"class_list":["post-213","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-homelab","tag-homelab","tag-linux","tag-python","tag-scripting","tag-truenas"],"_links":{"self":[{"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=\/wp\/v2\/posts\/213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=213"}],"version-history":[{"count":7,"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=\/wp\/v2\/posts\/213\/revisions"}],"predecessor-version":[{"id":294,"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=\/wp\/v2\/posts\/213\/revisions\/294"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=\/wp\/v2\/media\/243"}],"wp:attachment":[{"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/underwoodtechnologies.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}