FTD REST API
FTD REST API
Americas Headquarters
Cisco Systems, Inc.
170 West Tasman Drive
San Jose, CA 95134-1706
USA
http://www.cisco.com
Tel: 408 526-4000
800 553-NETS (6387)
Fax: 408 527-0883
THE SPECIFICATIONS AND INFORMATION REGARDING THE PRODUCTS IN THIS MANUAL ARE SUBJECT TO CHANGE WITHOUT NOTICE. ALL STATEMENTS,
INFORMATION, AND RECOMMENDATIONS IN THIS MANUAL ARE BELIEVED TO BE ACCURATE BUT ARE PRESENTED WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED. USERS MUST TAKE FULL RESPONSIBILITY FOR THEIR APPLICATION OF ANY PRODUCTS.
THE SOFTWARE LICENSE AND LIMITED WARRANTY FOR THE ACCOMPANYING PRODUCT ARE SET FORTH IN THE INFORMATION PACKET THAT SHIPPED WITH
THE PRODUCT AND ARE INCORPORATED HEREIN BY THIS REFERENCE. IF YOU ARE UNABLE TO LOCATE THE SOFTWARE LICENSE OR LIMITED WARRANTY,
CONTACT YOUR CISCO REPRESENTATIVE FOR A COPY.
The Cisco implementation of TCP header compression is an adaptation of a program developed by the University of California, Berkeley (UCB) as part of UCB's public domain version of
the UNIX operating system. All rights reserved. Copyright © 1981, Regents of the University of California.
NOTWITHSTANDING ANY OTHER WARRANTY HEREIN, ALL DOCUMENT FILES AND SOFTWARE OF THESE SUPPLIERS ARE PROVIDED “AS IS" WITH ALL FAULTS.
CISCO AND THE ABOVE-NAMED SUPPLIERS DISCLAIM ALL WARRANTIES, EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THOSE OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OR ARISING FROM A COURSE OF DEALING, USAGE, OR TRADE PRACTICE.
IN NO EVENT SHALL CISCO OR ITS SUPPLIERS BE LIABLE FOR ANY INDIRECT, SPECIAL, CONSEQUENTIAL, OR INCIDENTAL DAMAGES, INCLUDING, WITHOUT
LIMITATION, LOST PROFITS OR LOSS OR DAMAGE TO DATA ARISING OUT OF THE USE OR INABILITY TO USE THIS MANUAL, EVEN IF CISCO OR ITS SUPPLIERS
HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
Any Internet Protocol (IP) addresses and phone numbers used in this document are not intended to be actual addresses and phone numbers. Any examples, command display output, network
topology diagrams, and other figures included in the document are shown for illustrative purposes only. Any use of actual IP addresses or phone numbers in illustrative content is unintentional
and coincidental.
All printed copies and duplicate soft copies of this document are considered uncontrolled. See the current online version for the latest version.
Cisco has more than 200 offices worldwide. Addresses and phone numbers are listed on the Cisco website at www.cisco.com/go/offices.
Cisco and the Cisco logo are trademarks or registered trademarks of Cisco and/or its affiliates in the U.S. and other countries. To view a list of Cisco trademarks, go to this URL:
https://www.cisco.com/c/en/us/about/legal/trademarks.html. Third-party trademarks mentioned are the property of their respective owners. The use of the word partner does not imply a
partnership relationship between Cisco and any other company. (1721R)
© 2017–2024 Cisco Systems, Inc. All rights reserved.
CONTENTS
https://ftd.example.com/api/fdm/v1/object/networks
The server name part of the URL is the hostname or IP address of the threat defense device, and will be
different for your device in place of “ftd.example.com.” In this example, you delete /object/networks from
the path to get the base URL:
https://ftd.example.com/api/fdm/v1/
All resource calls use this URL as the base for the request URL.
If you changed the HTTPS data port, you must include the custom port in the URL. For example, if you
changed the port to 4443: https://ftd.example.com:4443/api/fdm/v1/
The "v" element in the URL is the API version, and this will typically change with the software version. For
example, the API version for the threat defense version 6.3.0 is v2, so the base URL would be:
https://ftd.example.com/api/fdm/v2/
Note Starting with the threat defense 6.4, you can avoid the need to update the path in your API calls by using latest
instead of the v element in the path. For example, https://ftd.example.com/api/fdm/latest/. The latest alias
resolves to the most recent API version supported by the device.
In the API Explorer, if you scroll to the bottom of the page, you can see information on the base URL (without
the server name) and API version.
When connecting with a browser, you are prompted to accept the self-signed certificate, but a command such
as curl will reject the certificate. In the case of curl, you can bypass the certificate check failure by adding the
--insecure keyword. For example:
One of the first things you should do is obtain a CA-signed device certificate for the threat defense device.
Then, using the device manager or the API, assign this certificate as the management certificate. Subsequently,
SSL/TLS certificate checking should not fail, and you will not need to use insecure communications in your
API calls.
Procedure
Step 1 Upload the CA-signed device certificate using the POST /object/internalcertificates resource.
Step 2 Make this certificate the management certificate using the PUT
/devicesettings/default/webuicertificates/{objId} resource.
Use the GET /devicesettings/default/webuicertificates resource to determine the object ID for the web UI
certificate.
Replace “ftd.example.com” with the hostname or IP address of the threat defense device.
This method returns a list of API versions you can use. For example:
{
"supportedVersions":["v3", "latest"]
}
The version strings are the same ones you use in the URL for subsequent API calls. If you use latest instead
of the specific version identifier, you can avoid the need to update your calls for subsequent releases. However,
using this technique does not overcome changes to the object models used in your calls, which might need
adjustment from release to release.
Typically, your next step would be to get an access token, as described in Authenticating Your REST API
Client Using OAuth, on page 13.
Tip The purpose of the API Explorer is to help you learn the API. Testing calls through the API Explorer requires
the creation of access locks that might interfere with regular operation. We recommend that you use the API
Explorer on a non-production device.
Procedure
Step 1 Using a browser, open the home page of the system, for example, https://ftd.example.com.
Step 2 Log into the device manager.
Step 3 (6.4 and earlier.) Edit the URL to point to /#/api-explorer, for example, https://ftd.example.com/#/api-explorer.
Step 4 (6.5 and later.) Click the more options button ( ) and choose API Explorer.
The system opens the API Explorer in a separate tab or window, depending on your browser settings.
These group names are links: click the link to open the group to see the methods you can use with the resources
in the group. Each group also includes the following commands on the right:
• Show/Hide opens and closes the group. This is the same as clicking the group name. Initially, the
expansion simply shows the methods (same as List Operations), but the system remembers the last
expanded state (before you closed it) and re-opens to the same degree of expansion.
• List Operations shows the HTTP methods available for each resource in the group. The information
includes the relative path for the universal resource locator (URL) template for each resource. Path
variables are indicated by the standard convention: {variable}. You need to replace {variable}, including
the braces, with an appropriate value. You must add the base URL to this relative path; see The Base
URL for the API, on page 2.
Click an operation URL template to see complete documentation for that method.
• Expand Operations opens all of the HTTP methods and resources available for in a group.
Some groups have many children resources. For example, the DataInterface ManagementAccess group includes
GET, POST, and DELETE operations for /devicesettings/default/managementaccess, and GET and PUT
operations for /devicesettings/default/managementaccess/{objId}.
Procedure
Step 1 Drill down to the specific resource and method that interests you.
Step 2 In the Response Class section, click the Model tab.
The model lists the attributes with descriptions and data types. For GET, there are also paging options that
might be returned. If there are more objects than were returned in the response, you get the URLs for the next
and previous batch of objects.
For example, the following graphic shows the POST /object/tcpports method and resource, with the Model
tab selected. By default, the Example Value tab is selected, so you must always click Model to see the
documentation.
In most cases, you can get the object or parent ID by using a GET method one level higher in the resource
hierarchy. The object/parent ID is the UUID on the id parameter for a given object.
For example, GET /object/networks returns a list of all network objects currently defined. You might need to
do multiple calls to page through the list to get to the object you want, or include the limit query parameter
to increase the number of objects returned for a call. Each object has the following format; the object ID is
highlighted.
{
"version": "9bbb9e5d-8115-11e7-8cb4-772d7eb1894d",
"name": "any-ipv4",
"description": null,
"subType": "NETWORK",
"value": "0.0.0.0/0",
"isSystemDefined": true,
"id": "9bbbc56e-8115-11e7-8cb4-01865c95f930",
"type": "networkobject",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/object/networks/
9bbbc56e-8115-11e7-8cb4-01865c95f930"
}
Note In some cases, the {objId} occurs at the top-level of a hierarchy. In these cases, sometimes you can enter any
value for object ID and get the same results. In other cases, examine the object model documentation for
information on valid object types; the ID is one of the valid types. These are always GET calls. For example,
GET /operational/systeminfo/{objId} and GET /operational/featureinfo/{objId}.
{
"name": "test-network",
"subType": "NETWORK",
"value": "10.10.10.0",
"type": "networkobject"
}
The result would be an HTTP response code of 422, and a response body that includes a specific error message:
{
"error": {
"severity": "ERROR",
"key": "Validation",
"messages": [
{
"description": "The type Network requires a netmask. To specify a single host,
either use the type Host, or use {0}/255.255.255.255.",
"code": "networkWithoutNetmask",
"location": "value"
}
]
}
}
The following procedure explains how to view the list of possible error messages that can be returned in a
response body.
Procedure
Step 1 In the device manager, click the more options button ( ) and choose API Explorer.
Step 2 Click Error Catalog in the table of contents.
The messages have the following components.
• Category—The general type of message. This value appears in the key attribute of the error response
body. Categories include Validation, General, and Deployment.
• Code—A unique string that identifies the error message. This value appears in the code attribute of the
error response body. You can use the browser’s Find On Page feature to locate messages in the catalog
using this value.
• Message—The specific message that explains the error. This value appears in the description attribute
of the error response body. Variables within the message are indicated as {0}, {1}, and so forth.
The following topics explain the methods for obtaining and using the required tokens.
• Overview of the API Client Authentication Process, on page 13
• Requesting a Password-Granted Access Token, on page 15
• Requesting a Custom Access Token, on page 17
• Using an Access Token on API Calls, on page 19
• Refreshing an Access Token, on page 19
• Revoking an Access Token, on page 21
Procedure
Step 1 Authenticate the API client user using whatever method you require.
Your client is obligated to authenticate users and ensure they have the authority to access and modify the
threat defense device. If you want to provide differential abilities based on authorization rights, you need to
build that into your client.
For example, if you want to allow read-only access, you must set up the required authentication server, user
accounts, and so forth. Then, when a user with read-only rights logs into your client, you must ensure that
you issue GET calls only. In API v1, this type of variable access cannot be controlled by the threat defense
device itself. Starting with API v2, if you are using external users and you do not groom calls based on user
authorization, you will get errors if there is a mismatch between user authorization and the calls you attempt.
For v1, when communicating with the device, you must use the admin user account on the threat defense
device. The admin account has full read/write authorization for all user-configurable objects.
Step 2 Request a password-granted access token based on username/password using the admin account.
See Requesting a Password-Granted Access Token, on page 15.
Step 4 Use the access token on API calls in the Authorization: Bearer header.
See Using an Access Token on API Calls, on page 19.
Step 6 When you are finished, revoke the token if it has not yet expired.
See Revoking an Access Token, on page 21.
Procedure
Step 1 Create the JSON object for the password-granted access token grant.
"grant_type": "password",
"username": "string",
"password": "string"
}
Specify the admin username and the correct password, for example:
{
"grant_type": "password",
"username": "admin",
"password": "Admin123"
}
Step 3 Retrieve the access and refresh tokens from the response.
A good response (status code 200) looks like the following:
{
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MDI4MzI2NjcsInN
1YiI6ImFkbWluIiwianRpIjoiMGM3ZDBmNDgtODIwMS0xMWU3LWE4MWMtMDcwZmYzOW
U3ZjQ0IiwibmJmIjoxNTAyODMyNjY3LCJleHAiOjE1MDI4MzQ0NjcsInJlZnJlc2hU
b2tlbkV4cGlyZXNBdCI6MTUwMjgzNTA2NzQxOSwidG9rZW5UeXBlIjoiSldUX0FjY2
VzcyIsIm9yaWdpbiI6InBhc3N3b3JkIn0.b2hI6fVA_GbmhCOPM-ZUx6IC8SgCk1Ak
HXI-llV0r7s",
"expires_in": 1800,
"token_type": "Bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MDI4MzI2NjcsI
nN1YiI6ImFkbWluIiwia nRpIjoiMGM3ZDBmNDgtODIwMS0xMWU3LWE4MWMtMDcwZmY
zOWU3ZjQ0IiwibmJmIjoxNTAyODMyNjY3LCJleHAiOjE1MDI4MzUwNjcsImFjY2Vzc1
Rva2VuRXhwaXJlc0F0IjoxNTAyODM0NDY3NDE5LCJyZWZyZXNoQ291bnQiOi0xLCJ0b2
tlblR5cGUiOiJKV1RfUmVmcmVzaCIsIm9yaWdpbiI6InBhc3N3b3JkIn0.iLNqz1c1Xl
vcq0j9pQYW4gwYsvUCcSyaiDRXGutAz_o",
"refresh_expires_in": 2400
}
Where:
• access_token is the bearer token you need to include on API calls. See Using an Access Token on API
Calls, on page 19.
• expires_in is the number of seconds for which the access token is valid, from the time the token is issued.
• refresh_token is the token you would use on a refresh request. See Refreshing an Access Token, on
page 19.
• refresh_expires_in is the number of seconds for which the refresh token is valid. This is always longer
than the access token validity period.
Procedure
Step 1 Create the JSON object for the custom access token grant.
{
"grant_type": "custom_token",
"access_token": "string",
"desired_expires_in": 0,
"desired_refresh_expires_in": 0,
"desired_subject": "string",
"desired_refresh_count": 0
}
Where:
• access_token is a valid password-granted access token.
• desired_expires_in is an integer representing the number of seconds for which the custom access token
will be valid. In comparison, the password-granted tokens are valid for 1800 seconds.
• desired_refresh_expires_in is an integer representing the number of seconds for which the custom
refresh token will be valid. If you obtain a refresh token, ensure that this value is larger than the
desired_expires_in value. In comparison, the password-granted refresh tokens are valid for 2400 seconds.
This parameter is not required if you specify 0 for desired_refresh_count.
• desired_subject is a name you give to the custom token.
• desired_refresh_count is the number of times you want to be able to refresh the token. Specify 0 if you
do not want to get a refresh token. When you do not have a refresh token, you must obtain a new access
token when the existing one expires.
For example, the following requests a custom token for api-client that expires in 2400 seconds, with a refresh
token that expires in 3000 seconds. The token can be refreshed 3 times.
{{
"grant_type": "custom_token",
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MDI4MzI2NjcsInN
1YiI6ImFkbWluIiwianRpIjoiMGM3ZDBmNDgtODIwMS0xMWU3LWE4MWMtMDcwZmYzOW
U3ZjQ0IiwibmJmIjoxNTAyODMyNjY3LCJleHAiOjE1MDI4MzQ0NjcsInJlZnJlc2hU
b2tlbkV4cGlyZXNBdCI6MTUwMjgzNTA2NzQxOSwidG9rZW5UeXBlIjoiSldUX0FjY2
VzcyIsIm9yaWdpbiI6InBhc3N3b3JkIn0.b2hI6fVA_GbmhCOPM-ZUx6IC8SgCk1Ak
HXI-llV0r7s",
"desired_expires_in": 2400,
"desired_refresh_expires_in": 3000,
"desired_subject": "api-client",
"desired_refresh_count": 3
}
Step 3 Retrieve the access and refresh tokens from the response.
A good response (status code 200) looks like the following:
{
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MDI4MzU5O
TEsInN1YiI6ImFwaS1jbGllbnQiLCJqdGkiOiJjOWIxYzdjYi04MjA4LTExZT
ctYTgxYy02YmY0NzY3ZmRmZGUiLCJuYmYiOjE1MDI4MzU5OTEsImV4cCI6MTU
wMjgzODM5MSwicmVmcmVzaFRva2VuRXhwaXJlc0F0IjoxNTAyODM4OTkxMzMx
LCJ0b2tlblR5cGUiOiJKV1RfQWNjZXNzIiwib3JpZ2luIjoiY3VzdG9tIn0.9
IVzLjGffVQffHAWdrNkrYfvuO6TgpJ7Zi_z3RYubN8",
"expires_in": 2400,
"token_type": "Bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MDI4MzU5
OTEsInN1YiI6ImFwaS1jbGllbnQiLCJqdGkiOiJjOWIxYzdjYi04MjA4LTExZ
TctYTgxYy02YmY0NzY3ZmRmZGUiLCJuYmYiOjE1MDI4MzU5OTEsImV4cCI6MT
UwMjgzODk5MSwiYWNjZXNzVG9rZW5FeHBpcmVzQXQiOjE1MDI4MzgzOTEzMzE
sInJlZnJlc2hDb3VudCI6MywidG9rZW5UeXBlIjoiSldUX1JlZnJlc2giLCJv
cmlnaW4iOiJjdXN0b20ifQ.qseqjg3Uo183YvfN_77iJZELEqwpWw5AbKAqAn
CIcSA",
"refresh_expires_in": 3000
}
Where:
• access_token is the bearer token you need to include on API calls. See Using an Access Token on API
Calls, on page 19.
• expires_in is the number of seconds for which the access token is valid, from the time the token is issued.
• refresh_token is the token you would use on a refresh request. See Refreshing an Access Token, on
page 19.
• refresh_expires_in is the number of seconds for which the refresh token is valid. This is always longer
than the access token validity period.
Note When you use the API Explorer to try out methods and resources, the curl command shown does not include
the Authorization: Bearer header. However, you must add this header when making calls from your API
client.
Procedure
Step 1 Create the JSON object for the refresh token grant.
{
"grant_type": "refresh_token",
"refresh_token": "string"
}
{
"grant_type": "refresh_token",
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQ
iOjE1MDI4MzU5OTEsInN1YiI6ImFwaS1jbGllbnQiLCJqdGk
iOiJjOWIxYzdjYi04MjA4LTExZTctYTgxYy02YmY0NzY3ZmR
mZGUiLCJuYmYiOjE1MDI4MzU5OTEsImV4cCI6MTUwMjgzODk
5MSwiYWNjZXNzVG9rZW5FeHBpcmVzQXQiOjE1MDI4MzgzOTE
zMzEsInJlZnJlc2hDb3VudCI6MywidG9rZW5UeXBlIjoiSld
UX1JlZnJlc2giLCJvcmlnaW4iOiJjdXN0b20ifQ.qseqjg3U
o183YvfN_77iJZELEqwpWw5AbKAqAnCIcSA"
}
Step 3 Retrieve the access and refresh tokens from the response.
A good response (status code 200) looks like the following. In this example, the refresh token was for a custom
token. The expiration periods are based on the values from the original custom access token request.
{
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQ
iOjE1MDI4Mzc1MTAsInN1YiI6ImFwaS1jbGllbnQiLCJqdG
kiOiJjOWIxYzdjYi04MjA4LTExZTctYTgxYy02YmY0NzY3Z
mRmZGUiLCJuYmYiOjE1MDI4Mzc1MTAsImV4cCI6MTUwMjgz
OTkxMSwicmVmcmVzaFRva2VuRXhwaXJlc0F0IjoxNTAyODQ
wNTEwNzQxLCJ0b2tlblR5cGUiOiJKV1RfQWNjZXNzIiwib3
JpZ2luIjoiY3VzdG9tIn0.fAAreX0DdnuqnM0Bs0NXYnI-9
jkpyW1pWDMwgwO_h7A",
"expires_in": 2400,
"token_type": "Bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYX
QiOjE1MDI4Mzc1MTAsInN1YiI6ImFwaS1jbGllbnQiLCJqd
GkiOiJjOWIxYzdjYi04MjA4LTExZTctYTgxYy02YmY0NzY3
ZmRmZGUiLCJuYmYiOjE1MDI4Mzc1MTAsImV4cCI6MTUwMjg
0MDUxMCwiYWNjZXNzVG9rZW5FeHBpcmVzQXQiOjE1MDI4Mz
k5MTEwNzIsInJlZnJlc2hDb3VudCI6MiwidG9rZW5UeXBlI
joiSldUX1JlZnJlc2giLCJvcmlnaW4iOiJjdXN0b20ifQ.p
Adc2N0oun7Yyw872qK12pFlix4arAwyMETD1ErKu5c",
"refresh_expires_in": 3000
}
Where:
• access_token is the bearer token you need to include on API calls. See Using an Access Token on API
Calls, on page 19.
• expires_in is the number of seconds for which the access token is valid, from the time the token is issued.
• refresh_token is the token you would use on a refresh request.
• refresh_expires_in is the number of seconds for which the refresh token is valid. This is always longer
than the access token validity period.
Procedure
Step 1 Create the JSON object for the revoke token grant.
{
"grant_type": "revoke_token",
"access_token": "string",
"token_to_revoke": "string",
"custom_token_id_to_revoke": "string",
"custom_token_subject_to_revoke": "string"
}
Where:
• access_token must be a password-granted access token. You cannot revoke a token using a custom
access token.
• You must specify one, and only one, of the following:
• token_to_revoke is a password-granted or custom token that you want to revoke. This can be the
same token as access_token, so you can use a password-granted token to revoke itself.
• (Do not use.) custom_token_id_to_revoke identifies custom access token by its internal unique
ID. However, there is no direct way for you to obtain this value. Use the other options instead.
• custom_token_subject_to_revoke is the desired_subject value for the custom access token that
you want to revoke.
For example:
{
"grant_type": "revoke_token",
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQ
iOjE1MDI5MDQzMjQsInN1YiI6ImFkbWluIiwianRpIjoiZT
MzNGIxOWYtODJhNy0xMWU3LWE4MWMtNGQ3NzY2ZTExMzVkI
iwibmJmIjoxNTAyOTA0MzI0LCJleHAiOjE1MDI5MDYxMjQs
InJlZnJlc2hUb2tlbkV4cGlyZXNBdCI6MTUwMjkwNjcyNDE
xMiwidG9rZW5UeXBlIjoiSldUX0FjY2VzcyIsIm9yaWdpbi
I6InBhc3N3b3JkIn0.OVZBT9yVZc4zxZfZiiLH4SZcFclaH
yCPbZJC_Gyd5FE",
"custom_token_subject_to_revoke": "api-client"
}
Step 3 Evaluate the response to verify that the token was revoked.
A good response (status code 200) looks like the following.
{
"message": "OK",
"status_code": 200
}
Procedure
Step 1 Define Authorization Rights in the RADIUS User Accounts, on page 24.
Step 2 Define the RADIUS Servers, on page 24.
Step 3 Create a AAA Server Group for the RADIUS Servers, on page 26.
Step 4 Establish the AAA Server Group as an Authentication Source for HTTPS Access, on page 28.
Step 5 Use POST /operational/deploy to start a deployment job.
The curl command would be similar to the following:
'https://ftd.example.com/api/fdm/latest/operational/deploy'
For detailed information on deploying changes, see Deploying Configuration Changes, on page 45.
Note These external users are also authorized for device manager.
To provide role-based access control (RBAC), update the user accounts on your RADIUS server to define
the cisco-av-pair attribute. This attribute must be defined correctly on a user account, or the user is denied
access to the REST API. Following are the supported values for the cisco-av-pair attribute:
• fdm.userrole.authority.admin provides full Administrator access. These users can do all actions that
the local admin user can do.
• fdm.userrole.authority.rw provides read-write access. These users can do everything a read-only user
can do, and also edit and deploy the configuration. The only restrictions are for system-critical actions,
which include installing upgrades, creating and restoring backups, viewing the audit log, and logging
off other users.
• fdm.userrole.authority.ro provides read-only access. These users can view dashboards and the
configuration, but cannot make any changes. If the user tries to make a change, the error message explains
that this is due to lack of permission.
Use the POST /object/radiusidentitysources resource to create an object for each RADIUS server you want
to define.
Procedure
Step 1 Create the JSON object body for the RADIUS server.
Following is an example of the JSON object to use with this call.
{
"name": "aaa-server-1",
"description": "RADIUS server for API access.",
"host": "172.16.246.220",
"timeout": 10,
"serverAuthenticationPort": 1812,
"serverSecretKey": "secret123",
"type": "radiusidentitysource"
}
You should get a response code of 200. A successful response body would look something like the following.
Note that sensitive information, such as the secret key, is masked in the response.
{
"version": "nfamb3cr2jlyi",
"name": "aaa-server-1",
"description": "RADIUS server for API access.",
"host": "172.16.246.220",
"timeout": 10,
"serverAuthenticationPort": 1812,
"serverSecretKey": "*********",
"capabilities": [
"AUTHENTICATION",
"AUTHORIZATION"
],
"id": "1b962e3b-6e56-11e8-bd65-379fa8aaaba1",
"type": "radiusidentitysource",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/object/
radiusidentitysources/1b962e3b-6e56-11e8-bd65-379fa8aaaba1"
}
}
Procedure
Step 1 Create the JSON object body for the RADIUS server group.
Following is an example of the JSON object to use with this call.
{
"name": "radius-group",
"maxFailedAttempts": 3,
"deadTime": 10,
"description": "AAA RADIUS server group.",
"radiusIdentitySources": [
{
"id": "1b962e3b-6e56-11e8-bd65-379fa8aaaba1",
"type": "radiusidentitysource",
"version": "nfamb3cr2jlyi",
"name": "aaa-server-1"
}
],
"type": "radiusidentitysourcegroup"
}
• name—The object name. This does not need to match anything defined on the member RADIUS servers.
• maxFailedAttempts—(Optional.) Failed servers are reactivated only after all servers have failed. The
dead time is how long to wait, from 0 - 1440 minutes, after the last server fails before reactivating all
servers. If you do not include this attribute, the default is 10 minutes.
• deadTime—(Optional.) The number of failed requests (that is, requests that do not get a response) sent
to a RADIUS server in the group before trying the next server. You can specify 1-5, and the default is
3. When the maximum number of failed attempts is exceeded, the system marks the server as Failed.
For a given feature, if you configured a fallback method using the local database, and all the servers in
the group fail to respond, then the group is considered to be unresponsive, and the fallback method is
tried. The server group remains marked as unresponsive for the duration of the dead time, so that additional
AAA requests within that period do not attempt to contact the server group, and the fallback method is
used immediately.
• description—(Optional.) A description of the object.
• radiusIdentitySources—This is a group of items that define each radiusidentitysource object that defines
a RADIUS server to include in the group. Include the items within the [brackets]. Following are the
attributes and syntax for each object. You get the value for the id, version, and name attributes from the
individual objects; the information is in the response body when you create the objects. You can also get
the information from a GET /object/radiusidentitysources call. The type must be radiusidentitysource.
{
"id": "1b962e3b-6e56-11e8-bd65-379fa8aaaba1",
"type": "radiusidentitysource",
"version": "nfamb3cr2jlyi",
"name": "aaa-server-1"
}
"version": "7r572novdiyy",
"name": "radius-group",
"maxFailedAttempts": 3,
"deadTime": 10,
"description": "AAA RADIUS server group.",
"radiusIdentitySources": [
{
"version": "nfamb3cr2jlyi",
"name": "aaa-server-1",
"id": "1b962e3b-6e56-11e8-bd65-379fa8aaaba1",
"type": "radiusidentitysource"
}
],
"activeDirectoryRealm": null,
"id": "0a7996ae-6e5b-11e8-bd65-dbab801c44b9",
"type": "radiusidentitysourcegroup",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/object/
radiusidentitysourcegroups/0a7996ae-6e5b-11e8-bd65-dbab801c44b9"
}
}
Procedure
Step 1 Use GET /devicesettings/default/aaasettings to determine the attributes of the aaasettings objects.
The curl command would be similar to the following:
For example, the response body should be similar to the following. This example shows that the local identity
source is the one defined for HTTPS access. It is also used for SSH access, which is not relevant for the REST
API.
{
"items": [
{
"version": "du52clrtmawlt",
"name": "HTTPS",
"identitySourceGroup": {
"version": "cynutari5ffkl",
"name": "LocalIdentitySource",
"id": "e3e74c32-3c03-11e8-983b-95c21a1b6da9",
"type": "localidentitysource"
},
"description": null,
"protocolType": "HTTPS",
"useLocal": "NOT_APPLICABLE",
"id": "00000003-0000-0000-0000-000000000007",
"type": "aaasetting",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/
devicesettings/default/aaasettings/00000003-0000-0000-0000-000000000007"
}
},
{
"version": "fgkhvu4kwucgv",
"name": "SSH",
"identitySourceGroup": {
"version": "cynutari5ffkl",
"name": "LocalIdentitySource",
"id": "e3e74c32-3c03-11e8-983b-95c21a1b6da9",
"type": "localidentitysource"
},
"description": null,
"protocolType": "SSH",
"useLocal": "NOT_APPLICABLE",
"id": "00000003-0000-0000-0000-000000000008",
"type": "aaasetting",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/
devicesettings/default/aaasettings/00000003-0000-0000-0000-000000000008"
}
}
],
"paging": {
"prev": [],
"next": [],
"limit": 10,
"offset": 0,
"count": 2,
"pages": 0
}
}
Step 2 (Optional.) Use GET /devicesettings/default/aaasettings/{objId} to obtain a copy of the HTTPS AAA setting
object to narrow your view.
Your PUT call will update the HTTPS object only. You do not need to update the SSH object.
In this example, the ID of the HTTPS object is 00000003-0000-0000-0000-000000000007, so a curl command
would be similar to the following:
{
"version": "ha4653ootep7z",
"name": "HTTPS",
"identitySourceGroup": {
"version": "cynutari5ffkl",
"name": "LocalIdentitySource",
"id": "e3e74c32-3c03-11e8-983b-95c21a1b6da9",
"type": "localidentitysource"
},
"description": null,
"protocolType": "HTTPS",
"useLocal": "NOT_APPLICABLE",
"id": "00000003-0000-0000-0000-000000000007",
"type": "aaasetting",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/
devicesettings/default/aaasettings/00000003-0000-0000-0000-000000000007"
}
Step 3 Create the JSON object body for AAA management access.
Following is an example of the JSON object to use with this call.
{
"version": "ha4653ootep7z",
"name": "HTTPS",
"identitySourceGroup": {
"id": "0a7996ae-6e5b-11e8-bd65-dbab801c44b9",
"type": "radiusidentitysourcegroup",
"version": "7r572novdiyy",
"name": "radius-group"
},
"description": null,
"protocolType": "HTTPS",
"useLocal": "BEFORE",
"id": "00000003-0000-0000-0000-000000000007",
"type": "aaasetting"
}
• id—The ID value for the HTTPS object. Find this value in the response body for the GET call.
• type—The object type, aaasetting.
{
"version": "ehxcytq4iccb3",
"name": "HTTPS",
"identitySourceGroup": {
"version": "7r572novdiyy",
"name": "radius-group",
"id": "0a7996ae-6e5b-11e8-bd65-dbab801c44b9",
"type": "radiusidentitysourcegroup"
},
"description": null,
"protocolType": "HTTPS",
"useLocal": "BEFORE",
"id": "00000003-0000-0000-0000-000000000007",
"type": "aaasetting",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/devicesettings/
default/aaasettings/00000003-0000-0000-0000-000000000007"
}
}
Procedure
Step 1 Log into the device manager using an external username that has a valid cisco-av-pair attribute.
The login should be successful, and the upper right of the page should show the username and privilege level.
{
"grant_type": "password",
"username": "radiusreadwriteuser1",
"password": "Readwrite123!"
}
{
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1Mjg4MjM
3MTAsInN1YiI6InJhZGl1c3JlYWR3cml0ZXVzZXIxIiwianRpIjoiMjk5Zj
Q5YjYtNmU2NC0xMWU4LWJkNjUtNmY0ZmVmYjY1MzI5IiwibmJmIjoxNTI4O
DIzNzEwLCJleHAiOjE1Mjg4MjU1MTAsInJlZnJlc2hUb2tlbkV4cGlyZXNB
dCI6MTUyODgyNjExMDg4OSwidG9rZW5UeXBlIjoiSldUX0FjY2VzcyIsInV
zZXJVdWlkIjoiMjliMjBlNjctNmU2NC0xMWU4LWJkNjUtMzU4MmUwZjU5Yj
Q4IiwidXNlclJvbGUiOiJST0xFX1JFQURfV1JJVEUiLCJvcmlnaW4iOiJwY
XNzd29yZCJ9.dtKsl9IB4ds3RAktEeaSuQy_Zs2SrzLr976UtblBt28",
"expires_in": 1800,
"token_type": "Bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1Mjg4Mj
M3MTAsInN1YiI6InJhZGl1c3JlYWR3cml0ZXVzZXIxIiwianRpIjoiMjk5Z
jQ5YjYtNmU2NC0xMWU4LWJkNjUtNmY0ZmVmYjY1MzI5IiwibmJmIjoxNTI4
ODIzNzEwLCJleHAiOjE1Mjg4MjYxMTAsImFjY2Vzc1Rva2VuRXhwaXJlc0F
0IjoxNTI4ODI1NTEwODg5LCJyZWZyZXNoQ291bnQiOi0xLCJ0b2tlblR5cG
UiOiJKV1RfUmVmcmVzaCIsInVzZXJVdWlkIjoiMjliMjBlNjctNmU2NC0xM
WU4LWJkNjUtMzU4MmUwZjU5YjQ4IiwidXNlclJvbGUiOiJST0xFX1JFQURf
V1JJVEUiLCJvcmlnaW4iOiJwYXNzd29yZCJ9.Lc7MYmieNMMrjx7XoTiW-x
8Z8qFCnzfNM1apgbwLQvo",
"refresh_expires_in": 2400
}
Step 3 Use GET /object/users to verify that user objects were created for each user.
User objects are automatically created for each new user who logs into the device manager or who obtains an
access token. You must run a deployment job to save these user objects. In high availability mode, the
deployment job is required before the user can log into the standby unit.
For example, the curl command would look like the following:
The following response body shows that two external users logged in. Note that userRole shows the rights
obtained from the cisco-av-pair configured in the RADIUS server for those user accounts. Use this information
to verify you configured the RADIUS user accounts correctly. The admin user is the locally-defined user.
{
"items": [
{
"version": "h2vom4wckm2js",
"name": "radiusadminuser1",
"password": null,
"newPassword": null,
"userPreferences": {
"preferredTimeZone": "(UTC+00:00) UTC",
"colorTheme": "NORMAL_CISCO_IDENTITY",
"type": "userpreferences"
},
"userRole": "ROLE_ADMIN",
"identitySourceId": "0a7996ae-6e5b-11e8-bd65-dbab801c44b9",
"userServiceTypes": [
"MGMT"
],
"id": "150d9754-6e63-11e8-bd65-ed9b20f62114",
"type": "user",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/
object/users/150d9754-6e63-11e8-bd65-ed9b20f62114"
}
},
{
"version": "p4rgwcjr5colj",
"name": "admin",
"password": null,
"newPassword": null,
"userPreferences": {
"preferredTimeZone": "(UTC-07:00) America/Los_Angeles",
"colorTheme": "NORMAL_CISCO_IDENTITY",
"type": "userpreferences"
},
"userRole": "ROLE_ADMIN",
"identitySourceId": "e3e74c32-3c03-11e8-983b-95c21a1b6da9",
"userServiceTypes": [
"MGMT"
],
"id": "5023d3ab-6dc5-11e8-b9ed-db6dba9bf94c",
"type": "user",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/
object/users/5023d3ab-6dc5-11e8-b9ed-db6dba9bf94c"
}
},
{
"version": "ngx7a2dixngoq",
"name": "radiusreadwriteuser1",
"password": null,
"newPassword": null,
"userPreferences": {
"preferredTimeZone": "(UTC+00:00) UTC",
"colorTheme": "NORMAL_CISCO_IDENTITY",
"type": "userpreferences"
},
"userRole": "ROLE_READ_WRITE",
"identitySourceId": "0a7996ae-6e5b-11e8-bd65-dbab801c44b9",
"userServiceTypes": [
"MGMT"
],
"id": "29b20e67-6e64-11e8-bd65-3582e0f59b48",
"type": "user",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/
object/users/29b20e67-6e64-11e8-bd65-3582e0f59b48"
}
}
],
"paging": {
"prev": [],
"next": [],
"limit": 10,
"offset": 0,
"count": 3,
"pages": 0
}
}
Note This does not include the Authorization: Bearer header, which would be required in an API call from
your client.
Request URL
The URL to issue from your client to make the request. For example, for GET /object/networks:
https://ftd.example.com/api/fdm/latest/object/networks
Response Body
The object that the system returns to your client. If a resource can include multiple objects (such as
/object/network), you get a list of items on a GET request. POST/PUT/DELETE responses will be about
a single object.
The specific content returned is based on the resource model. For example, GET /object/networks returns
a list of objects, with each object looking something like the following (the initial indication of an items
list is also shown). Note that the links/self value indicates the URL you would use to refer to this object;
the object ID is included in the URL.
{
"items": [
{
"version": "900f8558-7d19-11e7-bf7b-3dcaf0c58345",
"name": "AIM_SERVERS-205.188.1.132",
"description": null,
"subType": "HOST",
"value": "205.188.1.132",
"isSystemDefined": true,
"id": "900fac69-7d19-11e7-bf7b-d9417b20e59e",
"type": "networkobject",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/
object/networks/900fac69-7d19-11e7-bf7b-d9417b20e59e"
}
},
GET requests also include a paging section, which is explained in GET: Obtaining Data from the System,
on page 37.
Response Code
The numeric HTTP status code returned for the HTTP call. These are the standard HTTP status codes,
which you can find in RFCs or Wikipedia (such as
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes). For example, 200 (OK) indicates a successful
GET/PUT/POST call, and 204 a successful DELETE call.
Response Headers
These are the packet headers in the HTTP response. For example, GET /object/networks might have
headers such as the following:
{
"date": "Thu, 10 Aug 2017 19:19:16 GMT",
"content-encoding": "gzip",
"x-content-type-options": "nosniff",
"transfer-encoding": "chunked",
"connection": "Keep-Alive",
"vary": "Accept-Encoding",
"x-xss-protection": "1; mode=block",
"pragma": "no-cache",
"server": "Apache",
"x-frame-options": "SAMEORIGIN",
"strict-transport-security": "max-age=31536000 ; includeSubDomains",
"content-type": "application/json;charset=UTF-8",
"cache-control": "no-cache, no-store, max-age=0, must-revalidate",
"accept-ranges": "bytes",
"keep-alive": "timeout=5, max=99",
"expires": "0"
}
Procedure
Step 1 In API Explorer, open a GET method (first, open the group to see the methods and resources).
Step 2 If the method you want to use requires an object or parent ID in the URL, use a parent method to obtain the
needed ID.
For example, GET /objects/networks/{objId} requires the ID of a specific object. Use the GET /objects/networks
method to get a list of network objects, then look for the id value for the object you want to examine. Note
that in this case, the information returned in the GET /object/networks call will be the same as what you see
in GET /objects/network/{objId}. See Finding the Object ID (objId) and Parent ID, on page 8.
• sort—How to sort the objects returned in the response. The default sort is alphabetical by the name
value. To change the sort, enter the name of the attribute within the resource to sort on. For example,
you can use sort=value in network objects to sort on the value (that is, IP address) attribute. To sort in
reverse order, include a minus sign, for example, sort=-name.
• filter (not available for all resources)—Return items that match the filter criteria only. The format of the
filter value is {key}{operator}{value}, where the key is an attribute name and value is the string to filter
on. There are no spaces between the items. The fields you can filter on are listed in the description of
the filter parameter in the API Explorer; the fields differ per object. If an object supports filtering on
multiple fields, you can include multiple values on the filter parameter, separated with a semi-colon (;).
For example, you could filter on gid:1;sid:105 for GET /policy/intrusionpolicies/{parentId}/intrusionrules.
The allowed operators are:
• : for equal to. For example, filter=name:Canada.
• ! for not equal to. For example, filter=name!Canada.
• ~ for similar to. For example, filter=name~United.
• filter=fts~string (not available for all resources)—Return items that match the filter only. The fts~ option
is for full-text search. All attributes in the object are searched for the string. You can include a partial
string; using the asterisk * as a wildcard to match one or more characters is optional. Do not include the
following characters, they are not supported as part of the search string: ?~!{}<>:%. The following
characters are ignored: ;#&.
For example, you could find all network objects that have 10. as the first octet using GET
/object/networks?filter=fts~10. Note that it takes 3-5 seconds to index newly-created or updated objects,
so you need to pause before immediately doing a full-text search on new or changed objects.
• filter=fetchZeroHitCount:{true | false} (available for access rules only)—If you specify
includeHitCounts=true, you can use this filter option to either include (true) or exclude (false) rules
that have not been hit, that is, whose hit count is zero. The default is true.
• includeHitCounts (available for access rules only)—Whether to include hit count information for the
rules in the policy. Specify includeHitCounts=true to get hit counts. Specify false (the default) to
exclude hit counts. The hit count information is returned in the hitCount attribute in the returned object.
• time_duration (available for trending reports only)—How many seconds into the past the report should
include. For example, 1800 returns a report for the past 30 minutes.
Note
Whereas {objId} and {parentId} are part of the URL path, add the offset, limit, sort, filter, includeHitCounts,
and time_duration parameters after a ? character to the end of the URL.
Step 4 Click the Try It Out! button and examine the response.
For successful calls (return code 200), the response body includes one object or a list of objects, depending
on the call you made. For information on the general structure and content of the response, see Trying a
Method and Interpreting the Results, on page 35.
GET requests include a paging section. If there are more objects than were returned for the call, the prev and
next values indicate how to get the previous or next set of objects. The count value indicates the overall
number of objects. The limit value indicates how many items are returned in the response. The offset value
indicates the starting position of the returned objects, with 0 indicating the start of the list.
"paging": {
"prev": [],
"next": [
"https://ftd.example.com/api/fdm/latest/object/networks?limit=10&offset=10"
],
"limit": 10,
"offset": 0,
"count": 22,
"pages": 0
}
Procedure
Step 1 In API Explorer, open a POST method (first, open the group to see the methods and resources).
Step 2 Click Model under the Response Class heading and read about the data types and values for the resource
attributes.
Step 3 Under the Parameters heading, configure the following options if they are available:
• parentId—The ID of the parent object that will contain this object. For example, when adding an SSL
rule, the ID of the SSL Decryption policy.
• at—For objects that reside in a parent that organizes the objects in an ordered list, such as SSL decryption
policies, the location to insert the object. Use an integer to indicate the location, with 0 being the start of
the list. The default is to insert the new object at the end of the list.
Note
Whereas {objId} and {parentId} are part of the URL path, add the at parameter after a ? character to the end
of the URL.
Step 4 Also under the Parameters heading, click the JSON model shown in the Data Type > Example Value
column for the body parameter.
Clicking in this box loads the JSON model into the Value column for the body parameter. For example,
clicking the box for the POST /object/networks resource loads the following body:
{
"name": "string",
"description": "string",
"subType": "HOST",
"value": "string",
"type": "networkobject"
Step 5 Fill in the required values for the body JSON object attributes.
For enum values, be certain to read the allowed values under Response Class > Model. For example, you
can create a network object for a subnet (rather than a host) address by filling in the values and changing the
default value for subType:
{
"name": "new_network_object",
"description": "A subnet object created using the REST API.",
"subType": "NETWORK",
"value": "10.100.10.0/24",
"type": "networkobject"
}
Step 6 Click the Try It Out! button and examine the response.
Examine the curl command used to update the system. Note the additional headers. When you create your
API client, you need to also include these header fields and values. For example, the curl command to create
the sample object is the following. Note the Content-Type and Accept headers.
For successful calls (return code 200), the response body includes the complete object that you created,
including other system-generated values such as version and id. The version and ID values are especially
important, as you need them if you subsequently use PUT to change the object. For information on the general
structure and content of the response, see Trying a Method and Interpreting the Results, on page 35.
The response body also includes the links/self value, which is the URL for the object you created. For example,
the following is the response body for the sample object.
{
"version": "f6d8da48-7ed5-11e7-9bfd-d96183b5f5f1",
"name": "new_network_object",
"description": "A subnet object created using the REST API.",
"subType": "NETWORK",
"value": "10.100.10.0/24",
"isSystemDefined": false,
"id": "f6d8da49-7ed5-11e7-9bfd-27136f5686ad",
"type": "networkobject",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/object/networks/
f6d8da49-7ed5-11e7-9bfd-27136f5686ad"
}
}
Procedure
Step 1 In API Explorer, open a PUT method (first, open the group to see the methods and resources).
Step 2 Under the Parameters heading, configure the following options:
• objId—The id value for the object. For example, 900fac69-7d19-11e7-bf7b-d9417b20e59e.
• parentId—For objects that reside within another object, the ID of the parent object that will contain this
object. For example, when modifying an SSL rule, the ID of the SSL Decryption policy.
• at—For objects that reside in a parent that organizes the objects in an ordered list, such as SSL decryption
policies, the location to insert the object. Use an integer to indicate the location, with 0 being the start of
the list. The default is to insert the object at the end of the list.
Note
Whereas {objId} and {parentId} are part of the URL path, add the at parameter after a ? character to the end
of the URL.
Step 3 Also under the Parameters heading, click the JSON model shown in the Data Type > Example Value
column for the body parameter.
Clicking in this box loads the JSON model into the Value column for the body parameter. For example,
clicking the box for the PUT /object/networks resource loads the following body. Note that this is slightly
different from the POST version for the same resource: the PUT body includes the version attribute.
{
"version": "string",
"name": "string",
"description": "string",
"subType": "HOST",
"value": "string",
"type": "networkobject"
}
Step 4 Fill in the required values for the body JSON object attributes.
Be certain to replicate old values that you do not want to change.
For enum values, be certain to read the allowed values under Response Class > Model. Repeat the old value
unless you are changing the object to a different subtype. For example, the default PUT model for a network
object has HOST for subType, but if you are changing a subnet object, make sure you change subType to
NETWORK.
For example, to update the subnet IP address in a network object, repeat all the old values for all attributes
except value. Enter the new subnet address in value.
{
"version": "f6d8da48-7ed5-11e7-9bfd-d96183b5f5f1",
"name": "new_network_object",
"description": "A subnet object created using the REST API.",
"subType": "NETWORK",
"value": "10.100.11.0/24",
"type": "networkobject",
}
Step 5 Click the Try It Out! button and examine the response.
Examine the curl command used to update the system. Note the additional headers. When you create your
API client, you need to also include these header fields and values. For example, the curl command to update
the sample object is the following. Note the Content-Type and Accept headers.
For successful calls (return code 200), the response body includes the complete object that you updated. Note
that the version value changes, but the object ID (and thus the link/self) stays the same. The version changes
every time you modify an object. For information on the general structure and content of the response, see
Trying a Method and Interpreting the Results, on page 35.
Note
If you did not make any changes to the object, that is, the object being updated is the same as its previous
version, the system does not process the request and instead and sends back a 204 code saying that nothing
has changed for that resource.
For example, the following is the response body for updating the sample object.
"version": "96f5f3cc-7ede-11e7-9bfd-9b7d8a92863f",
"name": "new_network_object",
"description": "A subnet object created using the REST API.",
"subType": "NETWORK",
"value": "10.100.11.0/24",
"isSystemDefined": false,
"id": "f6d8da49-7ed5-11e7-9bfd-27136f5686ad",
"type": "networkobject",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/object/networks/
f6d8da49-7ed5-11e7-9bfd-27136f5686ad"
}
}
Procedure
Step 1 In API Explorer, open a DELETE method (first, open the group to see the methods and resources).
Step 2 Under the Parameters heading, enter the id value for the object in the objId field. For example,
f6d8da49-7ed5-11e7-9bfd-27136f5686ad.
If the object resides within a container, you also need to enter the ID of the parent object into the parentId
field.
Step 3 Click the Try It Out! button and examine the response.
Examine the curl command used to delete the object from the system. Note the additional headers. When you
create your API client, you need to also include these header fields and values. For example, the curl command
to delete the sample object is the following. Note the Accept header.
networks/f6d8da49-7ed5-11e7-9bfd-27136f5686ad'
For successful calls (return code 204 “No Content”), you get an empty response body. This is the expected
result.
Procedure
Step 1 Use the POST /operational/deploy resource in the Deployment group to initiate a deployment.
For example, the curl command would look like the following:
Step 2 Evaluate the response to verify that the deployment job was queued.
A good response (status code 200) looks like the following. Note the state.
{
"id": "62bf405f-796c-11e8-8640-a9156b92ec49",
"statusMessage": null,
"statusMessages": null,
"modifiedObjects": {},
"cliErrorMessage": null,
"queuedTime": 1530036705491,
"startTime": -1,
"endTime": -1,
"state": "QUEUED",
"name": "User (admin) Triggered Deployment",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/operational/deploy/
62bf405f-796c-11e8-8640-a9156b92ec49"
}
}
Note
The cliErrorMessage and name attributes were added in API v2; they are not included in v1 responses.
Step 3 Use the GET /operational/deploy/{objId} resource to check the status of the job.
For example, the curl command would look like the following:
The response might look like the following. Note the state, DEPLOYED, indicates the job completed
successfully. The modifiedObjects parameter lists the objects that were changed in the deployment job. In
this case, there is a single change, to a network object named new-network.
{
"id": "62bf405f-796c-11e8-8640-a9156b92ec49",
"statusMessage": "Deployed Successfully",
"statusMessages": [
"Deployed Successfully"
],
"modifiedObjects": {
"NetworkObject": [
"new-network"
]
},
"cliErrorMessage": null,
"queuedTime": 1530036705491,
"startTime": 1530036705924,
"endTime": 1530036822612,
"state": "DEPLOYED",
"name": "User (admin) Triggered Deployment",
"links": {
"self": "https://ftd.example.com/api/fdm/latest/operational/deploy/
62bf405f-796c-11e8-8640-a9156b92ec49"
}
}
• If you configured remote access VPN, the AnyConnect packages and any other referenced files, such as
client profile XML files, the DAP XML file, and Hostscan packages.
• If you configured custom file policies, any referenced clean list or custom detection list.
Procedure
Step 1 Create the JSON object body for the export job.
Following is an example of the JSON object to use with this call.
{
"diskFileName": "string",
"encryptionKey": "*********",
"doNotEncrypt": false,
"configExportType": "FULL_EXPORT",
"deployedObjectsOnly": true,
"entityIds": [
"string"
],
"jobName": "string",
"type": "scheduleconfigexport"
}
• deployedObjectsOnly—(Optional.) Whether to include objects in the export file only if they have been
deployed. That is, do not include pending changes. This attribute is ignored for
PENDING_CHANGE_EXPORT jobs, because those jobs include undeployed objects only. The default
is false, which means all pending changes are included in the export. Specify true to exclude pending
changes.
• entityIds—A comma-separated list of the identities of a set of starting-point objects, enclosed in [brackets].
This list is required for a PARTIAL_EXPORT job. Each item in this list could be either a UUID value
or an attribute-value pair matching patterns like "id=uuid-value", "type=object-type" or
"name=object-name". For example, "type=networkobject".
The type can be either a leaf entity, such as networkobject, or an alias of a set of leaf types. Some typical
type aliases are: network (NetworkObject and NetworkObjectGroup), port (all TCP/UDP/ICMP port,
protocol and group types), url (URL objects and groups), ikepolicy (IKE V1/V2 policies), ikeproposal
(Ike V1/V2 proposals), identitysource (all identity sources), certificate (all certificate types), object (all
object/group types that would be listed in the device manager on the Objects page), interface (all network
interfaces, s2svpn (all site-to-site VPN related types), ravpn (all RA VPN related types), vpn (both s2svpn
and ravpn).
All of these objects and their outgoing referential descendants will be included in the PARTIAL_EXPORT
output file. Note all the unexportable objects will be excluded from the output even if you specify their
identities. Use the GET method for the appropriate resource types to obtain the UUIDs, types, or names
for the target objects.
For example, to export all network objects, plus an access rule named myaccessrule, and two objects
identified by UUID, you can specify:
"entityIds": [
"type=networkobject",
"id=bab3e3cd-8c70-11e9-930a-1f12ee87d473",
"name=myaccessrule",
"acc2e3cd-8c70-11e9-930a-1f12ee87b286"
]",
• jobName—(Optional.) A name for the export job. Giving the job a name might make it easier to find it
when you retrieve job status.
• type—The job type, which is always scheduleconfigexport.
Example:
The following example performs a full export to the file export-config-1 and accepts the defaults for all other
attributes:
{
"diskFileName": "export-config-1",
"doNotEncrypt": true
"configExportType": "FULL_EXPORT",
"type": "scheduleconfigexport"
}
{
"version": null,
"scheduleType": "IMMEDIATE",
"user": "admin",
"forceOperation": false,
"jobHistoryUuid": "c7a8ba61-629a-11e9-8b8d-0fcc3c9d6d0b",
"ipAddress": "10.24.5.177",
"diskFileName": "export-config-1",
"encryptionKey": null,
"doNotEncrypt": true
"configExportType": "FULL_EXPORT",
"deployedObjectsOnly": false,
"entityIds": null,
"jobName": "Config Export",
"id": "c79be920-629a-11e9-8b8d-85231be77de0",
"type": "scheduleconfigexport",
"links": {
"self": "https://10.89.5.38/api/fdm/latest
/action/configexport/c79be920-629a-11e9-8b8d-85231be77de0"
}
}
{
"version": "hdy62yf5xp3vf",
"jobName": "Config Export",
"jobDescription": null,
"user": "admin",
"startDateTime": "2019-04-19 13:14:54Z",
"endDateTime": "2019-04-19 13:14:56Z",
"status": "SUCCESS",
"statusMessage": "The configuration was exported successfully",
"scheduleUuid": "1ef502ad-62a5-11e9-8b8d-074ebc750708",
"diskFileName": "export-config-1.zip",
"messages": [],
"configExportType": "FULL_EXPORT",
"deployedObjectsOnly": false,
"entityIds": null,
"id": "1f0aad8e-62a5-11e9-8b8d-bb1ebb4d1300",
"type": "configexportjobstatus",
"links": {
"self": "https://10.89.5.38/api/fdm/latest
/jobs/configexportstatus/1f0aad8e-62a5-11e9-8b8d-bb1ebb4d1300"
}
}
You can alternatively use the GET /jobs/configexportstatus/{objId} method to retrieve status for a specific
job. You would get the object ID from the id field in the response object.
Note With GET /action/downloadconfigfile/{objId} you typically specify the file name as the object ID. Alternatively,
you can specify the ID of the ConfigExportStatus object associated with the file.
Procedure
The response would show a list of items, each of which is a configuration file. For example, the following
list shows 2 files. Note that the id for all files is default. Ignore the ID, and use the diskFileName instead.
{
"items": [
{
"diskFileName": "export-config-2.zip",
"dateModified": "2019-04-19 13:32:28Z",
"sizeBytes": 10182,
"id": "default",
"type": "configimportexportfileinfo",
"links": {
"self": "https://10.89.5.38/api/fdm/latest/action/configfiles/default"
}
},
{
"diskFileName": "export-config-1.zip",
"dateModified": "2019-04-19 13:14:56Z",
"sizeBytes": 10083,
"id": "default",
"type": "configimportexportfileinfo",
"links": {
"self": "https://10.89.5.38/api/fdm/latest/action/configfiles/default"
}
}
],
Step 2 Download the file using the diskFileName as the object ID.
The curl command would be similar to the following:
The file is downloaded to your default downloads folder. If you are issuing the GET method from the API
Explorer, and your browser is configured to prompt for download location, you will be prompted to save the
file.
A successful download will result in a 200 return code and no response body.
• The metadata object must specify the appropriate configuration type (configType) value.
• FULL_CONFIG—This text file includes the full device configuration.
• DELTA_CONFIG—This text file includes a partial configuration, perhaps even just a few objects.
{
"type" : "identitywrapper",
"data" : {},
"parentName" : "container-name",
"oldName" : "old-object-name",
"action" : "EDIT", //Enum values: CREATE, EDIT or DELETE
"index" : integer,
}
• index—(Optional; integer.) For objects that are part of an ordered list, such as access control and manual
NAT rules, the position of the object in the policy. If you are creating a new rule and you do not specify
an index value, the rule is added to the end of policy as the last rule. If you are editing the rule, the system
will retain the rule’s existing position.
{"type":"identitywrapper",
"action":"CREATE",
"data":{
"version":"lfxdbtbyg4ex6",
"name":"syslog-host",
"subType":"HOST",
"value":"10.100.10.10",
"isSystemDefined":false,
"dnsResolution":"IPV4_AND_IPV6",
"id":"2cd0ea03-62a7-11e9-8b8d-dbf377c781d8",
"type":"networkobject"}}
Suppose you exported this object from a device, and you want to import the object into a different device, but
the new device should use a syslog server at a different address, 192.168.5.15. Because you are going to create
a new object, remove the version and id attributes from the data attribute. You can also remove
isSystemDefined (whose default is false) and dnsResolution (which is relevant for an FQDN object only).
The resulting new object would look like the following:
{"type":"identitywrapper",
"action":"CREATE",
"data":{
"name":"syslog-host",
"subType":"HOST",
"value":"192.168.5.15",
"type":"networkobject"}}
At the top of the file, you need to retain (or add) the metadata object. You can also add line returns to make
it easier to scan and verify the file content. Thus, the complete configuration file would look like the following:
[
{"hardwareModel":"Cisco Firepower Threat Defense for VMWare",
"type":"metadata",
"configType":"DELTA_CONFIG",
"apiVersion":"latest",
"exportType":"PARTIAL_EXPORT",
"softwareVersion":"6.5.0-10465"}
,
{"type":"identitywrapper",
"action":"CREATE",
"data":{
"name":"syslog-host",
"subType":"HOST",
"value":"192.168.5.15",
"type":"networkobject"}}
]
• If you are using the method from your own program, the request payload must contain a single file-item
with a file-name field. The file-name extension must be either .txt or .zip and the actual file content
format must be consistent with the file extension.
curl -F 'fileToUpload=@./import-1.txt'
'https://10.89.5.38/api/fdm/latest/action/uploadconfigfile’
A successful transfer results in a 200 return code and a response body similar to the following, which shows
the file name on the threat defense system (diskFileName), which you need for the import job.
{
"diskFileName": "import-1.txt",
"dateModified": "2019-04-22 10:18:12Z",
"sizeBytes": 267,
"id": "default",
"type": "configimportexportfileinfo",
"links": {
"self": "https://10.89.5.38/api/fdm/latest/action/uploadconfigfile/default"
}
}
Procedure
Step 1 Create the JSON object body for the import job.
Following is an example of the JSON object to use with this call.
{
"diskFileName": "string",
"encryptionKey": "*********",
"preserveConfigFile": true,
"autoDeploy": true,
"allowPendingChange": true,
"excludeEntities": [
"string"
]",
"inputEntities": [
{
"action": "CREATE",
"oldName": "string",
"parentId": "string",
"parentName": "string",
"index": 0,
"data": {
"version": "string",
"id": "string",
"type": "identity"
},
"id": "string",
"type": "IdEntityWrapper"
}
],
"jobName": "string",
"type": "scheduleconfigimport"
}
"excludeEntities": [
"type=networkobject",
"name=myobj",
"id=acc2e3cd-8c70-11e9-930a-1f12ee87b286"
]",
• inputEntities—If you have a small number of objects to import, you can define them in the inputEntities
object list rather than in a configuration file. To use this attribute, you cannot include the diskFileName
attribute, or you must set that attribute to null.
• jobName—(Optional.) A name for the export job. Giving the job a name might make it easier to find it
when you retrieve job status.
• type—The job type, which is always scheduleconfigimport.
Example:
The following example imports the configuration file named import-1.txt:
{
"diskFileName": "import-2.txt",
"preserveConfigFile": true,
"autoDeploy": true,
"allowPendingChange": true,
"type": "scheduleconfigimport"
}
{
"version": null,
"scheduleType": "IMMEDIATE",
"user": "admin",
"forceOperation": false,
"jobHistoryUuid": "7e360139-6725-11e9-abb5-078014531401",
"ipAddress": "10.24.127.37",
"diskFileName": "import-2.txt",
"encryptionKey": null,
"preserveConfigFile": true,
"autoDeploy": true,
"allowPendingChange": true,
"jobName": "Config Import",
"id": "7e2b52d8-6725-11e9-abb5-5dec35337506",
"type": "scheduleconfigimport",
"links": {
"self": "https://10.89.5.38/api/fdm/latest
/action/configimport/7e2b52d8-6725-11e9-abb5-5dec35337506"
}
}
Step 4 Use GET /jobs/configimportstatus to check the status of the import job.
Alternatively, you can use GET /jobs/configimportstatus/{objId} to get status of one import job. For objId,
use the jobHistoryUuid value from the response body to your POST /action/configimport call.
The curl command would look like the following:
The response body might look like the following for a successful import. If the import fails, you might need
to edit the file to correct formatting or content errors and try again.
{
"version": "pcgccfnk4hmiz",
"jobName": "Config Import",
"jobDescription": null,
"user": "admin",
"startDateTime": "2019-04-25 06:43:54Z",
"endDateTime": "2019-04-25 06:44:01Z",
"status": "SUCCESS",
"statusMessage": "The configuration was imported successfully",
"scheduleUuid": "7e2b52d8-6725-11e9-abb5-5dec35337506",
"diskFileName": "import-2.txt",
"messages": [],
"preserveConfigFile": true,
"autoDeploy": true,
"allowPendingChange": true,
"id": "7e360139-6725-11e9-abb5-078014531401",
"type": "configimportjobstatus",
"links": {
"self": "https://10.89.5.38/api/fdm/latest
/jobs/configimportstatus/7e360139-6725-11e9-abb5-078014531401"
}
}
What to do next
If you set autoDeploy to false, you need to run a deployment job to incorporate the imported changes. Use
the POST /operational/deploy method. If you set it to true, the configuration should have been deployed
successfully. In the device manager or the API (GET /operational/auditevents), you can check the audit log,
and the deployment job is named “Post Configuration Import Deployment.”
Note Some features require particular licenses. For example, a device must have a license for any remote access
VPN features. However, the import process does not validate licenses. Thus, if you import objects for a
license-controlled feature to a device that does not have the required license, the deployment job will fail. If
you encounter this problem, either assign the required licenses to the device, or delete the objects.
For example, to delete the file named export-config-2.zip, the curl command would be the following: