- SECTIONS
The FactSet Conversational API allows clients to integrate core FactSet Mercury capabilities in chatbot experiences.
The Conversational API is powered by FactSet Mercury, FactSet's Generative Artificial Intelligence (GenAI) large language model. The Conversational API provides a variety of content and capabilities, including FactSet’s Federation layer (FactSet’s core GenAI-based technology), as well as more specific content and functionality tailored for financial services workflows.
The Conversational API provides answers to hundreds of natural language search queries and allows you to easily ask questions related to companies and markets research.
Some example supported prompts:
- Nintendo's highest closing stock price over the last 3 months
- Has Yelp issued any guidance?
- What are the key trends impacting costs for DaVita?
For Information on Access to and Content Available via the Conversational API
Please see the Conversational API Online Assistant Page. Here you can find instructions on how to set up access to the Conversational API, and the full list of content available.
Conversational API Consumer Workflow
The Conversational API is an asynchronous API that utilizes status polling to inform the consumer when a query response is complete. Please see the technical OpenAPI documentation below for specific information regarding consuming the API programmatically.
At a high level, the API consumer workflow is as follows:
- Send a natural language query to the
/query
endpoint and start the response generation process. - Poll the status of the response generation process using the
/status
endpoint. - Once the status indicates a ready response, retrieve it using the
/result
endpoint.
- If your response contains a file ID, such as for an Excel chart or a FactSet ActiveGraph, retrieve it using the file ID at the
/download/file
endpoint. - To provide feedback on your response and help the Conversational API better serve you content, we encourage you to use the
/feedback
endpoint.
Current Limitations
- "Natural language" in this documentation refers to modern conversational English. Support for other languages is currently unavailable.
- The Conversational API is currently limited to accept 10 natural language queries per minute and 200 per hour for an individual consumer. If you anticipate your needs to be greater than these limits, please reach out to FactSet Support.
FAQ
- How can I receive updates on changes to the Conversational API? - Please subscribe to our FactSet Notify by clicking "Subscribe to notifications" in the upper right above the API overview. You will receive email updates when any updates occur to the API.
- Why am I receiving a 403 error with a valid API key? - Please ensure that your current public IP is within the IP range allocated to the API key you are using to authenticate API requests. You can update your API key's allowable IP range via the FactSet Developer Portal API Authentication page. If this does not resolve the issue, please reach out to FactSet Support to ensure you are appropriately authorized to access the Conversational API.
// This code snippet demonstrates using our JavaScript SDK to utilize basic features of the FactSet Conversational API.
// A general workflow overview:
// 1. Import required packages
// 2. Enter your authorization credentials (OAuth or API Key credentials, generated via the developer portal here: https://developer.factset.com/api-authentication )
// 3. Initialize the SDK modules
// 4. Define helper functions to interact with the Conversational API
// 5. Run queries to ask for data from the Conversational API
// 6. (Optional) Download files generated by the Conversational API, and provide feedback on the responses
import {ApiClient, ChatApi, DownloadApi, FeedbackApi} from '@factset/sdk-conversationalapipoweredbyfactsetmercury';
// If using OAuth, import the following as well
import {ConfidentialClient} from '@factset/sdk-utils';
/*
Setup for authentication
Replace the following placeholders with your own credentials:
*/
// Basic authentication: FactSetApiKey
// See https://developer.factset.com/learn/authentication-api-key for information how to create an API key
const USERNAME = 'YOUR_USERNAME';
const SERIAL = 'YOUR_SERIAL';
const API_KEY = 'YOUR_API_KEY';
// OAuth 2.0 authentication - Client Credentials only
// We do not recommend using OAuth 2.0 when using the Enterprise SDK, as the Client Credentials flow does not respect individual user entitlements.
// Please see https://github.com/factset/oauth2-guidelines?tab=readme-ov-file#authorization-code-flow-1
// for details on implementing the OAuth 2.0 Authorization Code flow, which respects individual user entitlements
// Use the following code snippet to authenticate using OAuth 2.0
// const OAUTH_CONFIG = '/path/to/app-config.json';
class ConversationalAPIInterface {
#apiClient;
#chatApi;
#downloadApi;
#feedbackApi;
constructor() {
this.#apiClient = null;
this.#chatApi = null;
this.#downloadApi = null;
this.#feedbackApi = null;
this.maxPollCount = Infinity;
this.pollInterval = 1000;
}
// Set parameters for polling the Conversational API
setPollingParams(pollInterval, maxPollCount = Infinity) {
this.pollInterval = pollInterval;
this.maxPollCount = maxPollCount;
}
// Authenticate with the Conversational API
login() {
if (this.#apiClient) {
return;
}
// Basic authentication: FactSetApiKey
// See https://developer.factset.com/learn/authentication-api-key for information how to create an API key
const username = USERNAME + '-' + SERIAL;
const apiKey = API_KEY;
const apiClient = ApiClient.instance;
const factSetApiKey = apiClient.authentications['FactSetApiKey'];
factSetApiKey.username = username;
factSetApiKey.password = apiKey;
// OAuth 2.0 authentication - Client Credentials only
// We do not recommend using OAuth 2.0 when using the Enterprise SDK, as the Client Credentials flow does not respect individual user entitlements.
// Please see https://github.com/factset/oauth2-guidelines?tab=readme-ov-file#authorization-code-flow-1
// for details on implementing the OAuth 2.0 Authorization Code flow, which respects individual user entitlements.
// See https://developer.factset.com/learn/authentication-oauth2 for information on how to create the app-config.json file.
// See https://github.com/FactSet/enterprise-sdk-utils-typescript#authentication for more information on using the ConfidentialClient class.
// Use the following code snippet to authenticate using OAuth 2.0
// const apiClient = ApiClient.instance;
// apiClient.factsetOauth2Client = new ConfidentialClient(OAUTH_CONFIG);
this.#apiClient = apiClient;
this.#chatApi = new ChatApi(apiClient);
this.#downloadApi = new DownloadApi(apiClient);
this.#feedbackApi = new FeedbackApi(apiClient);
}
// Send a chat message to the Conversational API
sendQuery(query, chatId = '') {
try {
return this.#chatApi.sendQuery(
JSON.stringify({
data: {
query,
...(chatId && {chatId}),
},
})
);
} catch (error) {
console.error('Error in sendQuery: ', error.body);
return {};
}
}
// Retrieve the status of a chat response process
async getChatStatus(jobId) {
// Poll for the status at pollInterval for maxPollCount times
let pollCount = 0;
while (pollCount <= this.maxPollCount) {
try {
const stat = await this.#chatApi.getChatStatus({data: {jobId}});
const {status} = stat.data;
if (status === 'created') {
return stat;
}
} catch (error) {
console.error('Error in getChatStatus: ', error.body);
return false;
}
pollCount++;
await new Promise((resolve) =>
setTimeout(() => {
resolve(true);
}, this.pollInterval)
);
}
console.error('Error: Timeout fetching Conversational API Response');
return {};
}
// Retrieve the completed response for your query
getChatResult(jobId) {
try {
return this.#chatApi.getChatResult({data: {jobId}});
} catch (error) {
throw new Error('Error in getChatResult: ', error.body);
}
}
// Send feedback for the query response
sendFeedback(responseId, helpful, comment) {
try {
return this.#feedbackApi.sendFeedback(
JSON.stringify({
data: {
responseId,
helpful,
comment,
},
})
);
} catch (error) {
console.error('Error in sendFeedback: ', error.body);
return false;
}
}
// Download file based on response data from /result
// Note: the file is returned represented as an ArrayBuffer. You can convert it to a file object or write it to disk as needed.
downloadFile(fileId) {
try {
return this.#downloadApi.downloadFile({data: {fileId}});
} catch (error) {
console.error('Error in downloadFile: ', error.body);
return false;
}
}
// Summary method to ask a question and receive a response from the Conversational API
async askFactSetConversationalAPI(query, existingChatId = '') {
const {
data: {chatId, jobId},
} = await this.sendQuery(query, existingChatId);
const {
data: {status},
} = await this.getChatStatus(jobId);
if (status) {
const {
data: {responseId, data},
} = await this.getChatResult(jobId);
return {chatId, responseId, data};
}
return {chatId, error: true};
}
}
/**********************
* RUN SAMPLE QUERIES *
**********************/
export async function runSample() {
const conversationalAPI = new ConversationalAPIInterface();
conversationalAPI.login();
conversationalAPI.setPollingParams(1000);
// Ask a question to the Conversational API
const {chatId, data: firstMessageData} = await conversationalAPI.askFactSetConversationalAPI(
`What is Pepsi's enterprise value?`
);
console.log('Conversational API response: ', firstMessageData);
// Ask a follow-up question question to the Conversational API
const {data: secondMessageData} = await conversationalAPI.askFactSetConversationalAPI(
`What is their stock price?`,
chatId
);
console.log('Conversational API response: ', secondMessageData);
// Ask a question to the Conversational API to generate a chart
const {responseId, data: chartMessageData} = await conversationalAPI.askFactSetConversationalAPI(
`Generate a price chart for tesla`
);
console.log('Conversational API response: ', chartMessageData);
// Check for downloadable files in the response and download
// Please note that there may be multiple downloadable files in the response. This code snippet demonstrates downloading the first file.
chartMessageData?.forEach(async (messageItem) => {
if (messageItem.type === 'NextStep') {
const fileItem = messageItem.value.find((nextStep) => nextStep.action === 'Download');
if (fileItem) {
// Retrieve the chart file
const fileBuffer = await conversationalAPI.downloadFile(fileItem.fileId, fileItem.fileName);
/*
If consuming in a browser, you can generate a download link for the file using the following code
*/
if (fileBuffer) {
const file = new Blob(fileBuffer, {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
// Use the file directly or generate a download link (below) to download the file from the browser
const downloadLink = URL.createObjectURL(file);
}
/*
If consuming in a Node.js environment, you can write the file directly to disk using the following code
*/
// if (fileBuffer) {
// const fs = require('fs');
// fs.writeFile(fileItem.fileName, fileBuffer, (err) => {
// if (err) console.log(err);
// else {
// console.log('Chart downloaded to disk');
// }
// });
// }
}
}
});
// Provide feedback on the response
conversationalAPI.sendFeedback(responseId, true, 'Conversational API JavaScript Code Snippet');
}
1.0.5
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 1.0.5
- Date: 27 NOV 2024
Changes
- Minor documentation updates
1.0.4
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 1.0.4
- Date: 20 NOV 2024
Changes
- Update code snippets to use enterprise SDK
1.0.3
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 1.0.3
- Date: 08 NOV 2024
Bug Fixes
- Addressed issue where http links would not exist for certain OpenUrl NextStep actions
1.0.2
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 1.0.2
- Date: 31 OCT 2024
Changes
- Filtered boilerplate text from response
1.0.1
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 1.0.1
- Date: 23 OCT 2024
Changes
- Updated Api-Supported-Versions header value
1.0.0
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 1.0.0
- Date: 18 OCT 2024
Changes
Major release version
0.7.0
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.7.0
- Date: 15 OCT 2024
Functionality Additions
- Added new fields sourceData and sourceTitle in the Phrase schema
0.6.0
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.6.0
- Date: 19 SEP 2024
Functionality Additions
- Added support for inline citations within the response string and associated datatype
0.5.3
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.5.3
- Date: 11 SEP 2024
Bug Fixes
- Improved error handling and app stability
0.5.2
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.5.2
- Date: 04 SEP 2024
Bug Fixes
- Improved details for 4xx error responses
0.5.1
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.5.1
- Date: 28 AUG 2024
Bug Fixes
- Fixed bug that caused app crash when Stach to Excel Chart generation failed
0.5.0
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.5.0
- Date: 20 AUG 2024
Functionality Additions
- Deprecated OpenComponent, OpenExcelChart from NextSteps
- Deprecated FollowUpSuggestion
- Added Download in NextSteps to indicate all forthcoming file retrieval operations
0.4.0
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.4.0
- Date: 02 AUG 2024
Functionality Additions
- Added new data type SuggestedPrompts
0.3.0
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.3.0
- Date: 06 JUN 2024
Functionality Additions
- Added support for conversation chaining
- Tabular data now returned in STACH format
- Added follow-up question suggestions to query response data
- Added chart previews as adaptive cards in response data
0.2.0
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.2.0
- Date: 08 APR 2024
Functionality Additions
-
Added support for chart downloading
-
Added feedback endpoint
0.1.0
Summary
- Product: Conversational API Powered by FactSet Mercury
- Version: 0.1.0
- Date: 14 FEB 2024
Functionality Additions
- Initial release