API Integrations

Modified on Tue, 6 Aug at 12:16 AM

This is a copy of the API documentation that can be found here.

Introduction

Perception Point API enables the scanning of files and URLs to detect whether they are malicious or clean. Files and URLs are scanned using Perception Point’s multi-layered architecture including HAP (Hardware Assisted Platform). The API can be used in two ways; callbacks or polling. provides a callback mechanism that allows getting notifications when scanning is completed instead of polling the service.

API Structure

Authentication

The request HEADERS must contain an Authorization token:

  • Header Key: “Authorization”

  • Header Value: “Token <TOKEN_VALUE>

Example

response = requests.post(“https://<PERCEPTION-POINT-URL>/someAPI/”,
              headers= { “Authorization”: “Token <TOKEN_VALUE>”},

            )

print response

{"scan_id": 123456}

File API

POST https://<PERCEPTION-POINT-URL>/api/v1/files/

Field Name

Field Description

Mandatory/ Read Only

Field Type

name

Filename to scan 

Mandatory

String

data 

File data

Mandatory*

String

path

Path to the file in storage
(i.e S3 bucket)

Mandatory*

String

download_link

May be passed instead of [data/path]. Must contain a direct download link.

Optional

String

storage

The storage that path reads from (default is our internal S3)

Optional

String

file_password 

The file password

Optional

String

callback_url

The URL the system will send its response to

Optional

String

callback_params

Additional params to be sent to the callback_url

Optional

JSON

callback_headers

Headers for the callback_url
for example, can be used for authentication 

Optional

JSON

*only one is required

The response will be the scan ID, for Example:

{"scan_id": 123456}

If you supply a `callback_params`, then it will be included in the response under `callback_params`. For example:

{“scan_id”: 123456, “callback_params”: {“key1”: “val1”, “key2”:”value2”}}

Examples

  • Request to scan a file in the default storage called sample.doc, with no callback to send the response to.

response = requests.post(“https://<PERCEPTION-POINT-URL>/api/v1/files/”,
              data={"path": "sample.doc"},
              headers= { “Authorization”: “Token <TOKEN_VALUE>”},

            )

print response

{"scan_id": 123456}

  • Request to scan a file from my file system located at /tmp, the file will be called ‘my_file.doc’, the response of the scan will be sent to "https://my-api.com/callback ",
    with {“Auth”: “<TOKEN_VALUE>”} as a header.

file = open(‘/tmp/example.pdf’, ‘rb’)
response = requests.post(“https://<PERCEPTION-POINT-URL>/api/v1/files/”,

              files={"data": file}
              data={
                    “name”:”my_file.doc”,
                    “callback_url”:"https://my-api.com/callback ",

                     “callback_headers”:{ “Auth”: “<TOKEN_VALUE>”},
                  },
              headers= { “Authorization”: “Token <TOKEN_VALUE>”},

            )

print response

{"scan_id": 123456}


URL API

POST https://<PERCEPTION-POINT-URL>/api/v1/urls/

Field Name

Field Description

Mandatory/ Read Only

Field Type

path

The URL to be inspected

Mandatory

String

user_agent_string

A User Agent string the URL will be scanned with

Optional

String

user_location 

The user location (USA, Europe, etc)

Optional

String

callback_url

The URL the system will send its response to

Optional

String

callback_params

Additional params to be sent to the callback_url

Optional

JSON

callback_headers

Headers for the callback_url
for example, can be used for authentication 

Optional

JSON

The response will be the scan ID, for Example:

{"scan_id": 123456}

If you supply a `callback_params`, then it will be included in the response under `callback_params`. For example:

{“scan_id”: 123456, “callback_params”: {“key1”: “val1”, “key2”:”value2”}}

Examples

  1. Request to scan a URL, with no callback to send the response to.

response = requests.post(“https://<PERCEPTION-POINT-URL>/api/v1/urls/”,
              data={"path": "http://www.cnn.com "},
              headers= json.dumps({ “Authorization”: “Token <TOKEN_VALUE>”}),

            )

print response

{"scan_id": 123456}

  1. Request to scan “http://images.google.com ”, the response of the scan will be sent to "https://my-api.com/callback ",
    with {“Auth”: “<TOKEN_VALUE>”} as a header.

response = requests.post(“https://<PERCEPTION-POINT-URL>/api/v1/urls/”,
              data={"path": "http://images.google.com ",
                    “name”:”my_file.doc”,
                    “callback_url”:"https://my-api.com/callback ",

                     “Callback_headers”: json.dumps({
                                                “Auth”: “<TOKEN_VALUE>”}),
                  },
              headers=  json.dumps({“Authorization”: “Token     
                                  <TOKEN_VALUE>”}),

            )

print response

{"scan_id": 123456}


Callback API

  1. The API should be at the URL provided by the callback_url field from the File or URL API’s

  2. The API sends a POST request with the following structure:

    1. The request HEADERS receive its value from callback_headers supplied in the File or URL API’s. In JSON format: {<KEY>: <VALUE>}

    2. The API body will contain the following fields in JSON format:

Field Name

Field Description

scan_id

The id of the scan in the system

name

The name of the file / path of the URL

type 

‘File’ or ‘URL’ accordingly

path

The path to the file in the system’s storage,
or the path to the URL

verdict

The verdict of the scan: 

  • “MAL” - for malicious

  • “CLN” - for clean

evidence

A list of evidence found for the verdict

params

Additional params to be sent to the callback URL received from callback_params from the file or URL API

Examples:

  1. The response from the callback will be:

{

  "verdict": "MAL",

  "scan_id": "123456",

  "name": "FILE.pdf",

  "evidence": "["{

    "Data": {

      "Name": "cfg_trigger",

      "Description": ""

      "module_name": "DeviceHarddiskVolume1Program FilesAdobeAcrobat Reader DCReaderAXE8SharedExpat.dll",

      "module_md5": "000000b5bf63c7d1925599218c6a2a7b",

      "os_and_software": "Win7x86|Acrobat Reader 15"

    },

      }", "{

    "Data": {

      "module_name": "DeviceHarddiskVolume1Program FilesAdobeAcrobat Reader DCReaderAXE8SharedExpat.dll",

      "module_md5": "000000b5bf63c7d1925599218c6a2a7b",

      "os_and_software": "Win7x86|Acrobat Reader 15"

    },

    "Name": "cfg_trigger",

    "Description": null

  }"]",

  "params": "{}",

  "path": "https://FILE_PATH_IN_SERVER.pdf",

  "type": "File"

}



API Response Codes

Response Code

Response Body

Response Meaning

200

{"scan_id": 123456}

The file or URL were received, the corresponding scan id is in the body

403


User not authenticated, probably a token issue

50x 


Internal server error

Examples:

  1. The response will be a list of scans:

response = requests.get(“https://<PERCEPTION-POINT-URL>/api/scans/177”,
                        headers=json.dumps({“Authorization”: “Token <TOKEN_VALUE>”}))

print response

{

    "id": 177,

    "organization": 1,

    "parent_organization_name": null,

    "created_at": "2019-05-28T13:03:50.223119",

    "finished_at": "2019-05-28T13:04:24.444439",

    "start_scanning_at": "2019-05-28T13:03:52.347372",

    "self_finished_at": "2019-05-28T13:04:10.423116",

    "children_finished_at": "2019-05-28T13:04:24.435917",

    "verdict": "CLN",

    "sub_verdict": "CLN",

    "status": "CMP",

    "verbose_status": "CMP",

    "verbose_action": null,

    "verbose_verdict": "CLN",

    "verbose_confidence": "HIGH",

    "origin": "analyze",

    "verbose_origin": "analyze",

    "content_type": 31,

    "object_id": 108,

    "scan_traces": [],

    "joesandbox_report": null,

    "static_signatures": [],

    "sample_type_str": "url",

    "sample_title": "http://www.ynet.co.il ",

    "sample": {

        "id": 108,

        "path": "http://www.ynet.co.il ",

        "scan_id": 177,

        "md5": "934b64e940a3e8c21ad739fdd28beed5",

        "sha1": "d47ff1928f0ca4b7be2dc23f439dfa8237412281",

        "sha256": "20d82f0d02ce46009ac5c6fbfbd4a78932613127a7e0268bcf63e8397e80e905",

        "sha512": "00c8ada9fb63a091316bcfd045d04eec586d6ab88a1b96365e58a34a2e019173880e7821c94c16cda63d6f375401c7f6102e65c7e67dffaf06d516097ba2bd0c",

        "status_code": 200,

        "is_redirect": false,

        "user_agent_string": "",

        "click_count": 0,

        "content_type": "text/html",

        "origin": "analyze",

        "domain": "http://www.ynet.co.il "

    },

    "payload_type": null,

    "sample_file_type": "url",

    "parent_scan_id": null,

    "original_scan_id": null,

    "found_in_cache": false,

    "children": [

        {

            "verbose_verdict": "CLN",

            "verbose_status": "CMP",

            "id": 178,

            "sample_title": "https://www.ynet.co.il/home/0,7340,L-8,00.html ",

            "created_at": "2019-05-28T13:04:09.090512",

            "sample_type_str": "url",

            "sample_file_type": "url",

            "sample_from": null,

            "sample_to": null,

            "payload_type": null,

            "organization_id": 1,

            "origin": "analyze",

            "verbose_origin": "analyze",

            "children": [],

            "has_mal_children": false,

            "highlighted": false

        }

    ],

    "has_warnings": false,

    "children_warning_types_json": [],

    "is_fp": false,

    "is_fn": false,

    "has_mal_children": false,

    "confidence": 0,

    "user_full_name": "<ADDRESS@perception-point.io>",

    "summaries": [],

    "images": [],

    "highlighted": false,

    "organization_id": 1,

    "sample_to": null,

    "sample_from": "<ADDRESS@perception-point.io>",

    "sample_from_type": null,

    "sample_to_type": null,

    "scan_failures": [],

    "siblings": [

        {

            "sample_sha256": "020a96f144d569cb92d4aeeb71fc32a23a6df25b034269f7d1334c42881c1c84",

            "id": 178,

            "sample_title": "https://www.ynet.co.il/home/0,7340,L-8,00.html "

        }

    ],

    "is_root_scan": true,

    "evidence": [],

    "root_evidence": [],

    "is_ready_to_viewer": true,

    "uploaded_to_elastic": true

}


API Response Codes

Response Code

Response Body

Response Meaning

200

In example

Response will contain requested result

403


User not authenticated, probably a token issue

404


Will be returned in one of the following cases:

  • No scan for the given scan id.

  • Scan just were finished or still running (Usually takes 0-2 minutes after scan was finished until the scan data is available)

  • Permission issue if the user isn’t authorized to view data about the scan with the given id

50x 


Internal server error

Change scan verdict:

In order to change the scan verdict we’ll send a PUT request with the new verdict and a comment

Usage (request body)

Field Name

Field Description

Mandatory/ Read Only

Field Type

comment

A comment describing reason for changing verdict

Optional

String

sub_verdict

The new verdict

Can be one of CLN, LSP, BLK, SUS, SPM, MAL

Verdict code

verdict

CLN

Clean

LSP

Likely spam

BLK

Blocked

SUS

Suspicious

SPM

Spam

MAL

Malicious


Required

String

Example:

PUT https://<PERCEPTION-POINT-URL>/api/v1/scans/handle_scan/<SCAN_ID>/

The request body:

PUT /api/v1/scans/handle_scan/<SCAN_ID>

{

    "comment": "I saw him going into a vent",

    "sub_verdict":"SUS"

}


API Response Codes

Response Code

Response Meaning

200

Verdict changed

400

The current sub verdict is the same as the new one requested

Release email:

In order to release email we’ll send GET request to the release from quarantine endpoint

Usage (query params)

Field Name

Field Description

Mandatory/ Read Only

Field Type

should_mark_as_clean

Set to false if you want to release a mail without marking the scan as clean

Optional (default is true)

Bollean

Example:

GET https://<PERCEPTION-POINT-URL>/api/v1/quarantine/release/<SCAN_ID>/


API Response Codes

Response Code

Response Meaning

200

Email released

400

Bad scan id or bad input for should_mark_as_clean parameter

Blacklist / Whitelist API

  • The blacklist / whitelist API will allow being configured as the following:

    • Sender Email Address Blacklist / Whitelist.

    • Sender IP Blacklist / Whitelist.

    • URL Blacklist / Whitelist.

  • You are allowed to do the following actions:

    • Retrieve a single entry.

    • Retrieve all entries.

    • Create a new entry.

    • Modify an existing entry.

    • Delete an existing entry.

Usage

All the lists are sharing a wide of common attributes. Here is a list of the common attributes:

Attribute

Acceptable format

Description

Read Only

id

Integer

Entry ID

Yes

created_by

username <email>

The user who created the entry

Yes

last_updated_by

username <email>

The user who last modified the entry

Yes

owner_organization

Foreign Key as Integer

The organization to apply rule on.

If not given they the user organization is set.

No

Possible assignments:

  • <list_type> might be: blacklist, whitelist

  • <list_target> might be: email, ip, url

Retrieve a single entry:

In order to retrieve a single entry, we’ll send a GET request specifying the entry id:

GET /api/v1/<list_type>/<list_target>/<entry_id>

Example:

GET /api/v1/blacklist/url/2/

{

    "id": 2,

    "comment": "this is an example and I modified it\r\n!",

    "created_by": "Nimrod Wagner <nimrod.wagner@perception-point.io>",

    "last_updated_by": "Nimrod Wagner <nimrod.wagner@perception-point.io>",

    "owner_organization": 1,

    "prefix": "example.com"

}

List the entries:

In order to get a list of all items, we’ll send a GET request:

GET /api/v1/<list_type>/<list_target>/

Example:

GET /api/v1/blacklist/url/

{

    "count": 1,

    "next": null,

    "previous": null,

    "results": [

        {

            "id": 1,

            "comment": "hello world!",

            "created_by": "Nimrod Wagner <nimrod.wagner@perception-point.io>",

            "last_updated_by": "Nimrod Wagner <nimrod.wagner@perception-point.io>",

            "owner_organization": 1,

            "prefix": "http://hello-world.com "

        }

    ]

}

Create a new entry:

In order to create a new entry, we’ll send a POST request:

POST /api/v1/<list_type>/<list_target>/

Please see additional data payload in the relevant section.

The successful response will contain your new entry.

Example:

POST /api/v1/blacklist/url/

{

    "id": 2,

    "comment": "this is an example!",

    "created_by": "Nimrod Wagner <nimrod.wagner@perception-point.io>",

    "last_updated_by": "Nimrod Wagner <nimrod.wagner@perception-point.io>",

    "owner_organization": 1,

    "prefix": "example.com"

}

Modify an existing entry:

In order to modify an entry, we’ll send a PUT request with a payload of the new data:

Example:

PUT /api/v1/<list_type>/<list_target>/<entry_id>

The response will contain the updated entry.

PUT /api/v1/blacklist/url/2/

{

    "id": 2,

    "comment": "this is an example and I modified it\r\n!",

    "created_by": "Nimrod Wagner <nimrod.wagner@perception-point.io>",

    "last_updated_by": "Nimrod Wagner <nimrod.wagner@perception-point.io>",

    "owner_organization": 1,

    "prefix": "example.com"

}

Delete an existing entry:

In order to delete an entry, we’ll send a simple DELETE request specifying the entry id

DELETE /api/v1/<list_type>/<list_target>/<entry_id>

Example

DELETE /api/v1/blacklist/url/2/

Additional attributes:

BlackList / Whitelist Email Address

Attribute

Acceptable format

Description

Read Only

address

Email address format

Email address

No

BlackList / Whitelist IP Address

Attribute

Acceptable format

Description

Read Only

ip

IPv4 IP Address

IP Address

No

BlackList URL Address

Attribute

Acceptable format

Description

Read Only

prefix

IPv4 IP Address

IP Address

No

WhiteList URL Address

Attribute

Acceptable format

Description

Read Only

prefix

IPv4 IP Address

IP Address

No

exact

Boolean (true/ false)

Exact match or not

No

Completed Jobs Report API

The Completed Jobs Report API is made to allow easy access to summaries of jobs that have been completed.

In the API you will be able to:

  • List all of your completed jobs, sorted by completion timestamp.

  • Get a summary (report) for each completed job.

Usage - Completed Job List

To get a completed job list, query the following URL:

GET /api/v1/scans/completed-jobs/

Possible GET query params

Param

Format

Description

Optional

from

