API Methods

CRUD API

Authentication API

Authenticate

This API is used to generate a JWT authentication token for FortiSOAR™ authentication using username and password. It returns a JSON response containing the JWT token which you can then use to call other FortiSOAR™ APIs by passing it into the Authorization header. For example, Authorization: "Bearer {Token}".

Request

  METHOD: POST
  URL: https://{HOSTNAME}/auth/authenticate
  BODY:
  {
    "credentials":
    {
        "loginid": "{{username}}",
        "password":"{{password}}"
    }
  }

Response

{
    token:  VALID JWT TOKEN"
}

You can deploy the FortiSOAR™ enterprise license by running the csadm command as a root user: csadm license --deploy-enterprise-license <License File Path> . For more information on the FortiSOAR™ Admin CLI (csadm), see the FortiSOAR™ Admin CLI chapter in the "Administration Guide." For more information on licensing, see the Licensing FortiSOAR™ chapter in the "Deployment Guide."

Deploying the FortiSOAR™ license using the API

Before you can deploy the license file using the API, you require to generate the authorization token. Use the following curl call to get the token:

curl -X POST \
  https://<fortisoar_host>/auth/authenticate \
  -H 'Content-Type: application/json' \
  -d '{
    "credentials":
    {
        "loginid":"<loginid>",
        "password":"<password>"
    }
}

To deploy the license file using the API, make the following REST call:

curl -X POST 
  'https://<hostname>/api/auth/license 
  -H 'authorization: AUTH_TOKEN' 
  -H 'content-type: application/json'  
  -d '{
        "license_key" : "LICENSE_KEY"
    }' 

The LICENSE_KEY value is the contents of the license file generated during the license generation step. As this API is an authenticated API, it can be used only when a valid license is already deployed. A successful deployment returns an HTTP 200 OK status.

Retrieving the license details

Once you have successfully deployed a FortiSOAR™ license, you can retrieve the details of your license at any time using the following API:

curl -X GET 
  'https://<fortisoar_host>/auth/license/?param=license_details'  
  -H 'authorization: AUTH_TOKEN' 

The API displays a message similar to the following:

{
  "expired": false,
  "expired_nodes": [],
  "remaining_days": 180,
  "details": {
    "is_distributed": false,
    "role": [
      "master"
    ],
    "entitlements": {}
  },
  "nodes": {
    "6d1a908cc06887910ed3237e0c233fb1": {
      "message": "License Details: Max Users: 10, Expiring on: 2019-11-03, Issued for 180 days",
      "details": {
        "total_users": 10,
        "remaining_users": 9,
        "expiring_on": "2019-11-03",
        "issue_time": "2019-05-07 06:26:13.368238",
        "total_days": 180,
        "remaining_days": 180,
        "customer_name": "abc",
        "is_distributed": false,
        "entitlements": {},
        "role": [
          "master"
        ]
      },
      "node": {
        "nodeId": "6d1a908cc06887910ed3237e0c233fb1",
        "nodeName": "fortisoar.localhost",
        "status": "active",
        "role": "primary",
        "currentState": "primary server"
      }
    }
  }
}

Model Operations

Create Individual Model Records

Request

METHOD: POST
URL: /api/{version}/{collection}
BODY:
{
  "field1": "value1",
  "field2": "value2"
}

Example

Request

METHOD: POST
URL: /api/3/assets
BODY:
{
  "ip": "8.8.8.8",
  "hostname": "google-public-dns-a.google.com"
}
Response
STATUS: 201
BODY:
{
  "@id": "/api/3/assets/01199609-d60f-356b-a762-129a6e1b353b",
  "@type": "Asset",
  "ip": "8.8.8.8",
  "hostname": "google-public-dns-a.google.com"
}

Retrieve Collection of Model Records

The responses adhere to the Hydra Spec for pagination. Records that match the specified query (see Filtering for more info) are returned as objects within the "hydra:member" array.

Request

