Signal AI Risk Events API
The Risk Events API from Signal AI — 3 operation(s) for risk events.
The Risk Events API from Signal AI — 3 operation(s) for risk events.
openapi: 3.1.0
info:
title: Signal AI Affinity Risk Events API
description: "# Overview\n\nThe Signal AI API is an HTTP+JSON API offering programmatic access to Signal AI's decision augmentation platform.\nSignal AI has the world's largest dataset of real-time, global news and regulatory information. Our proprietary AIQ framework understands, enriches and surfaces relevant news and regulatory data in real-time, and at scale.\n\nOur API offers three powerful capabilities:\n\n1. **Content Search**: Create hyper-relevant content feeds using Signal's AI-powered search\n1. **Content Metrics**: Get coverage & sentiment metrics at a glance to power Business Intelligence & data visualisation solutions\n1. **Affinity**: Uncover unknowns through the Signal AI Knowledge Graph\n1. **Events**: Identify significant clusters of news coverage about entities and topics of interest\n\nTo be able to interact with the Signal AI API endpoints and get the most value out of them, it is useful to understand the metadata concepts that our AI enriches content with.\n\n# Concepts\n\n## Topics\n\nSignal AI experts have trained over 300 topics (or themes), from Health to Blockchain to provide clients an easy way to track emerging trends relevant to their businesses.\nClients can also train their own topics with help from our experts for use in our API.\nThe API provides the ability to query for documents pertaining to one or many topics. Examples of topics include: `Renewable Energy`, `Autonomous Vehicles`, `Corporate Responsibility`, `Artificial Intelligence`, etc.\n\n## Entities\n\nOur world-leading entity extraction ensures you never miss updates about the people, places or companies you or your clients care about most. Signal AI uses machine learning to identify and disambiguate these entities so it can discern between _‘Iceland’_ the supermarket and _‘Iceland’_ the country.\nThe API provides the ability to query for mentions of one or many entities. Examples of entities include: `Tim Cook`, `Apple Inc.`, `United States`, `Hong Kong`, etc.\n\n### Sentiment\n\nOur proprietary AIQ framework looks at the context within articles to identify the sentiment around every mention of an entity in the article's content.\nFor example, if an article mentions _“Volvo’s new electric vehicles provide better range than the Tesla Model 3”_, Signal AI will recognise Volvo as having a positive sentiment while Tesla as negative.\nEach mention is then given a `negative`, `neutral`, or `positive` label which is included in the metadata returned with each document. In addition, an aggregated document-level sentiment label is also computed for each entity, indicating the overall sentiment around this entity in the document.\nSentiment labels are only attached to entities and their mentions, and not to topics.\n\n### Salience\n\nA salience score is computed for every entity found in an article. It provides information about the importance or centrality of that entity to the entire article text. The higher the score, the more the article is ‘about’ the entity. We expose this as a `salient` boolean attribute if the score is above a threshold.\nThe `salience-rank` of the entity is the rank order of each entity's salience score. The entity of rank 1 is the most central to the article. It is possible that an article contains no salient entities.\n\nWhen querying by entity, it is also possible to increase the relevance of results by restricting the search to documents for which these entities are salient, using the `where.entities.salient-only` flag.\n\nNext, we describe the different API endpoints that enable these capabilities\n\n# Authorization\n\nAccess to the API is authorized using OAuth2 Bearer Tokens.\n\n<!-- ReDoc-Inject: <security-definitions> -->\n\n# Endpoints\n\n## Concept Discovery\n\nThe following endpoints allow the exploration of Signal AI's trained concepts (topics and entities), and publication sources, for the purpose of crafting content search and affinity-related queries.\n\n### `/topics`\n\n```bash\ncurl \\\n -H \"Authorization: Bearer eyJhbGciOi…\" \\\n -H \"Content-Type: application/json\" \\\n https://api.signal-ai.com/topics?name=environment&size=10\n```\n\n### `/categories/iptc-media-topics`\n\n```bash\ncurl \\\n -H \"Authorization: Bearer eyJhbGciOi…\" \\\n -H \"Content-Type: application/json\" \\\n https://api.signal-ai.com/categories/iptc-media-topics\n```\n\n### `/entities`\n\n```bash\ncurl \\\n -H \"Authorization: Bearer eyJhbGciOi…\" \\\n -H \"Content-Type: application/json\" \\\n https://api.signal-ai.com/entities?type=person&name=cook&size=10\n```\n\n### `/sources`\n\n```bash\ncurl \\\n -H \"Authorization: Bearer eyJhbGciOi…\" \\\n -H \"Content-Type: application/json\" \\\n https://api.signal-ai.com/sources?name=times&size=10\n```\n\n### `/source-locations`\n\n```bash\ncurl \\\n -H \"Authorization: Bearer eyJhbGciOi…\" \\\n -H \"Content-Type: application/json\" \\\n https://api.signal-ai.com/source-locations\n```\n\n## Content Search\n\nThis endpoint allows searching through Signal AI's vast content datasets, using a sophisticated query language.\n\n### `/search`\n\n```bash\ncurl \\\n -H \"Authorization: Bearer eyJhbGciOi…\" \\\n -H \"Content-Type: application/json\" \\\n -X POST \\\n -d '{ \"where\": { \"entities\": { \"id\": { \"eq\": \"11cab8df-4be1-470f-8f49-8f7f0863ec95\" } } } }' \\\n https://api.signal-ai.com/search\n```\n\n## Content Metrics\n\nThis endpoint provides aggregated metrics over all our news & regulatory content.\n\n### `/metrics`\n\n```bash\ncurl \\\n -H \"Authorization: Bearer eyJhbGciOi…\" \\\n -H \"Content-Type: application/json\" \\\n -X POST \\\n -d '{ \"where\": { \"entities\": { \"id\": { \"eq\": \"11cab8df-4be1-470f-8f49-8f7f0863ec95\" } } },\n \"aggregations\": { \"group-by\": [\"published-at\", \"country\"], \"metrics\": [\"document-count\"] } }' \\\n https://api.signal-ai.com/metrics\n```\n\n## Affinity\n\nThe Affinity API allows users to discover connections between entities (e.g.\ncompanies) and topics, understand their proximity, and how it develops over\ntime, providing them with actionable intelligence about reputational risks and\ncommunication opportunities. It is powered by the Signal AI Knowledge Graph,\nwhich is generated by analyzing millions of documents every day.\n\n```bash\ncurl \\\n -H \"Authorization: Bearer eyJhbGciOi…\" \\\n -H \"Content-Type: application/json\" \\\n -X POST \\\n -d '{ \"relationship\": { \"type\": \"proximity\", \"date\": { \"start\": \"2022-01\", \"end\": \"2022-01\" }, \"interval\": \"month\", \"limit-per-interval\": 10 },\n \"source-concept\": {\"id\": \"11cab8df-4be1-470f-8f49-8f7f0863ec95\"},\n \"target-concepts\": { \"types\": [\"topic\"] } }' \\\n https://api.signal-ai.com/affinity\n```\n\n## Events\n\nThe Events API enables monitoring of major news events, allowing users to easily identify changes that could impact them or their business. By leveraging the 15-month archive, users can easily get up to speed on the recent developments involving specific companies, industries or topics.\n\n```bash\ncurl \\\n-H 'Authorization: Bearer eyJhbGc...' \\\n-H 'Content-Type: application/json' \\\n-X POST \\\n-d '{\n \"where\": {\n \"date\": {\n \"gte\": \"2022-05-01\",\n \"lte\": \"2022-05-30\"\n },\n \"entities\": {\n \"id\": {\"any\": [\"aee5dfa5-cf7e-4bcd-80c3-79b0125effc8\"]}\n }\n },\n \"size\": 50\n}' \\\nhttps://api.signal-ai.com/events\n```\n\n# Pagination\n\nSome of our endpoints such as `/search` and `/entities` limit the number of results returned in the response. Often there is a `size` parameter that controls how many results should be returned per page. To get additional results you will need to use pagination.\n\nEndpoints that have pagination will include a `next-cursor` field in the response. This can be used to fetch additional results by issuing further requests with the same query and specifying a `from-cursor` parameter. The value of `next-cursor` from the last response should be used to set the `from-cursor` parameter. For `GET` requests this will need to be specified in the query parameter. For `POST` requests this will need to be specified in the request body.\n\nThe absence of `next-cursor` in the response indicates that you have consumed all results matching the query.\n\n# Rate Limiting\n\nWe put limits on all API requests to protect our system from receiving more requests than it can handle, and to ensure an equitable distribution of the system resources across API clients.\nThe following API rate limits apply on a per-endpoint, per-Client ID basis:\n\n| Endpoint | requests/second | requests/minute |\n| ---------------- | --------------- | --------------- |\n| Content search | 2 | 30 |\n| Content metrics | 2 | 15 |\n| Concept affinity | 2 | 30 |\n| All others | 5 | 60 |\n\n# Error responses\n\n### 400 – Bad request\n\nThe request is invalid. This could be due to invalid parameters or invalid\nvalues. The error response will contain a top level field called `errors`\nlisting the errors. Each error is reported as a tuple:\n\n- the first element indicates which element is invalid, potentially providing a\n path to the incorrect field in the form `#/{type}/path/to/error` with `{type}`\n one of:\n - `query-params` for errors in URL parameters (or query string parameters)\n - `path-params` for errors in the URL (usually invalid resource ID)\n - `body` for errors in the body (for `POST` requests)\n- the second element contains an indication about the error\n\nExample of an error message:\n\n```json\n{\n \"errors\": [\n [\"#/query-params/sizee\", \"Invalid parameter\"],\n [\"#/path-params/id\", \"String does not match format \\\"uuid\\\"\"],\n [\n \"#/body/relationship/date/start\",\n \"must not be older than 15 months ago (2000-01)\"\n ]\n ]\n}\n```\n\n### 401 – Unauthorized\n\nIncorrect credentials, refer to the [Authorization](#section/Authorization)\nsection for more information.\n\n### 404 – Not found\n\nInvalid endpoint or unknown resource. For \"GET\" requests in particular (e.g.\n`GET /entities/{id}`) the body of the response will hold the invalid field.\n\n### 429 – Too many requests\n\nThe server received too many requests in the last second or minute. The [rate\nlimiting](#section/Rate-Limiting) section lists the limits for each endpoints.\n\n### 500 – Internal server error\n\nThe server encountered a problem while processing the request and failed\nunexpectedly. These errors are actively monitored and are automatically reported\nto our team so they can be investigated and fixed.\n\n### 502/503/504 – Gateway error / service unavailable\n\nThese error responses mean that the server either returned an invalid response\nor could not respond in time. For example, this could be due to unexpected high\nload on the server. It is usually safe to retry the request after some time.\n\n# Dates & Time Zones\n\nThe time zone that dictates the publication date is UTC. To be more precise, dates should respect the ISO 8601 format, where “Z” indicates UTC+0.\n\n# Changelog\n\n## v1.4 - 04/04/2023\n\n- Events GA\n - Added support for pagination\n - Added `/events/{hash}` endpoint\n\n## v1.3 - 28/07/2022\n\n- New Events capability\n - Added the new `events` endpoint for monitoring major news events\n - Enabled story-level metrics in the `metrics` endpoint to support volume and sentiment analysis of events\n\n## v1.2 - 08/06/2022\n\n- Improved Search capability\n - Added support for `story-id` as a search query criterion\n - Added support for `source.region` and `source.subregion` as search query criteria\n\n## v1.1 - 17/02/2022\n\n- Improved Affinity capability\n\n - Added the new `affinity` endpoint for querying relationships between concepts\n - Deprecated the existing `affinity/entities` and `affinity/topics` endpoints\n - Improved the `proximity-score` and `sentiment-score` models for better explainability and precision\n\n New endpoint:\n\n - `POST /affinity`\n\n Deprecated endpoints:\n\n - `GET /affinity/entities`\n - `GET /affinity/topics`\n"
version: v1.3
servers:
- url: https://api.signal-ai.com
security:
- OAuth2:
- default
tags:
- name: Risk Events
paths:
/risk-events-search:
post:
operationId: risk-events-search
security:
- OAuth2:
- risk-events
tags:
- Risk Events
summary: Risk Events Search
description: 'With our risk events search you can find significant events that impact business risk, extracted from our dataset of global news.
Events are derived from news content and clustered on a daily basis. Each event instance is labelled according to the [Risk Event Definition][] it matched. It also includes information about the entities that instigated the event ("actors"), and those directly impacted ("targets").
### Search query criteria
Construct a query to find events of interest by specifying matching criteria. The matching criteria are expressed in a `where` clause of the request body (see below). This works in a similar way to [Content Search][], however there is a more limited set of criteria and `exclude` clauses are not supported.
The criteria available are:
- the entities that were involved in the event, either as actors or targets
- the event definitions
- a date range of when the event was first reported
The returned data will be paginated, with a maximum of 100 results per page depending on the requested `size` paramater. For more information see the [Pagination][] docs.
### Risk event metadata returned
- unique event ID
- the definition the event matched
- the date the event was first reported
- the date we first detected the event (normally the same as first reported)
- the entities who were the "actors" in the event i.e. those that instigated or caused the event
- the entities who were the "targets" of the event i.e. those who were directly impacted by the event
- a list of documents that mentioned the event - id, headline and link will be provided, additional metadata can be retrieved using the [Get Document][] endpoint
[Risk Event Definition]: #tag/Risk-Events/operation/risk-events-definitions
[Get Document]: #tag/Content-Search/operation/get-document
[Content Search]: #tag/Content-Search
[Pagination]: #section/Pagination
'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RiskEventSearchQuery'
responses:
'200':
description: Returns a list of events matching the query
content:
application/json:
schema:
$ref: '#/components/schemas/RiskEventSearchResponse'
/risk-events-definitions:
get:
operationId: risk-events-definitions
security:
- OAuth2:
- risk-events
tags:
- Risk Events
summary: Risk Event Definitions
description: 'Our Risk Event Definitions represent a specific classification that we apply to news to extract events. Each definition is intended to describe a specific kind of concrete event that might happen. The goal is to find objective evidence of actions happening in the world, and avoid general discussion and speculation.
Event definitions can be used for both filtering [Risk Events][] and computing [Risk Scores][].
[Risk Events]: #tag/Risk-Events/operation/risk-events-search
[Risk Scores]: #tag/Risk-Events/operation/risk-events-scores
'
responses:
'200':
description: Returns a list of available event definitions
content:
application/json:
schema:
$ref: '#/components/schemas/RiskEventDefinitionResponse'
/risk-events-scores:
post:
operationId: risk-events-scores
security:
- OAuth2:
- risk-events
tags:
- Risk Events
summary: Risk Events Scores
description: 'Our risk scoring methodology provides an indication of how exposed a company may be to a specific risk. It does this by looking at the frequency of particular types of events, and how prominent this type of event is in the news media.
### Scoring query criteria
Scoring is based on selecting events for a date range and a "cohort" of entities with a `where` clause, then applying scoring options with a `score-by` clause.
The `where` clause is a subset of what is available in [Risk Events Search][]. It requires entities and a date range. The entities that make up this cohort represent a benchmark for scoring against.
The `score-by` clause has two optional properties:
- the entities to score, which should be a subset of the entities that made up the cohort defined in the `where`
- the risk "pillars" which group different event definitions into arbitrary buckets
The default behaviour without either of these options is to return a score for every available [Risk Event Definition][]. This tells you the overall risk score for the cohort.
With the entities option set, a score is returned for every combination of Event Definition and the entities provided. This tells you the risk score for each entity.
With the pillars option set, rather than getting a score for each event definition you will get a score for that group of event definitions. This allows organising the event definitions into arbitrary buckets to support different kinds of risk framework. When combined with the entities option a score is returned for each combination of entity and pillar.
### Score data returned
The score data will include:
- a name for each data point, which is either the pillar name provided, or the event definition name if pillars were not used
- a list of the relevant event definitions, either from the pillar, or a list of one event definition if pillars were not used
- optionally an entity, if entities were provided
- the count of documents
- the count of event instances
- a number from 1 to 5 which represents the "likelihood" of the event based on previous frequency
- a number from 1 to 5 which represents the "impact" of the event based on media prominence both absolutely and relatively to the cohort
- the score, which is likelihood multiplied by impact, so always a number from 1 to 25
[Risk Events Search]: #tag/Risk-Events/operation/risk-events-search
[Risk Event Definition]: #tag/Risk-Events/operation/risk-events-definitions
'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RiskEventScoreQuery'
responses:
'200':
description: Returns a list of events matching the query
content:
application/json:
schema:
$ref: '#/components/schemas/RiskEventScoreResponse'
components:
schemas:
RiskEventSearchResponse:
properties:
events:
items:
$ref: '#/components/schemas/RiskEvent'
type: array
maxItems: 100
next-cursor:
type: string
description: Use the `next-cursor` field from a previous response to get the next page of results (see [Pagination](#section/Pagination))
required:
- events
type: object
additionalProperties: false
RiskScoreBy:
properties:
entity-ids:
type: array
items:
$ref: '#/components/schemas/ResourceId'
pillars:
type: array
items:
$ref: '#/components/schemas/RiskPillar'
type: object
additionalProperties: false
RiskEventScoreResponse:
type: object
required:
- scores
additionalProperties: false
properties:
scores:
type: array
items:
$ref: '#/components/schemas/RiskScore'
ResourceIds:
type: array
items:
$ref: '#/components/schemas/ResourceId'
RiskEventMatch:
type: object
additionalProperties: false
properties:
first-reported-at:
$ref: '#/components/schemas/DateRangeMatch'
entities:
$ref: '#/components/schemas/RiskEventEntitiesMatch'
event-definitions:
$ref: '#/components/schemas/RiskEventDefinitionsMatch'
RiskEventDocument:
type: object
required:
- id
- title
additionalProperties: false
properties:
id:
$ref: '#/components/schemas/ResourceId'
title:
type: string
signal-url:
type: string
DateRangeMatch:
type: object
properties:
gte:
$ref: '#/components/schemas/Date'
lte:
$ref: '#/components/schemas/Date'
additionalProperties: false
minProperties: 1
Entity:
type: object
required:
- id
- name
- type
properties:
id:
$ref: '#/components/schemas/ResourceId'
type:
$ref: '#/components/schemas/EntityType'
name:
type: string
RiskEventScoreQuery:
type: object
required:
- where
- score-by
additionalProperties: false
properties:
where:
$ref: '#/components/schemas/RiskScoreMatch'
score-by:
$ref: '#/components/schemas/RiskScoreBy'
ResourceId:
type: string
format: uuid
pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
example: bcd2d868-ed38-4382-b94a-622a30fc3215
RiskScoreMatch:
type: object
additionalProperties: false
required:
- entities
- first-reported-at
properties:
first-reported-at:
$ref: '#/components/schemas/DateRangeMatch'
entities:
$ref: '#/components/schemas/RiskEventEntitiesMatch'
RiskEventDefinitionsMatch:
type: object
additionalProperties: false
required:
- id
properties:
id:
allOf:
- $ref: '#/components/schemas/AnyResourceIds'
- properties:
any:
type: array
minItems: 1
maxItems: 200
AnyResourceIds:
type: object
additionalProperties: false
required:
- any
properties:
any:
$ref: '#/components/schemas/ResourceIds'
Date:
type: string
format: date
description: "A date based on the IETF RFC 3339 format (e.g. `2023-01-01`).\n Note that a day is the span of time between 00:00:00 and 23:59:59 based on\n the UTC timezone. You may prefer using the `date-time` option to match days\n in a different timezone."
example: '2023-01-01'
RiskPillar:
properties:
name:
type: string
event-definition-ids:
type: array
items:
$ref: '#/components/schemas/ResourceId'
type: object
required:
- name
- event-definition-ids
additionalProperties: false
RiskScore:
properties:
name:
type: string
event-definitions:
type: array
items:
$ref: '#/components/schemas/RiskEventDefinition'
entity:
$ref: '#/components/schemas/Entity'
document-count:
type: number
event-count:
type: number
likelihood:
type: number
minimum: 1
maximum: 5
impact:
type: number
minimum: 1
maximum: 5
score:
type: number
minimum: 1
maximum: 25
required:
- name
- event-definitions
- document-count
- event-count
- likelihood
- impact
- score
type: object
additionalProperties: false
RiskEventEntitiesMatch:
type: object
additionalProperties: false
required:
- id
properties:
id:
allOf:
- $ref: '#/components/schemas/AnyResourceIds'
- properties:
any:
type: array
minItems: 1
maxItems: 20
EntityType:
type: string
enum:
- person
- organisation
- location
- substance
- disease
- product
- regulation
RiskEventDefinition:
type: object
required:
- id
- name
additionalProperties: false
properties:
id:
type: string
name:
type: string
description:
type: string
RiskEventSearchQuery:
type: object
required:
- where
additionalProperties: false
properties:
where:
$ref: '#/components/schemas/RiskEventMatch'
size:
type: number
minimum: 1
maximum: 100
default: 20
description: Set the number of events to return per page
from-cursor:
type: string
description: Use the `next-cursor` field from a previous response to get the next page of results (see [Pagination](#section/Pagination))
RiskEventDefinitionResponse:
type: object
required:
- event-definitions
additionalProperties: false
properties:
event-definitions:
type: array
items:
$ref: '#/components/schemas/RiskEventDefinition'
RiskEvent:
properties:
id:
$ref: '#/components/schemas/ResourceId'
description: ID of the event
title:
type: string
description: A short description of the event
event-definition:
$ref: '#/components/schemas/RiskEventDefinition'
first-reported:
$ref: '#/components/schemas/Date'
description: Date the event was first reported in the news
first-detected:
$ref: '#/components/schemas/Date'
description: Date the event was first detected by AIQ
actors:
items:
$ref: '#/components/schemas/Entity'
type: array
description: The entities that instigated the event
targets:
items:
$ref: '#/components/schemas/Entity'
type: array
description: The entities that were impacted by the event
documents:
items:
$ref: '#/components/schemas/RiskEventDocument'
type: array
description: 'The IDs and headlines from up to 3 articles mentioning the event.
Further details can be obtained from the Document API'
required:
- id
- title
- event-definition
- first-reported
- first-detected
- actors
- targets
- documents
type: object
additionalProperties: false
securitySchemes:
OAuth2:
type: oauth2
description: "To obtain the Bearer Token using the Client ID / Secret pair provided to you:\n\n```bash\ncurl -X POST \\\n -d 'grant_type=client_credentials' \\\n -d 'client_id=YOUR_CLIENT_ID' \\\n -d 'client_secret=YOUR_CLIENT_SECRET' \\\n https://api.signal-ai.com/auth/token\n```\n\nThis will return the following JSON response:\n\n```json\n{\n \"access_token\": \"eyJhbGciOi…\",\n \"expires_in\": 86400,\n …\n}\n```\n\nYou must send the `access_token` from this response in the Authorization header when making requests to other API endpoints:\n\n```bash\ncurl -H \"Authorization: Bearer eyJhbGciOi…\" \\\n https://api.signal-ai.com/…\n```\n\nAccess tokens will expire 24 hours from the time they were issued.\n"
flows:
clientCredentials:
tokenUrl: https://api.signal-ai.com/auth/token
scopes:
default: Access to discovery endpoints
search: Access to content search endpoint
metrics: Access to content metrics endpoint
affinity: Access to concept affinity endpoints
events: Access to events endpoint
risk-events: Access to risk events
x-tagGroups:
- name: Concept Discovery
tags:
- Publication sources
- Topics
- Entities
- Categories
- name: Search
tags:
- Content Search
- name: Metrics
tags:
- Content Metrics
- name: Affinity
x-displayName: Affinity
tags:
- Affinity
- name: Events
x-displayName: Events
tags:
- Events
- name: Risk (Alpha)
tags:
- Risk Events