Skip to main content

Verity471

The official Python SDK for the Verity471 API.

The client abstracts low-level API concerns by performing automatic query and payload validation and exposing a clean, typed interface to Verity471 data.

It also bridges the gap to standard CTI workflows by providing built-in STIX mapping for supported data items, allowing easier integration with threat intelligence platforms.

API bindings are generated via OpenAPI Generator, with manual extensions for validation and STIX support.

  • API version: 1.1.12

    • creds: 1.0.4
    • indicators: 1.0.1
    • malware: 1.0.1
    • reports: 1.0.6
    • sources: 1.0.6
    • actors: 1.0.2
    • watchers: 1.0.2
    • observables: 1.0.1
    • entities: 1.0.1
    • girs: 1.0.1
  • Package version: 1.2.1

  • Generator version: 7.21.0

  • Build package: org.openapitools.codegen.languages.PythonClientCodegen

Requirements.

Python >= 3.10

Installation

pip install verity471

This installs the core SDK without optional STIX support.

Optional features

STIX support:

pip install "verity471[stix]"

Development and test dependencies:

pip install "verity471[test]"

Both extras can be installed together:

pip install "verity471[stix,test]"

Install from GitHub

You can also install the SDK directly from the Git repository:

pip install git+ssh://git@github.com/intel471/verity471-python.git

With extras:

pip install "git+ssh://git@github.com/intel471/verity471-python.git#egg=verity471[stix,test]"

Getting Started

Please follow the installation procedure and then run the following:

import verity471
from verity471.rest import ApiException
from pprint import pprint

# Defining the host is optional and defaults to https://api.intel471.cloud
# See configuration.py for a list of all supported configuration parameters.
configuration = verity471.Configuration(
    host = "https://api.intel471.cloud"
)

# The client must configure the authentication and authorization parameters
# in accordance with the API server security policy.
# Examples for each auth method are provided below, use the example that
# satisfies your auth use case.

# Configure HTTP basic authorization: basicAuth
configuration = verity471.Configuration(
    username = os.environ["USERNAME"],
    password = os.environ["PASSWORD"]
)


# Enter a context with an instance of the API client
with verity471.ApiClient(configuration) as api_client:

    # Create an instance of the API class
    api_instance = verity471.IndicatorsApi(api_client)

    threat_type = 'malware' # str | Search indicators by threat type
    malware_family_name = 'trickbot' # str | Search indicators by malware family
    var_from = 1767225600000 # int | Search from specific date (UNIX timestamp in milliseconds)
    size = 10 # int | Number from 1 to 1000 (default to 1000)

    try:
        # Indicators stream
        api_response = api_instance.get_indicators_stream(threat_type=threat_type, malware_family_name=malware_family_name, var_from=var_from, size=size)
        print("The response of IndicatorsApi->get_indicators_stream:\n")
        pprint(api_response)
    except ApiException as e:
        print("Exception when calling IndicatorsApi->get_indicators_stream: %s\n" % e)

Serialization

Each call to an API instance returns a structure composed of Python objects. The response can be serialized into one of the common formats, if needed.

Python dict

To convert the response into a Python dict, call the to_dict() method on the response object.

serialized = api_response.to_dict()

STIX format

Note
STIX support requires optional dependencies.
Install with:

pip install "verity471[stix]"

To convert the response into the STIX format (v2.1), call the to_stix() method on the response object. This method converts the API response into the corresponding STIX objects and returns them wrapped in a Bundle object (from stix2 package). The Bundle object can be serialized into a JSON string using its serialize() method.

bundle = api_response.to_stix()
json_repr = bundle.serialize()

Some responses can be augmented with additional data obtained via extra API calls. This applies only to report-related stream endpoints.

Stream endpoints are designed for search. When a report is large, the returned payload may be truncated: inline images are always removed, and in some cases entire fields are omitted. When fields are omitted, the is_truncated flag is set to true. As a result, the streamed representation may not contain the full report content.

If an instance of verity471.verity_stix.STIXMapperSettings is passed to the to_stix() method with the report_full_content flag set to True, the mapper will issue additional API calls to retrieve the full representation of each truncated report referenced in the stream results. This allows to execute a stream (search) endpoint and serialize it into STIX while still obtaining complete report data.

The STIXMapperSettings instance must be initialized with the verity471 package and an initialized api_client.

For the complete list of available settings, see the implementation of the STIXMapperSettings class in verity471/verity_stix/init.py.

import verity471
from verity471.verity_stix import STIXMapperSettings

configuration = verity471.Configuration(...)

with verity471.ApiClient(configuration) as api_client:
    api_instance = verity471.ReportsApi(api_client)
    api_response = api_instance.get_reports_info_stream(size=1)
    mapper_settings = STIXMapperSettings(
        verity471,
        api_client,
        report_full_content=True
    )
    bundle = api_response.to_stix(mapper_settings)

If the objects returned by the endpoint for some reason can't be mapped into STIX format, EmptyBundle exception will be raised.

At the moment following API methods provide the response in STIX format:

Client's class/method API endpoint Produced outcome
IndicatorsApi.get_indicators_stream /indicators/stream Indicator and Malware SDOs related using Relationship object; URL, IPv4Address, File, DomainName or EmailAddress Observable related with the Indicator SDO using Relationship object
IndicatorsApi.get_indicator_by_id /indicators/{id}
ReportsApi.get_reports_breach_alert_stream /reports/breach-alert/stream Report SDOs with related entities/victims via object_refs (Identity/Org, Malware, ThreatActor, Vulnerability and observables like URL, DomainName, IPv4Address, IPv6Address, EmailAddress, AutonomousSystem, File, UserAccount, CryptocurrencyWallet)
ReportsApi.get_reports_breach_alert_id /reports/breach-alert/{id}
ReportsApi.get_reports_fintel_stream /reports/fintel/stream
ReportsApi.get_reports_fintel_id /reports/fintel/{id}
ReportsApi.get_reports_geopol_stream /reports/geopol/stream
ReportsApi.get_reports_geopol_id /reports/geopol/{id}
ReportsApi.get_reports_info_stream /reports/info/stream
ReportsApi.get_reports_info_id /reports/info/{id}
ReportsApi.get_reports_malware_stream /reports/malware/stream
ReportsApi.get_reports_malware_id /reports/malware/{id}
ReportsApi.get_reports_spot_stream /reports/spot/stream
ReportsApi.get_reports_spot_id /reports/spot/{id}
ReportsApi.get_reports_vulnerability_stream /reports/vulnerability/stream Vulnerability SDOs
ReportsApi.get_reports_vulnerability_id /reports/vulnerability/{id}
SourcesApi.get_forums_posts_stream /forums/posts/stream Channel(s) (forum → sub-forum → thread) + Media-Content (the post) joined by publishes; author handle as an individual Identity; extracted entities as observables; attachments as File
SourcesApi.get_forums_posts_post_id /forums/posts/{id}
SourcesApi.get_forums_private_messages_stream /forums/private-messages/stream Channel + Media-Content joined by publishes; sender/recipient handles as individual Identity objects
SourcesApi.get_forums_private_messages_private_message_id /forums/private-messages/{id}
SourcesApi.get_messaging_services_messages_stream /messaging-services/messages/stream Channel (server/room) + Media-Content joined by publishes; author handle as an individual Identity; attachments as File
SourcesApi.get_messaging_services_messages_message_id /messaging-services/messages/{id}
SourcesApi.get_data_leak_sites_posts_stream /data-leak-sites/posts/stream Channel (site) + Media-Content (the post) joined by publishes; attachments as File
CredentialsApi.get_credentials_stream /credentials/stream UserAccount (password in credential) + EmailAddress (belongs_to_ref), DomainName and stealer Malware linked via Relationship
CredentialsApi.get_credentials_id /credentials/{id}
CredentialsApi.get_credentials_occurrences_stream /credentials/occurrences/stream
CredentialsApi.get_credentials_occurrences_id /credentials/occurrences/{id}
CredentialsApi.get_credential_sets_stream /credential-sets/stream victim organization Identity objects (breach metadata is carried by the alert Incident)
CredentialsApi.get_credential_sets_id /credential-sets/{id}
EventsApi.get_events_stream /events/stream Malware (is_family) + C2 Infrastructure + URL/IPv4Address/File observables joined via uses/consists-of
EventsApi.get_event_by_id /events/{id}
MalwareApi.get_malware_list /malware Malware (is_family) + Software (OS/platform) linked via Relationship
MalwareApi.get_malware_family_by_id /malware/{id}
AlertsApi.get_alerts_stream /alerts/stream Each alert's target is resolved (extra API calls, see fetch_alert_targets) and mapped as above, then wrapped in an Incident (incident_type alert or data-breach) carrying watcher labels + a portal reference and linked related-to the content. Requires api_client on STIXMapperSettings; set alerts_create_incident=False to emit the content without the wrapping Incident. Report targets are fetched with inline images (as when mapping a report directly) unless report_full_content=False

Empty cells inherit the value from the previous row.

Helper: fetch_alert_targets

The alerts stream endpoint returns lightweight StreamingWatcherAlert objects that carry metadata (status, watcher IDs, timestamps, highlights) but not the actual content the alert refers to. fetch_alert_targets resolves each alert's API link in parallel and pairs it with the fully fetched target object — a report, forum post, credential, indicator, or any other supported type.

When a target cannot be fetched (no link, no known SDK route, forbidden, or an unexpected error), the alert is still returned by default with target=None and a status explaining why, so nothing is silently lost. Pass skip_missing_targets=True to omit such alerts instead. Marketplace hits have no SDK route yet, so they come back as bare alerts with status=UNRESOLVABLE (or are omitted when skip_missing_targets=True), the same as any other unresolvable target.

from verity471.helpers import fetch_alert_targets, AlertTarget, AlertTargetStatus

Parameters

Parameter Type Default Description
alerts_response StreamingAlertsResponse (required) The page returned by AlertsApi.get_alerts_stream().
api_client ApiClient (required) An active ApiClient instance (must share credentials with the alerts call).
raise_on_error bool False When True, re-raise unexpected errors (and the missing-link error) instead of recording them on the result.
skip_missing_targets bool False When True, alerts whose target cannot be fetched are omitted from the result. When False (default), they are returned with target=None and a failure status. Marketplace hits (no SDK route yet) are treated like any other unresolvable target.
include_inline_images bool True When True (default), report targets are fetched with their images embedded in the body as base64 data URIs. Set to False for smaller responses, leaving the images as bare attachment URLs. Ignored by target types that have no such option.

Returns

A list of AlertTarget objects in the same order as alerts_response.alerts.

Each AlertTarget exposes:

Attribute Type Description
.alert StreamingWatcherAlert The original alert object (status, watcher IDs, timestamps, highlights, etc.).
.target model instance or None The resolved API object (report, post, credential, …). None when the URL could not be mapped to a known SDK route.
.status AlertTargetStatus Outcome of the target fetch: OK, NO_LINK, UNRESOLVABLE, FORBIDDEN, or ERROR. Anything other than OK means .target is None.
.status_reason str | None Human-readable detail for a non-OK status (the unresolvable URL, the underlying error message, …). None when .status is OK.
.target_summary str | None A compact, human-readable one-liner describing the target. HTML-bearing fields (report bodies and titles, forum posts, chat messages) are reduced to plain text, so the summary is safe to render as-is. Falls back to a summary built from the alert envelope when the target is missing or not summarizable.
.watcher GetWatcherResponse | None The full watcher object that triggered this alert (name, DSL query, mute status, etc.). None if the watcher ID was not found in the user's watcher list.
.watcher_group GetWatcherGroupResponse | None The full watcher group object the watcher belongs to (name, description, etc.). None if not found.