METHOD: GET
URL: /api/{version}/{collection}
Response
STATUS: 200
BODY:
{
  "@context": "/api/{version}/contexts/{collection type}",
  "@id": "/api/{version}/{collection}",
  "@type": "hydra:PagedCollection",
  /* Contains some Hydra pagination properties */
  "hydra:member": [
    { "@id": "/api/{version}/{collection}/{uuid}", ... },
    { "@id": "/api/{version}/{collection}/{uuid}", ... },
    { "@id": "/api/{version}/{collection}/{uuid}", ... }
  ]
}

Example

Request

METHOD: GET
URL: /api/3/assets
Response
STATUS: 200
BODY:
{
  "@context": "/api/3/contexts/Asset",
  "@id": "/api/3/assets",
  "@type": "hydra:PagedCollection",
  "hydra:totalItems": 2,
  "hydra:itemsPerPage": 30,
  "hydra:firstPage": "/api/3/assets",
  "hydra:lastPage": "/api/3/assets",
  "hydra:member": [
    {
      "@id": "/api/3/assets/01199609-d60f-356b-a762-129a6e1b353b",
      "@type": "Asset",
      "ip": "8.8.8.8",
      "hostname": "google-public-dns-a.google.com"
    },
    {
      "@id": "/api/3/assets/017d3845-e204-367c-b74d-6bb37a8239b7",
      "@type": "Asset",
      "ip": "8.8.4.4",
      "hostname": "google-public-dns-b.google.com"
    }
  ]
}

Retrieve Single Model Records

Request

METHOD: GET
URL: /api/{version}/{collection}/{uuid}
Response
STATUS: 200
BODY:
{
  "@id": "/api/{version}/{collection}/{uuid}",
  "@type": "{collection type}",
  "field1": "value1",
  "field2": "value2"
}

Example

Request

METHOD: GET
URL: /api/3/assets/01199609-d60f-356b-a762-129a6e1b353b
Response
STATUS: 200
BODY:
{
  "@id": "/api/3/assets/01199609-d60f-356b-a762-129a6e1b353b",
  "@type": "Asset",
  "ip": "8.8.8.8",
  "hostname": "google-public-dns-a.google.com"
}

Update Single Model Records

Request

METHOD: PUT
URL: /api/{version}/{collection}/{uuid}
BODY:
{
  "field1": "value1",
  "field2": "value2"
}

Example

Request

METHOD: GET
URL: /api/3/assets/01199609-d60f-356b-a762-129a6e1b353b
BODY:
{
  "ip": "8.8.8.8"
}
Response
STATUS: 200
BODY:
{
  "@id": "/api/3/assets/01199609-d60f-356b-a762-129a6e1b353b",
  "@type": "Asset",
  "ip": "8.8.8.8",
  "hostname": "google-public-dns-a.google.com"
}

Delete Single Model Records

Danger

Deleting models can result in system instability and data model. We advise that you do not delete models after creation.

Request

METHOD: DELETE
URL: /api/{version}/{collection}/{uuid}

Example

Request

METHOD: DELETE
URL: /api/3/assets/01199609-d60f-356b-a762-129a6e1b353b
Response
STATUS: 204
REASON: No Content

Insert records in bulk

You can use the Bulk Insert API to insert records in bulk, in a module that you specify.

Note: It is recommended that you insert up to 100 records in single request and loop over your dataset.

Request

METHOD: POST
URL: {{YourFortiSOARHostname}}/api/{version}/insert/{moduleType}
BODY: {
        "data: [{record 1}, {record 2}]
      }     
}

Example

Request

METHOD: POST
URL: {{YourFortiSOARHostname}}/api/3/insert/alerts
BODY: {
        "data": [
        {
            "name": "bulk record 1",
            "description": "<p>bulk record 1 description</p>",
            "severity": "/api/3/picklists/58d0753f-f7e4-403b-953c-b0f521eab759"
        },{
            "name": "bulk record 2",
            "description": "<p>bulk record 2 description</p>",
            "severity": "/api/3/picklists/58d0753f-f7e4-403b-953c-b0f521eab759"
        },{
            "name": "bulk record 3",
            "description": "<p>bulk record 3 description</p>",
            "severity": "/api/3/picklists/58d0753f-f7e4-403b-953c-b0f521eab759"
        }
    ]   
}
Response: If all the records are inserted successfully, then you will get a 200 OK response. If not all the records can be inserted, then you will get a 207 (Partially Deleted) response.

Example of a complete response:

{
   @context”: /api/3/contexts/Alert,
   @id”: null,
   @type”: hydra:Collection,
   hydra:member”: [
       {
           inserted record data
       }
   ]
}

Delete records in bulk

You can use the Bulk Delete API to delete records in bulk, in a module that you specify.

Request

METHOD: DELETE
URL: {{YourFortiSOARHostname}}/api/{version}/delete/{moduleType}
BODY: {
        "ids": ["value1", "value2", "value3"]
      }     
}

Example

Request

METHOD: DELETE
URL: {{YourFortiSOARHostname}}/api/3/delete/alerts
BODY: {
        "ids": ["13d7115a-2d4d-4bfb-bdb8-efabfce547f011", 
                "13d7115a-2d4d-4bfb-bdb8-efabfce547f012", 
                "13d7115a-2d4d-4bfb-bdb8-efabfce547f013"]
      }     
}

Response: If all the records are deleted successfully, then you will get a 200 OK response. If not all the records can be deleted, if for example, you have provided an ID of an already deleted record, then you will get a 207 (Partially Deleted) response.

Update records in bulk

You can use the Bulk Update API to update records in bulk, in a module that you specify.

Request

METHOD: PUT
URL: {{YourFortiSOARHostname}}/api/{version}/update/{moduleType}
BODY: {
    data : [
        {
            "field1": "value1",
            "field2": "value2", 
            "field3": "value3"
        },
        {
            "field1": "value1",
            "field2": "value2", 
            "field3": "value3"
        }
    ]
}

Example

Request

METHOD: PUT
URL: {{YourFortiSOARHostname}}/api/3/update/alerts
BODY: {
    data : [
        {
            “@id: /api/3/alerts/a3abeb23-f323-45a9-856b-2bf9d10386cb,
            source: 1238765, 
            "description": "Test 1"
        },
        {
            “@id: /api/3/alerts/8c086c21-2c79-4488-ae22-d0e116469fe2,
            source: 097353,
            description: Test 2,
        }
    ]
}

Response: The response will contain all the fields specified in the metadata of the module. Following is a snippet extract of a successful response:

STATUS: 200
BODY: {
    data : [
        {
            “@id: /api/3/alerts/a3abeb23-f323-45a9-856b-2bf9d10386cb,
            source: 1238765, 
            "description": "Test 1"
        },
        {
            “@id: /api/3/alerts/8c086c21-2c79-4488-ae22-d0e116469fe2,
            source: 097353,
            description: Test 2,
        }
    ]
}

Notes:

  • If you provide the body of the request appropriately, then all the records get successfully updated to the specified module, and you get a 200 OK response.
  • If you do not provide an id for an object (record), then the module is partially updated with the records that have an associated id. Records that do not have an id will not be updated in the specified module. In this case, you get a 207 response, which will list the records that are not updated.
  • If you specify a null value for any field, those records get successfully updated.

Upsert records

Important

That upsert works only if you have defined uniqueness for records in the module you want to upsert records. If you have not defined record uniqueness, the upsert operation will always insert records. Also, note that when you are upserting records, fields that are marked as non-editable also get updated and the upsert behavior for uniqueness will not work for fields that are marked as encrypted.

Single Upsert API

You can use the Upsert API to either update an existing record, if any record matches the unique list of fields you have specified for that module using the Module Editor, or insert a new record.

Request

Following is a sample request for a single upsert request:

METHOD: POST
URI: {{YourFortiSOARHostname}}/api/3/upsert/{moduleType}
BODY: 
      {
        "name": "value1",
        "sourceId": null, 
        "severity": "value2"
      }

Bulk Upsert API

You can use the Bulk Upsert API to either bulk update multiple records, if the records match the unique list of fields you have specified for that module, or bulk insert new records.