10-digit epoch timestamp

Limits the results where timestamp >= from

YES

to

10-digit epoch timestamp

Limits the results where timestamp <= to

YES

Response pattern

{

    "count": <total_queryset_count>,

    "page_result_count": <page_result_count>,

    "next": <next_page_link> or null,

    "results": [

        {

            "verbose_verdict": <CLN|SPM|MAL|BLK>,

            "created_on_elastic_at": <ISO6081 timestamp>,

            "id": <Scan ID>,

        },

        … (more <page_result_count> entries>)

    ]

}

Param

Format

Description

from

10-digit epoch timestamp

Limits the results where timestamp >= from

to

10-digit epoch timestamp

Limits the results where timestamp <= to

For Example:

{

    "count": 2,

    "page_result_count": 2,

    "next": null,

    "results": [

        {

            "verbose_verdict": "CLN",

            "created_on_elastic_at": "2019-08-18T11:59:31.120259",

            "id": 502,

            "_index": "scans.2019-08.write"

        },

        {

            "verbose_verdict": "CLN",

            "created_on_elastic_at": "2019-08-18T11:57:42.456463",

            "id": 501,

            "_index": "scans.2019-08.write"

        }

    ]

}

Example using the from and to params

GET /api/v1/scans/completed-jobs/?from=1566129480

{

    "count": 1,

    "page_result_count": 1,

    "next": null,

    "results": [

        {

            "verbose_verdict": "CLN",

            "created_on_elastic_at": "2019-08-18T11:59:31.120259",

            "id": 502,

            "_index": "scans.2019-08.write"

        }

    ]

}

The reason is that 1566129480 resolves into August 18, 2019 11:58:00 AM.

You can supply to, from or both params.

Usage - Report Completed Job

To get a detailed job report, query the following URL:

GET /api/v1/scans/report/<scan_id>

Where scan_id is an id from the above list.

Response Pattern

{

    "scan_id": <scan_id>,

    "timestamp": <completed-job-finish-time>,

    "name": <file-name-or-url-path>,

    "type": <”file”|”url”>,

    "verdict": <"CLN"|”SPM”|”BLK”|”MAL”|”SUS”>,

    "scan_engines": [<scan engines array>],

    "scan_layers": [<scan layers array>],

    "scan_tree": [<child report array>],

    "evidence": [<evidence array>],

    "decisions": [<decisions array>],

    "params": <all given query params as a json>

}

Field

Description

scan_id

The scan ID queried upon for this response

timestamp

The time that the analysis was completed by the system

type

The type of object

verdict

  • CLN - Object is benign / clean

  • MAL - Object is Malicious

  • SUS - Object is Suspicious

  • BLK - Object should be blocked by policy

  • SPM - Object is Spam

evidence

Describe breadcrumbs or evidence that were collected during the analysis

decisions

Represents the decisions that were applied upon the evidence in order to convict the inspected artifact

scan engines

Describes the engines that triggered during the inspection (and created matching evidence)

scan layers

Describes the logical layers of the product in which the engines are associated with

scan tree

Contains children scan IDs that are associated with this scan

For Example:

GET /api/v1/scans/report/502

{

    "scan_id": 502,

    "timestamp": "2019-08-18T11:59:31.120259",

    "name": "example.docx",

    "type": "file",

    "verdict": "CLN",

    "evidence": [],

    "params": {}

}

Health Check

You can check the availability of the services by querying the Health Check API

GET /v1/health_check

You’ll get the following response:

{

    "hap”: <”on”|”off”>,

    “static”: <”on”|”off”>,

    “status”: <”on”|”off”>

}

Request Investigation 

You can request an investigation for a scan.

GET /api/v1/scans/request-investigation/<scan_id>/

Possible GET query params

Param

Format

Description

Optional

option

Text

  • INV - Please investigate this scan.

  • MAL - I think this scan is malicious.

  • SPM - I think this scan is malicious.

  • CLN - I think this scan is clean

MANDATORY

comment

Text

An additional comment.

OPTIONAL

The response will be a blank 200 OK on success;

Or any other appropriate response if an error occurred.

Delete scan:

In order to delete a scan we’ll send a PUT/POST request with the scan id

Example:

PUT https://<PERCEPTION-POINT-URL>/api/v1/scans/delete_scan/<SCAN_ID>/

POST https://<PERCEPTION-POINT-URL>/api/v1/scans/delete_scan/<SCAN_ID>/


API Response Codes

Response Code

Response Meaning

204

Scan deleted

Scan Search API:

Perception Point exposes an advanced scan search API.

API Endpoint:

GET https://<PERCEPTION-POINT-URL>/api/v1/scans/list/

API parameters can have multiple values. In order to use multiple values, append [] to the end of the parameter name. OR condition is applied between options of the same field.

AND condition is applied between fields.

Example

GET https://<PERCEPTION-POINT-URL>/api/v1/scans/list/?channel=email

GET https://<PERCEPTION-POINT-URL>/api/v1/scans/list/?channel[]=email,api

Accepted Parameters:

Param

Description

start

Lower bound for scan creation time (Inclusive). 10-digit timestamp

end

Upper bound for scan creation time (Inclusive). 10-digit timestamp

organization_id

Filters sub-organization id only

channel

Any of the following:

email, internalemail, onedrivebiz, analyze, s3, dropbox, box, gdrive,api, teams, sharepoint, salesforce, browser

belongs_to_vip

Search for vIP users incidents

verbose_verdict

Any of the following:

  • Malicious: MAL

  • Restricted: BLK

  • Spam: SPM

  • Suspicious: SUS

  • Clean: CLN

handle_status

IR Handling status

search_descendants.subject

Subject

search_descendants.original_message_id

Message ID

verbose_action

One of the following:

indelivery, delivered, quarantine, scanned, delivery_error

sample_from

Sender Address

search_descendants.sender_domain

Sender Domain

search_descendants.source_ip

Sender IP

search_descendants.reply_to

Reply-To Address

search_descendants.source

Return-Path 

receiver_address

Receiver Address

sample.to_users.un_region

Region 

sample.to_users.country

Country

search_descendants.receiver_domain

Receiver Domain

search_descendants.original_file_path

folder

search_descendants.envelope_to

Envelope-To

max_group_size

Min Campaign Size

search_descendants.original_file_name

File Name

search_descendants.original_type

File Type

search_descendants.sample_sha256

File / URL Sha256 hash

search_descendants.mime_type

File Mime Type

search_descendants.path

URL path

search_descendants.domain

Domain

search_descendants.url_title

Webpage title

search_descendants.url_description

URL Description

evidence.data.brand

Brand Name

Examples

Get all scans from 01.07.2021:00:00:00 Until 08.07.2021:03:00:00

GET https://<PERCEPTION-POINT-URL>/api/v1/scans/list/?start=1625097600&end=1625713200

Get all scans from analyze and api channel:

GET https://<PERCEPTION-POINT-URL>/api/v1/scans/list/?channel[]=email,api

Get all highlighted clean scans from email or api channels:

GET https://<PERCEPTION-POINT-URL>/api/v1/scans/list/?channel[]=email,api&is_highlighted=true&verbose_verdict=CLN

Add organization API

POST https://<PERCEPTION-POINT-URL>/api/organizations/

 

Field Name

Field Description

Mandatory/

Default

Field type

name

Name of the organization you are creating

String

active

whether organization is active or not

Boolean

number_of_seats

Number of email addresses in the organization you are creating

Number

origins

The different services will be monitored for the new organization. Can be any one of the following: office365, gmail, onedrivebiz, sharepoint, gdrive, dropbox, salesforce, s3, teams

[]

List

email_report_recipients

Email address to receive reports

null

String

send_malicious_emails

Enable/disable blocking mode for malicious emails

True

Boolean

send_spam_emails

Enable/disable blocking mode for spam emails

True

Boolean

send_blocked_emails

Enable/disable blocking mode for blocked emails

True

Boolean

email_weekly_report

Send weekly reports

True

Boolean

email_monthly_report

Send monthly reports

True

Boolean

email_domains_report

Send domain reports

False

Boolean

email_end_user_on_malicious_alert

Send email to End user when malicious email was blocked

False

Boolean

client_alert_malicious_to_admin_email

Send an alert to admin when malicious email was detected

False

Boolean

 Response

{

    “id”: <created-organization-id>

}

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article