The following document will introduce and document the API endpoints exposed to external clients. All endpoints will work using REST API and JSON format. The documentation will include 2 types of requests and available endpoints - by demand API and event hooks.
Panorays API endpoint is under the domain of https://api.panoraysapp.com All requests should be sent there with the appropriate route and parameters. The API rate limit is 150 requests per minute. Exceeding this limit will result in a 429 HTTP error and a 1-hour block.
All requests to the different endpoints should include an Authorization Token. The Authorization Token is generated by Panorays and sent during onboarding. It should be kept a secret and not shared. The Authorization Token should be sent as part of the Authorization header in the format of Bearer <token>.
Panorays API paginated routes are using cursor pagination, this means the response containing a token that will get you the next page. This way you can send several requests in a loop phrase to get all relevant data.
let res = await axios.get('https://api.panoraysapp.com/v2/suppliers?limit=100');
// Process first page data
// If there is a next page you will get has_next = true, next = <next_token>
while (res.has_next) {
res = await axios.get(`https://api.panoraysapp.com/v2/suppliers?limit=100&next_token=${res.next}`);
// Process next page data
}
Offset pagination is not supported in Panorays API so sending skip as parameter won't work.
Add a new supplier to the portfolio. If a questionnaire is also sent via this request, and you have more than 1 questionnaire template, the latest template will be sent. For information regarding which template is the latest one, please contact Panorays Support. It is recommended to use “Send questionnaire” POST request to send a questionnaire instead.
Supplier created successfully.
Invalid input
Invalid Request. Portfolios are not available for this user
Forbidden.
Too Many Requests
{- "pocs": [
- {
- "email": "user@example.com",
- "name": "string",
- "language": "aa",
- "position": "string",
- "phone": "string"
}
], - "business_impact": 1,
- "business_information": [
- {
- "answer": "string",
- "question_id": "string"
}
], - "evaluation_type": "Continuous 360 Evaluation",
- "portfolios": [
- "string"
], - "questionnaire_contacts": [
- "string"
], - "questionnaire_type": "external",
- "name": "string",
- "asset": "string",
- "questionnaire_template_name": "string",
- "relationships": [
- "string"
], - "tags": [
- "string"
]
}
{- "id": "string"
}
Get all of your suppliers
All found suppliers are returned.
No suppliers found.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "business_information": [
- {
- "type": "text"
}
], - "contacts": [
- { }
], - "questionnaires": [
- {
- "questionnaire_id": "string",
- "questionnaire_score": 0,
- "questionnaire_sent_date": "string",
- "questionnaire_submit_date": "string",
- "questionnaire_type": "string"
}
], - "evaluation_type": "Continuous 360 Evaluation",
- "latest_assessment_date": "string",
- "id": "string",
- "name": "string",
- "relationships": [
- "string"
], - "business_impact": 0,
- "insert_ts": "string",
- "created_by": "string",
- "approval": {
- "status": "PENDING",
- "by": "string",
- "update_ts": "string",
- "reason": "string"
}, - "risk": 0,
- "combined_score": 0,
- "posture_score": 0,
- "tags": [
- "string"
], - "questionnaire_overall_score": 0,
- "portfolios": [
- "string"
], - "segmentId": "string"
}
]
Get a single supplier by id
Supplier found.
Unauthorized.
Forbidden.
Supplier was not found
Too Many Requests
{- "business_information": [
- {
- "type": "text"
}
], - "contacts": [
- { }
], - "questionnaires": [
- {
- "questionnaire_id": "string",
- "questionnaire_score": 0,
- "questionnaire_sent_date": "string",
- "questionnaire_submit_date": "string",
- "questionnaire_type": "string"
}
], - "evaluation_type": "Continuous 360 Evaluation",
- "latest_assessment_date": "string",
- "id": "string",
- "name": "string",
- "relationships": [
- "string"
], - "business_impact": 0,
- "insert_ts": "string",
- "created_by": "string",
- "approval": {
- "status": "PENDING",
- "by": "string",
- "update_ts": "string",
- "reason": "string"
}, - "risk": 0,
- "combined_score": 0,
- "posture_score": 0,
- "tags": [
- "string"
], - "questionnaire_overall_score": 0,
- "portfolios": [
- "string"
], - "segmentId": "string"
}
Update a single supplier by id.
Supplier updated.
Invalid input
Invalid Request. Portfolios are not available for this user
Forbidden.
Too Many Requests
{- "name": "Panorays",
- "assets": [
- "string"
], - "pocs": [
- {
- "email": "user@example.com",
- "name": "string",
- "language": "aa",
- "position": "string",
- "phone": "string"
}
], - "approval": {
- "status": "PENDING",
- "by": "string",
- "update_ts": "string",
- "reason": "string"
}, - "relationships": [
- "string"
], - "tags": [
- "string"
], - "business_impact": 1,
- "business_information": [
- {
- "answer": "string",
- "question_id": "string"
}
], - "evaluation_type": "Continuous 360 Evaluation",
- "portfolios": [
- "string"
]
}
{ }
This endpoint will return data and information about the requested supplier’s tests performed as part of the evaluation.
Tests.
Unauthorized.
Forbidden.
Too Many Requests
{- "severity": "INFO",
- "category": "string",
- "category_text": "string",
- "sub_category": "string",
- "sub_category_text": "string",
- "open_findings_count": 0,
- "closed_findings_count": 0,
- "id": "string",
- "name": "string",
- "criterion_text": "string"
}
This endpoint will create assets of a supplier.
Assets.
Supplier not found.
Unauthorized.
Forbidden.
Connection was not found
Too Many Requests
{- "assets": [
- "127.0.0.10",
- "panorays.com"
]
}
{- "type": "DOMAIN",
- "is_up": true,
- "location": "string",
- "domains": [
- "string"
], - "ips": [
- "string"
], - "asset_lifecycle": "string",
- "dispute_status": "string",
- "discovery_origin": "string",
- "name": "string",
- "insert_ts": "string"
}
Get assets of a specific supplier.
All found assets.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "type": "DOMAIN",
- "is_up": true,
- "location": "string",
- "domains": [
- "string"
], - "ips": [
- "string"
], - "asset_lifecycle": "string",
- "dispute_status": "string",
- "discovery_origin": "string",
- "name": "string",
- "insert_ts": "string"
}
]
This endpoint will return data and information about the requested supplier’s posture in the portfolio.
Posture.
Unauthorized.
Forbidden.
No posture found.
Too Many Requests
{- "categories": [
- {
- "sub_categories": [
- {
- "name": "string",
- "text": "string",
- "grade": 0
}
], - "name": "string",
- "text": "string",
- "grade": 0
}
], - "id": "string",
- "grade": 0,
- "name": "string"
}
This endpoint will return data and information about the posture in the portfolio.
Posture.
Posture not found
Unauthorized.
Forbidden.
Too Many Requests
{- "categories": [
- {
- "sub_categories": [
- {
- "name": "string",
- "text": "string",
- "grade": 0
}
], - "name": "string",
- "text": "string",
- "grade": 0
}
], - "id": "string",
- "grade": 0,
- "name": "string"
}
This endpoint will return the portfolios and the supplier’s id’s under it.
Found portfolios are being returned.
No portfolios found.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "suppliers": [
- {
- "id": "string",
- "name": "string"
}
], - "name": "string"
}
]
The endpoint is used to get all company assets.
All found assets
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "type": "DOMAIN",
- "is_up": true,
- "location": "string",
- "domains": [
- "string"
], - "ips": [
- "string"
], - "asset_lifecycle": "string",
- "dispute_status": "string",
- "discovery_origin": "string",
- "name": "string",
- "insert_ts": "string"
}
]
The endpoint is used to create company assets.
All created assets
Unauthorized.
Forbidden.
Too Many Requests
{- "assets": [
- "127.0.0.10",
- "panorays.com"
]
}
[- {
- "type": "DOMAIN",
- "is_up": true,
- "location": "string",
- "domains": [
- "string"
], - "ips": [
- "string"
], - "asset_lifecycle": "string",
- "dispute_status": "string",
- "discovery_origin": "string",
- "name": "string",
- "insert_ts": "string"
}
]
This endpoint will return data and information about a specific finding.
Finding found
Unauthorized.
Forbidden.
Too Many Requests
{- "status": "OPEN",
- "severity": "LOW",
- "id": "string",
- "metadata": { },
- "cves": [
- "string"
], - "asset_name": "string",
- "category": "string",
- "sub_category": "string",
- "test_text": "string",
- "finding_text": "string",
- "description": "string",
- "insert_ts": "string",
- "update_ts": "string",
- "test_name": "string",
- "segments": [
- "string"
]
}
This endpoint will return data and information about findings in the portfolio.
All found findings are returned.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "status": "OPEN",
- "severity": "LOW",
- "id": "string",
- "metadata": { },
- "cves": [
- "string"
], - "asset_name": "string",
- "category": "string",
- "sub_category": "string",
- "test_text": "string",
- "finding_text": "string",
- "description": "string",
- "insert_ts": "string",
- "update_ts": "string",
- "test_name": "string",
- "segments": [
- "string"
]
}
]
This endpoint will return data and information about findings in the portfolio.
All found findings are returned.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "status": "OPEN",
- "severity": "LOW",
- "id": "string",
- "metadata": { },
- "cves": [
- "string"
], - "asset_name": "string",
- "category": "string",
- "sub_category": "string",
- "test_text": "string",
- "finding_text": "string",
- "description": "string",
- "insert_ts": "string",
- "update_ts": "string",
- "test_name": "string",
- "segments": [
- "string"
]
}
]
THis endpoint is used to get a specific remediation task of a supplier by id.
Supplier remediation task
Invalid input
Unauthorized.
Forbidden.
Task was not found
Too Many Requests
{- "status_reason": {
- "reason": "string",
- "file_id": "string",
- "file_name": "string",
- "added_by": "string",
- "created_at": "string",
- "updated_at": "string"
}, - "account": {
- "full_name": "string",
- "account_id": "string",
- "email": "string"
}, - "company": {
- "id": "string",
- "name": "string"
}, - "question": {
- "type": "FreeText",
- "text": "string",
- "category": "string",
- "question_id": "string",
- "template_id": "string",
- "template_name": "string"
}, - "findings": [
- {
- "status": "OPEN",
- "_id": "string"
}
], - "id": "string",
- "company_id": "string",
- "supplier_id": "string",
- "type": "string",
- "issue_id": "string",
- "created_by": "string",
- "start_date": "string",
- "end_date": "string",
- "due_date": "string",
- "status": "string",
- "description": "string",
- "priority": "string",
- "pocs": [
- "string"
], - "title": "string",
- "created_at": "string",
- "updated_at": "string",
- "inquiry_id": "string",
- "question_id": "string"
}
The endpoint will retrieve all the remediation tasks of a specific supplier
All found remediation tasks.
No remediation tasks found.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "status": "TO_DO",
- "status_reason": {
- "reason": "string",
- "file_id": "string",
- "file_name": "string",
- "added_by": "string",
- "created_at": "string",
- "updated_at": "string"
}, - "account": {
- "full_name": "string",
- "account_id": "string",
- "email": "string"
}, - "company": {
- "id": "string",
- "name": "string"
}, - "question": {
- "type": "FreeText",
- "text": "string",
- "category": "string",
- "question_id": "string",
- "template_id": "string",
- "template_name": "string"
}, - "id": "string",
- "company_id": "string",
- "supplier_id": "string",
- "type": "string",
- "issue_id": "string",
- "created_by": "string",
- "start_date": "string",
- "end_date": "string",
- "due_date": "string",
- "description": "string",
- "priority": "string",
- "pocs": [
- "string"
], - "title": "string",
- "created_at": "string",
- "updated_at": "string",
- "inquiry_id": "string",
- "question_id": "string"
}
]
The endpoint retrieves all the remediation task of all suppliers
All found remediation tasks.
No remediation tasks found.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "status": "TO_DO",
- "status_reason": {
- "reason": "string",
- "file_id": "string",
- "file_name": "string",
- "added_by": "string",
- "created_at": "string",
- "updated_at": "string"
}, - "account": {
- "full_name": "string",
- "account_id": "string",
- "email": "string"
}, - "company": {
- "id": "string",
- "name": "string"
}, - "question": {
- "type": "FreeText",
- "text": "string",
- "category": "string",
- "question_id": "string",
- "template_id": "string",
- "template_name": "string"
}, - "id": "string",
- "company_id": "string",
- "supplier_id": "string",
- "type": "string",
- "issue_id": "string",
- "created_by": "string",
- "start_date": "string",
- "end_date": "string",
- "due_date": "string",
- "description": "string",
- "priority": "string",
- "pocs": [
- "string"
], - "title": "string",
- "created_at": "string",
- "updated_at": "string",
- "inquiry_id": "string",
- "question_id": "string"
}
]
The endpoint is used to get business information questions and structure
Business information template.
Business information template was not found
Unauthorized.
Forbidden.
Too Many Requests
{- "questions": [
- {
- "type": "text",
- "text": "string",
- "mandatory": true,
- "possible_answers": "string",
- "question_id": "string"
}
]
}
The endpoint will retrieve all the files of a specific supplier
All found files.
No files found.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "origin": "businessInformation",
- "type": "jpg",
- "filename": "string",
- "id": "string",
- "added_by": "string"
}
]
This endpoint will return info about the latest questionnaires for each template sent to a specific supplier.
Supplier questionnaires info
Invalid input
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "questionnaire_id": "string",
- "template_name": "string",
- "completion_rate": 1,
- "status": "SENT",
- "ttl": "string",
- "status_update_date": "string",
- "created_by": "string",
- "score": 0,
- "weight": 0,
- "questionnaire_submit_date": "string",
- "questionnaire_sent_date": "string"
}
]
This endpoint will return info about the latest questionnaires for each template sent to a specific supplier including the answers.
Supplier questionnaire answers info
Invalid input
Unauthorized.
Forbidden.
Questionnaires was not found
Too Many Requests
{- "status": "SENT",
- "score": 0,
- "ttl": "string",
- "questions": [
- {
- "type": "FreeText",
- "text": "string",
- "category": "string",
- "possible_answers": [
- "string"
], - "answer": "string",
- "out_of_policy": true,
- "additional_information": "string"
}
], - "id": "string",
- "template_name": "string"
}
This endpoint will extend due date of a questionnaire.
Questionnaire.
Unauthorized.
Forbidden.
Connection was not found
Too Many Requests
{- "note": "string",
- "ttl": "2024-12-20T14:48:56.366Z",
- "questionnaire_type": "internal"
}
{- "questionnaire_id": { },
- "status": "string",
- "ttl": "2019-08-24T14:15:22Z",
- "template_name": "string",
- "weight": 0,
- "created_by": "string",
- "status_update_date": "2019-08-24T14:15:22Z",
- "completion_rate": 0,
- "questionnaire_type": "string"
}
This endpoint will return pdf with questionnaire report.
Report has been found
Unauthorized.
Forbidden.
Report was not found.
Too Many Requests
This endpoint will send questionnaire to supplier.
Questionnaire.
Unauthorized.
Forbidden.
Connection was not found
Too Many Requests
{- "pocs": [
- "user@example.com"
], - "template_id": "string",
- "note": "string",
- "ttl": "2019-08-24T14:15:22Z",
- "questionnaire_type": "external"
}
{- "ttl": "string",
- "id": { },
- "insert_ts": "2019-08-24T14:15:22Z",
- "pocs": [
- { }
], - "status": "string",
- "template_id": "string",
- "template_name": "string"
}
This endpoint returns the tests of the company.
Tests.
Unauthorized.
Forbidden.
Too Many Requests
{- "severity": "INFO",
- "category": "string",
- "category_text": "string",
- "sub_category": "string",
- "sub_category_text": "string",
- "open_findings_count": 0,
- "closed_findings_count": 0,
- "id": "string",
- "name": "string",
- "criterion_text": "string"
}
This endpoint will return data and information about risk insights of the company.
All found risk insights are returned.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "impact_on_my_company": true,
- "impact_on_direct_suppliers": [
- "string"
], - "date_added": "string",
- "last_update": "string",
- "insight_status": "new",
- "event_id": "string",
- "event_type": "vulnerability",
- "event_date": "string",
- "event_title": "string",
- "event_links": {
- "NIST": "string",
- "Additional Information": "string"
}
}
]
Business snapshot.
Business snapshot was not found
Unauthorized.
Forbidden.
Too Many Requests
{- "location": {
- "city": "string",
- "state_code": "string",
- "country_code": "string"
}, - "security_statements": [
- {
- "type": "string",
- "name": "string",
- "isActive": true,
- "link": "string",
- "bug_bounty_url": "string",
- "policy_url": "string"
}
], - "company_name": "string",
- "industry": "string",
- "company_size": "string",
- "company_type": "string",
- "founded_year": 0,
- "capital": "string",
- "linkedin_url": "string",
- "facebook_url": "string",
- "twitter_url": "string"
}
This endpoint will return business snapshot information.
Business snapshot.
No business snapshot found.
Unauthorized.
Forbidden.
Connection was not found
Too Many Requests
{- "location": {
- "city": "string",
- "state_code": "string",
- "country_code": "string"
}, - "security_statements": [
- {
- "type": "string",
- "name": "string",
- "isActive": true,
- "link": "string",
- "bug_bounty_url": "string",
- "policy_url": "string"
}
], - "company_name": "string",
- "industry": "string",
- "company_size": "string",
- "company_type": "string",
- "founded_year": 0,
- "capital": "string",
- "linkedin_url": "string",
- "facebook_url": "string",
- "twitter_url": "string"
}
This endpoint will return all defined relationships.
Unauthorized.
Forbidden.
Too Many Requests
This endpoint will return data and information about licenses of the company.
Array of product names with the corresponding quantity and usage.
Unauthorized.
Forbidden.
Not Found.
Too Many Requests
{- "licenses": [
- {
- "productName": "Continuous 360 Evaluation",
- "quantityPurchased": 0,
- "quantityUsed": 0
}
]
}
Get all company templates
All templates are returned.
Unauthorized.
Forbidden.
Too Many Requests
[- {
- "status": "DRAFT",
- "weight": 1,
- "template_display_name": "string",
- "template_name": "string",
- "description": "string",
- "created_at": "string",
- "updated_at": "string",
- "created_by": "string",
- "updated_by": "string"
}
]
The following steps will walk you trough the process of registering and reacting to webhooks
Panorays signs every request with a secret that's unique to your service account, using this secret you can verify that the incoming request arrived from Panorays servers.
On every request Panorays sends we provide X-Panorays-Signature
header, this header contains a signature created from combining the event body, the request time and your secret using an HMAC SHA256 keyed hash.
By recreating this code on your side and comparing the values you can verify that the event came from Panorays.
secret = 'kqouK3lV+xOWzZ3SOvBv5lhbVhjolJJQs51hM8jG0xA60WqAz0wz/fMDqf/dd8rP'
X-Pano-Request-Time
header timestamp = request.headers['X-Pano-Request-Time']
:
as a delimiter signature = createHmac('sha256', secret)
.update(`${timestamp}:${JSON.stringify(request.body)}`)
.digest('base64');
X-Panorays-Signature
header. if (signature !== request.headers['X-Panorays-Signature']) {
// stop everything and hide.
}
Before being able to register and receive events, a server should be registered and verified. A “Verification Handshake” will happen which will verify SSL certificate and send a POST with a body of { challenge: <hash> }
to the server given. The response to the POST message should contain the given challenge hash and status 200.
The verification handshake process should only happen once and will be done during the onboarding of the API by Panorays.
url registered, secret generated
Unauthorized.
Forbidden.
Too Many Requests
{- "url": "string"
}
{- "secret": "string"
}
To enable notifications for a certain event you will need to subscribe to it using this route.
Subscription complete
One or more of the given hooks are already subscribed to.
Unauthorized.
Forbidden.
Too Many Requests
{- "hooks": [
- "url_verification"
]
}
{- "secret": "string"
}
{- "type": "approval_changed",
- "event": {
- "old_status": "PENDING",
- "new_status": "PENDING",
- "changed_by": "user@example.com",
- "timestamp": "string",
- "supplier_name": "string",
- "supplier_id": "string"
}
}
To disable notifications for a certain event you will need to unsubscribe from it using this route.
Unsubscribed successfully
One or more of the given hooks are not subscribed to.
Unauthorized.
Forbidden.
Too Many Requests
{- "hooks": [
- "url_verification"
]
}
{- "secret": "string"
}