Request

Following is a sample request for a bulk upsert request:

METHOD: POST
URI: {{YourFortiSOARHostname}}/api/3/bulkupsert/{moduleType}
BODY:[ 
       {
        "name": "value1",
        "sourceId": "null", 
        "severity": "value2"
       },
      {
        "name": "value1",
        "sourceId": "null", 
        "severity": "value2"
       }
]

Response: If all the records are upserted successfully, then you will get a 200 OK response. If some records are upserted successfully and some records are not upserted, then you will get a 207 (Partial Upsert) response. If none of the records are upserted successfully, then you will get a 400 response.

Relationship Operations

For these examples, we will expect that an Incident has already been created in the system. All these operations will affect the assets field of an Incident.

Get Relationship

Request

METHOD: GET
URL: /api/3/incidents/bbdc13f8-015f-4615-8c63-4cebb6ec991b/assets
Response
{
  "@context": "/api/3/contexts/Asset",
  "@id": "/api/3/incidents/bbdc13f8-015f-4615-8c63-4cebb6ec991b/assets",
  "@type": "hydra:PagedCollection",
  "hydra:totalItems": 1,
  "hydra:itemsPerPage": 30,
  "hydra:firstPage": "/api/3/incidents/bbdc13f8-015f-4615-8c63-4cebb6ec991b/assets",
  "hydra:lastPage": "/api/3/incidents/bbdc13f8-015f-4615-8c63-4cebb6ec991b/assets",
  "hydra:member": [
    {
      "@id": "/api/3/assets/2ac5eafd-e7dd-465e-8ddd-6b9aeb7125c0",
      "@type": "Asset",
      "macAddress": "as:se:t2",
      "id": 639
    }
  ]
}

Append Existing Object to Relationship

Request

METHOD: POST
URL: /api/3/incidents/bbdc13f8-015f-4615-8c63-4cebb6ec991b/assets
BODY:
{
  "@id": "/api/3/assets/e0a3521f-67de-473f-a9a0-7f2d44626567"
}
Response
{
  "@id": "/api/3/assets/e0a3521f-67de-473f-a9a0-7f2d44626567",
  "@type": "Asset",
  "macAddress": "as:se:t1",
  "id": 638
}

Append New Object to Relationship

Request

METHOD: POST
URL: /api/3/incidents/bbdc13f8-015f-4615-8c63-4cebb6ec991b/assets
BODY:
{
  "macAddress": "as:se:t3",
  "assetType": "laptop"
}
Response
{
  "@id": "/api/3/assets/5434a6e1-e9cd-4ecf-ba6b-f8ac82c3effc",
  "@type": "Asset",
  "macAddress": "as:se:t3",
  "id": 639
  "assetType": "laptop"
}

Delete Relationship

Request

METHOD: DELETE
URL: /api/3/incidents/bbdc13f8-015f-4615-8c63-4cebb6ec991b/assets/
e0a3521f-67de-473f-a9a0-7f2d44626567

Response

STATUS: 204
REASON: No Content

Audit Log Purge Operations

You can use the Audit Log Purge API to purge audit logs on an automated as well as on-demand basis.

Stop Automatic Purging of Audit Logs

To stop automatic purging of audit logs, run the following API:

Request

Method: DELETE 
URL:  /gateway/audit/activities/ttl
Content-Type: application/json
Authorization: <Bearer Token>

Example:

DELETE /gateway/audit/activities/ttl
Content-Type: application/json
Authorization: <Bearer Token>

Response: If the API is successfully run you will get a 200 OK response, which stops the automatic purging of audit logs.

Delete audit logs before a particular date

To delete audit logs before a particular date, run the following API:

Request

Method: DELETE 
URL:  /gateway/audit/activities
Authorization: <Bearer Token>
Cache-Control: no-cache

Example:

DELETE /gateway/audit/activities?uptoDate=1524477805
Authorization: <Bearer Token>
Cache-Control: no-cache

Response: If the API is successfully run you will get a 200 OK response and then audit logs that exist before the specified date will be purged.