Watcher and group data is fetched once per fetch_alert_targets call (two parallel API requests) and shared by reference across all AlertTarget objects — there is no duplication even when many alerts share the same watcher.

Example usage

import verity471
from verity471.helpers import fetch_alert_targets

configuration = verity471.Configuration(
    username="your_username",
    password="your_password",
)

with verity471.ApiClient(configuration) as api_client:
    alerts_api = verity471.AlertsApi(api_client)
    alerts_response = alerts_api.get_alerts_stream(size=10)

    targets = fetch_alert_targets(alerts_response, api_client)
    for t in targets:
        watcher_name = t.watcher.name if t.watcher else None
        group_name = t.watcher_group.name if t.watcher_group else None
        print(t.alert.source_type, t.alert.status, watcher_name, group_name, t.target_summary)

Example output

fintel read threat_actor Ransomware actors [Fintel] Threat Landscape: Q1 2025 Summary | 2025-03-15T12:00:00Z | Key findings from the first quarter include…
forum_post unread ddos_monitor My Watchers [Forum Post] Selling access to corporate VPN… | 2025-03-14T08:30:00Z
credential_occurrence unread cred_watcher Credential Alerts [Credential Occurrence] https://example.com/login | email | 2025-03-13T10:00:00Z
malware_report read malware_tracker My Watchers [Malware Report] New variant of Lumma Stealer | 2025-03-12T15:45:00Z | A new variant has been observed…

Helper: get_latest

Stream endpoints return data in ascending (oldest-first) order only — there is no way to sort descending or jump directly to the most recent page. get_latest works around this by probing the API with a small time window, expanding it until enough items exist, and then fetching and slicing the tail.

from verity471.helpers import get_latest

Parameters

Parameter Type Default Description
stream_method callable (required) A bound stream API method, e.g. reports_api.get_reports_spot_stream. Must end with _stream.
n int (required) Number of most-recent items to return.
**kwargs Additional filter parameters forwarded verbatim to the stream method (e.g. malware_family_name, threat_type, girs). Do not pass var_from, until, size, or cursor — these are managed internally.

Returns

A list of at most n items in ascending order (oldest first), so the last element is always the single most-recent item. When fewer than n items exist in the full history the function returns however many are available.

How probing works

The helper issues lightweight size=1 probe calls to count matching items in progressively wider time windows (doubling each round), starting from an endpoint-specific seed tuned to typical data density. Once count >= n, the helper drains that window by paging through the cursor and keeps only the newest n items. Because responses are best-effort — a page may contain fewer items than requested when the payload is large — paging continues until the window is drained or an empty page arrives, rather than assuming one request returns the whole window.

Example usage

import verity471
from verity471.helpers import get_latest

configuration = verity471.Configuration(
    username="your_username",
    password="your_password",
)

with verity471.ApiClient(configuration) as api_client:
    reports_api = verity471.ReportsApi(api_client)

    # 20 most recent spot reports
    reports = get_latest(reports_api.get_reports_spot_stream, n=20)
    for r in reports:
        print(r.title, r.released_ts)

    # 50 most recent malware events for a specific family
    events_api = verity471.EventsApi(api_client)
    events = get_latest(
        events_api.get_events_stream,
        n=50,
        malware_family_name="Cobalt Strike",
    )

Documentation for API Endpoints

All URIs are relative to https://api.intel471.cloud

