Skip to main content
Markus_M
Staff & Editor
Staff & Editor
February 10, 2026

Technical Tip: FortiNAC-F REST API example to create guest user accounts

  • February 10, 2026
  • 0 replies
  • 226 views
Description

This article describes and explains an example of a Linux command shell execution to create Guest users. It is assumed that the commands used in the article are present (curl, date, tr, sed, head) and can run in a shell environment. Minimal scripting knowledge is beneficial.

Commands and scripts should always be tested prior to implementing them in production, as incorrect implementation could potentially affect the production environment.

Scope FortiNAC-F.
Solution

To create a Guest user in FortiNAC, the GUI can be used, or as an alternative, the REST API can be used. The latter is typically useful in repeatable operations, creating 20 users in a batch with certain criteria that the UI may not offer. Another factor is helpdesk interaction, where an integration with REST API over a smaller UI can be the easier choice than a helpdesk account on FortiNAC GUI.

 

To get a start, read the documentation on the REST API with FortiNAC, generate the access token, and general syntax in the documentation library of Fortinet:
FortiNAC-F: REST API Introduction.

 

A flat example of a static guest user creation is as follows:

 

curl -k --location --request POST 'https://nac .forti.lab:8443/api/v2/user/guest ' --header 'Content-Type: application/json' --header 'Authorization: hMndd5DXSopv8MsAoAZzz98kTxg2iY' --data-raw "{
 \"userID\": "guestuser",
\"password\": "ThisIsAS3curePassw()rd",
\"firstName\": "guest",
\"lastName\": "visitor",
\"email\": "guestuser@forti.lab",
\"accountEnabled\": true,
\"creationTime\": 1770632803000,
\"validForTime\": 1770805602000,
\"userStartTime\": 1770632803000,
\"userEndTime\": 1770805602000,
\"templateID\": 1
}"


In this example, 'curl' is used as the command invoking the REST API communication. The URL is, per the documentation, the endpoint to create guest users. The Authorization header is an example REST API key.
The raw data block contains the following, and the minimum. These are defined:

  • userID - the user ID for internal use.
  • password - The guest users' password.
  • firstName - the user's first name or given name.
  • lastName - the user's last name or family name.
  • email - the user's email.
  • accountEnabled - whether the account is enabled or not. It can be enabled at a later date.
  • creationTime - when the user is created. For accounting purposes, that should reflect the timestamp for "now".
  • validForTime - when will the user account expire after the creation time.
  • userStartTime - at what time the user is allowed to work with this account.
  • userEndTime - at what time the user is no longer permitted to work with this account.
  • templateID - which user template does the user follow. This may not have much effect as the template is used to assign many of the criteria above, but the user's 'Role' will be determined by the template as well as a reauthentication period.

 

The 'Time' notations are called an "epoch timestamp", that is, the count of seconds since 1st of January 1970, UTC.

So "1770632803000" translates to "Monday, February 9, 2026 10:26:43 AM UTC'.

These are also documented in broader detail in the documentation library: FortiNAC-F Guest Account details.

 

The set above is a single-use template to create a guest user. This may be used to fill out static users and delete them, and recreate them when needed.

The following is a more automated approach that makes use of Linux CLI tools to provide a certain text format.

 

USERID=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 10 | sed -e 's/^/user_/g')
USERPASSWORD=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 10)
USEREMAIL=$USERID@forti.lab
CLIENTID=$(curl -k --location --request POST 'https://nac .forti.lab:8443/api/v2/user/guest' --header 'Content-Type: application/json' --header 'Authorization: hMndd5DXSopv8MsAoAZzz98kTxg2iY' --data-raw "{
\"userID\": \"$USERID\",
\"password\": \"$USERPASSWORD\",
\"firstName\": \"guest\",
\"lastName\": \"visitor\",
\"email\": \"$USEREMAIL\",
\"accountEnabled\": true,
\"creationTime\": $(date +%s000),
\"validForTime\": $(date -d '+2 days' +%s000),
\"userStartTime\": $(date +%s000),
\"userEndTime\": $(date -d '+2 days' +%s000),
\"templateID\": 1
}" -s | grep success | awk -F '[:}]' '{print $4}')

echo ""
echo "Created user $USERID with Password = $USERPASSWORD and email $USEREMAIL on FortiNAC with client ID $CLIENTID"

 

To break this command down:

The following are variable declarations.

 

USERID=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 10 | sed -e 's/^/user_/g')
USERPASSWORD=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 10)
USEREMAIL=$USERID@forti.lab

 

  • USERID will be created with 10 random characters and prefixed with 'user'.
  • USERPASSWORD will be created, same like the USERID, with 10 random characters (among lower case, upper case, and numerical characters).
  • USEREMAIL will be an email address in the same domain, forti.lab, with the USERID. This may not work in real environments. Adapt it as needed.

 

CLIENTID=$(curl -k --location --request POST 'https://nac .forti.lab:8443/api/v2/user/guest' --header 'Content-Type: application/json' --header 'Authorization: hMndd5DXSopv8MsAoAZzz98kTxg2iY' --data-raw "{ <-- This is the curl command, which, however, runs also as a variable declaration.

 

The 'raw data' blocks use the variables declared and are filled with the content.

 

\"userID\": \"$USERID\",
\"password\": \"$USERPASSWORD\",

\"email\": \"$USEREMAIL\",

 

The following fill in date variables.

 

\"creationTime\": $(date +%s000),
\"validForTime\": $(date -d '+2 days' +%s000),
\"userStartTime\": $(date +%s000),
\"userEndTime\": $(date -d '+2 days' +%s000), 

 

These use the 'date' command on Linux, which supplies the epoch timestamp but understands a literal value of days. As such, the user creation and user start time are 'now'. The account expiry and user end time will be two days from 'now'.

This part still belongs to the curl command, and in case of success, the command returns a client database ID (response from FortiNAC).

 

-s | grep success | awk -F '[:}]' '{print $4}')

 

The returned value is written into the variable CLIENTID.

Finally, the last line gives feedback with all the filled variables. These could also be written to a text file if required.

 

echo ""
echo "Created user $USERID with Password = $USERPASSWORD and email $USEREMAIL on FortiNAC with client ID $CLIENTID."

 

This is a sample output of the complete command:


Created user user_gWPs06aiv0 with Password = ANvlkV9pjM and email user_gWPs06aiv0@forti.lab on FortiNAC with client ID 1425654185320470.

 

On the UI with all tests, these have been created, with the latest user at the bottom:


automated guest user creationautomated guest user creation

 

As seen here, an automated approach can be helpful.

Note: If there is no limit on creating the accounts, FortiNAC's database could get very large, very quickly.

To delete a user, use the following similar command:


curl -k --location 'https://nac .forti.lab:8443/api/v2/user/guest/1425654185320470/delete' --header 'Content-Type: application/json' --data-urlencode 'id=325691070687232' --header 'Authorization: hMndd5DXSopv8MsAoAZzz98kTxg2iY'
{"status":"success","errorMessage":null}