Class Method HTTP request Description
ActorsApi get_actors_stream GET /integrations/actors/v1/actors/stream Retrieve a stream of actors
AlertsApi get_alerts_stream GET /integrations/watchers/v1/alerts/stream Get alerts for the current user in a stream way
AlertsApi put_alerts_id_status PUT /integrations/watchers/v1/alerts/{id}/{status} Change status of an alert
CredentialsApi get_credential_sets_accessed_domains_stream GET /integrations/creds/v1/credential-sets/accessed-domains/stream Credential set accessed domains stream
CredentialsApi get_credential_sets_accessed_urls_stream GET /integrations/creds/v1/credential-sets/accessed-urls/stream Credential set accessed url stream
CredentialsApi get_credential_sets_id GET /integrations/creds/v1/credential-sets/{id} Get credential set by ID
CredentialsApi get_credential_sets_stream GET /integrations/creds/v1/credential-sets/stream Credential set stream
CredentialsApi get_credentials_id GET /integrations/creds/v1/credentials/{id} Get credential by ID
CredentialsApi get_credentials_occurrences_id GET /integrations/creds/v1/credentials/occurrences/{id} Get credential occurrence by ID
CredentialsApi get_credentials_occurrences_stream GET /integrations/creds/v1/credentials/occurrences/stream Credential occurrence stream
CredentialsApi get_credentials_stream GET /integrations/creds/v1/credentials/stream Credential stream
EventsApi get_event_by_id GET /integrations/malware-intel/v1/events/{id} Get event by id
EventsApi get_events_stream GET /integrations/malware-intel/v1/events/stream Stream malware events using a cursor
GIRsApi get_list_of_girs_in_a_hierarchical_structure GET /integrations/girs/v1/girs/tree
IndicatorsApi get_indicator_by_id GET /integrations/indicators/v1/indicators/{id} Get indicator by id
IndicatorsApi get_indicators_stream GET /integrations/indicators/v1/indicators/stream Stream indicators using a cursor
MalwareApi get_malware_family_by_id GET /integrations/malware-intel/v1/malware/{id} Get malware family details by id
MalwareApi get_malware_file GET /integrations/malware-intel/v1/malware/files/{file_name}/download Get malware file using sha256
MalwareApi get_malware_list GET /integrations/malware-intel/v1/malware Get list of malware families.
ReportsApi get_reports_breach_alert_id GET /integrations/intel-report/v1/reports/breach-alert/{id} Get a breach alert report details
ReportsApi get_reports_breach_alert_stream GET /integrations/intel-report/v1/reports/breach-alert/stream Get all breach alert reports (stream)
ReportsApi get_reports_fintel_id GET /integrations/intel-report/v1/reports/fintel/{id} Get a fintel report details
ReportsApi get_reports_fintel_report_id_attachments_attachment_id GET /integrations/intel-report/v1/reports/fintel/{report_id}/attachments/{attachment_id} Get attachment for fintel report
ReportsApi get_reports_fintel_stream GET /integrations/intel-report/v1/reports/fintel/stream Get all fintel reports (stream)
ReportsApi get_reports_geopol_id GET /integrations/intel-report/v1/reports/geopol/{id} Get a geopol report details
ReportsApi get_reports_geopol_report_id_attachments_attachment_id GET /integrations/intel-report/v1/reports/geopol/{report_id}/attachments/{attachment_id} Get attachment for geopol report
ReportsApi get_reports_geopol_stream GET /integrations/intel-report/v1/reports/geopol/stream Get all geopol reports (stream)
ReportsApi get_reports_id_download_as_pdf GET /integrations/intel-report/v1/reports/{id}/download-as-pdf Get a report as PDF
ReportsApi get_reports_info_id GET /integrations/intel-report/v1/reports/info/{id} Get an info report details
ReportsApi get_reports_info_report_id_attachments_attachment_id GET /integrations/intel-report/v1/reports/info/{report_id}/attachments/{attachment_id} Get attachment for info report
ReportsApi get_reports_info_stream GET /integrations/intel-report/v1/reports/info/stream Get all info reports (stream)
ReportsApi get_reports_malware_id GET /integrations/intel-report/v1/reports/malware/{id} Get a malware report details
ReportsApi get_reports_malware_report_id_attachments_attachment_id GET /integrations/intel-report/v1/reports/malware/{report_id}/attachments/{attachment_id} Get attachment for malware report
ReportsApi get_reports_malware_stream GET /integrations/intel-report/v1/reports/malware/stream Get all malware reports (stream)
ReportsApi get_reports_spot_id GET /integrations/intel-report/v1/reports/spot/{id} Get a spot report details
ReportsApi get_reports_spot_stream GET /integrations/intel-report/v1/reports/spot/stream Get all spot reports (stream)
ReportsApi get_reports_stream GET /integrations/intel-report/v1/reports/stream Get all reports (stream)
ReportsApi get_reports_vulnerability_id GET /integrations/intel-report/v1/reports/vulnerability/{id} Get a vulnerability report details
ReportsApi get_reports_vulnerability_id_download_as_pdf GET /integrations/intel-report/v1/reports/vulnerability/{id}/download-as-pdf Get a vulnerability report as PDF
ReportsApi get_reports_vulnerability_stream GET /integrations/intel-report/v1/reports/vulnerability/stream Get all vulnerabilities reports (stream)
SourcesApi get_data_leak_sites_file_listings_id GET /integrations/sources/v1/data-leak-sites/file-listings/{id} Get a data leak site file listing content
SourcesApi get_data_leak_sites_posts_id GET /integrations/sources/v1/data-leak-sites/posts/{id} Get a data leak site post by id
SourcesApi get_data_leak_sites_posts_stream GET /integrations/sources/v1/data-leak-sites/posts/stream Get data leak sites posts (stream)
SourcesApi get_forums_posts_post_id GET /integrations/sources/v1/forums/posts/{post_id} Get a forum post by id
SourcesApi get_forums_posts_stream GET /integrations/sources/v1/forums/posts/stream Get forums posts (stream)
SourcesApi get_forums_private_messages_private_message_id GET /integrations/sources/v1/forums/private-messages/{private_message_id} Get a private message by id
SourcesApi get_forums_private_messages_stream GET /integrations/sources/v1/forums/private-messages/stream Get forums private messages (stream)
SourcesApi get_images_image_type_hash_name GET /integrations/sources/v1/images/{image_type}/{hash}/{name} Download image by type hash and name
SourcesApi get_messaging_services_messages_message_id GET /integrations/sources/v1/messaging-services/messages/{message_id} Get a chat message by id
SourcesApi get_messaging_services_messages_stream GET /integrations/sources/v1/messaging-services/messages/stream Get chat messages (stream)
WatchersApi get_watcher_groups GET /integrations/watchers/v1/watcher-groups Get list of watcher groups for user
WatchersApi get_watchers GET /integrations/watchers/v1/watchers Get list of watchers for the current user
EntitiesApi get_entities_stream GET /integrations/entities/v1/entities/stream Retrieve a stream of entities
ObservablesApi get_observables_stream GET /integrations/observables/v1/observables/stream Retrieve a stream of observables

Documentation For Models

Documentation For Authorization

Authentication schemes defined for the API:

basicAuth

  • Type: HTTP basic authentication

Author

Intel 471 Inc.

Metadata

Release files for verity471 1.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for verity471 1.2.1
File Size Uploaded
verity471-1.2.1.tar.gz 194.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for verity471 1.2.1
File Interpreter ABI Platform
verity471-1.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 645.5 kB

Release files / verity471-1.2.1.tar.gz

Download URL verity471-1.2.1.tar.gz
Size 194.8 kB
Tags Source
SHA-256 checksum
How to use checksums
6f0fa98ed1ea78bf68eaca38142ff0799c8f71dd988cb6b03868b36be8e3f18c
BLAKE2b-256 checksum
How to use checksums
df6635e38156a5de55c1ce3b464fe9f1e2c57318208e50438fa328c269652e6c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / verity471-1.2.1-py3-none-any.whl

Download URL verity471-1.2.1-py3-none-any.whl
Size 450.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bde3dc7f576d4fb0677e673c815508b75627038b3d61c40ed835bb9b239cb617
BLAKE2b-256 checksum
How to use checksums
2c2c9dd012b47f1ac3397b1744c92d565ccdff3ac153159a4b0ce37bae3d9790
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release history Release notifications | RSS feed

1.2.2

2 release files

This release

1.2.1 This release

2 release files

1.2.0

2 release files

1.1.11

2 release files

1.1.9

2 release files

1.1.7

2 release files

1.1.4

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page