{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"type":"markdown"},"seo":{"title":"Integrate Rev AI's Topic Extraction API with a Node.js Application","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"integrate-rev-ais-topic-extraction-api-with-a-nodejs-application","__idx":0},"children":["Integrate Rev AI's Topic Extraction API with a Node.js Application"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["By Vikram Vaswani, Developer Advocate - Jun 13, 2022"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"introduction","__idx":1},"children":["Introduction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://en.wikipedia.org/wiki/Topic_model"},"children":["Topic extraction"]}," attempts to detect the topics or subjects of a document. It is useful in a number of different scenarios, including"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Auto-generated agendas for meetings and phone calls"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Automated classification or keyword indexing for digital media libraries"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Automated tagging for Customer Service (CS) complaints or support tickets"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Rev AI offers a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/topic-extraction"},"children":["Topic Extraction API"]}," that identifies important keywords and corresponding topics in transcribed speech. For application developers, it provides a fast and accurate way to retrieve and rank the core subjects in a transcribed conversation and then take further actions based on this information."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial explains how to integrate the Rev AI Topic Extraction API into your Node.js application."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"assumptions","__idx":2},"children":["Assumptions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial assumes that:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You have a Rev AI account and access token. If not, ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://www.rev.ai/auth/signup"},"children":["sign up for a free account"]}," and ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/get-started#step-1-get-your-access-token"},"children":["generate an access token"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You have a properly-configured Node.js development environment with Node.js v16.x or v17.x. If not, ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://nodejs.org/en/download/"},"children":["download and install Node.js"]}," for your operating system."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You have a JSON transcript generated from the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/asynchronous"},"children":["Asynchronous Speech-to-Text API"]},". If not, use this ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://www.rev.ai/FTC_Sample_1_Transcript.json"},"children":["example JSON transcript"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-install-axios","__idx":3},"children":["Step 1: Install Axios"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Topic Extraction API is a REST API and, as such, you will need an HTTP client to interact with it. This tutorial uses ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://axios-http.com/"},"children":["Axios"]},", a popular Promise-based HTTP client for Node.js."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Begin by installing Axios into your application directory:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"npm install axios\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Within your application code, initialize Axios as below:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const axios = require('axios');\nconst token = '<REVAI_ACCESS_TOKEN>';\n\n// create a client\nconst http = axios.create({\n  baseURL: 'https://api.rev.ai/topic_extraction/v1/',\n  headers: {\n    'Authorization': `Bearer ${token}`,\n    'Content-Type': 'application/json'\n  }\n});\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here, the Axios HTTP client is initialized with the base endpoint for the Topic Extraction API, which is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.rev.ai/topic_extraction/v1/"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every request to the API must be in JSON format and must include an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}," header containing your API access token. The code shown above also attaches these required headers to the client."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2-submit-transcript-for-topic-extraction","__idx":4},"children":["Step 2: Submit transcript for topic extraction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To perform topic extraction on a transcript, you must begin by submitting an HTTP POST request containing the transcript content, in either plaintext or JSON, to the API endpoint at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.rev.ai/topic_extraction/v1/jobs"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The code listings below perform this operation using the HTTP client initialized in ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#step-1-install-axios"},"children":["Step 1"]},", for both plaintext and JSON transcripts:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const submitTopicExtractionJobText = async (textData) => {\n  return await http.post(`jobs`,\n    JSON.stringify({\n      text: textData\n    }))\n    .then(response => response.data)\n    .catch(console.error);\n};\n\nconst submitTopicExtractionJobJson = async (jsonData) => {\n  return await http.post(`jobs`,\n    JSON.stringify({\n      json: jsonData\n    }))\n    .then(response => response.data)\n    .catch(console.error);\n};\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you were to inspect the return value of the functions shown above, here is an example of what you would see:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  id: 'W6DvsEjteqwV',\n  created_on: '2022-04-13T09:16:07.033Z',\n  status: 'in_progress',\n  type: 'topic_extraction'\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The API response contains a job identifier (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]}," field). This job identifier will be required to check the job status and obtain the job result."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/topic-extraction"},"children":["Learn more about submitting a topic extraction job in the API reference guide"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-3-check-job-status","__idx":5},"children":["Step 3: Check job status"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Topic extraction jobs usually complete within 10-20 seconds. To check the status of the job, you must submit an HTTP GET request to the API endpoint at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.rev.ai/topic_extraction/v1/jobs/<ID>"]},", where ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<ID>"]}," is a placeholder for the job identifier."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The code listing below demonstrates this operation:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const getTopicExtractionJobStatus = async (jobId) => {\n  return await http.get(`jobs/${jobId}`)\n    .then(response => response.data)\n    .catch(console.error);\n};\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here is an example of the API response to the previous request after the job has completed:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  id: 'W6DvsEjteqwV',\n  created_on: '2022-04-13T09:16:07.033Z',\n  completed_on: '2022-04-13T09:16:07.17Z',\n  word_count: 13,\n  status: 'completed',\n  type: 'topic_extraction'\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/topic-extraction"},"children":["Learn more about retrieving the status of a topic extraction job in the API reference guide"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-4-retrieve-topic-extraction-report","__idx":6},"children":["Step 4: Retrieve topic extraction report"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once the topic extraction job's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]}," changes to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["completed"]},", you can retrieve the results by submitting an HTTP GET request to the API endpoint at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.rev.ai/topic_extraction/v1/jobs/<ID>/result"]},", where ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<ID>"]}," is a placeholder for the job identifier."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The code listing below demonstrates this operation:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const getTopicExtractionJobResult = async (jobId) => {\n  return await http.get(`jobs/${jobId}/result`,\n    { headers: { 'Accept': 'application/vnd.rev.topic.v1.0+json' } })\n    .then(response => response.data)\n    .catch(console.error);\n};\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the job status is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["completed"]},", the return value of the above function is a JSON-encoded response containing a sentence-wise topic extraction report. If the job status is not ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["completed"]},", the function will return an error instead."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here is an example of the topic extraction report returned from a completed job:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"topics\": [\n    {\n      \"topic_name\": \"incredible team\",\n      \"score\": 0.9,\n      \"informants\": [\n        {\n          \"content\": \"We have 17 folks and, uh, I think we have an incredible team and I just want to talk about some things that we've done that I think have helped us get there.\",\n          \"ts\": 71.4,\n          \"end_ts\": 78.39\n        },\n        {\n          \"content\": \"Um, it's sort of the overall thesis for this one.\",\n          \"ts\": 78.96,\n          \"end_ts\": 81.51\n        },\n        {\n          \"content\": \"One thing that's worth keeping in mind is that recruiting is a lot of work.\",\n          \"ts\": 81.51,\n          \"end_ts\": 84\n        },\n        {\n          \"content\": \"Some people think that you can raise money and spend a few weeks building your team and then move on to more\",\n          \"ts\": 84.21,\n          \"end_ts\": 88.47\n        }\n      ]\n    },\n    {\n      ...\n    }\n  ]\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["It’s also possible to filter the result set to return only topics which score above a certain value by adding a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/topic-extraction"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["threshold"]}," query parameter"]}," to the request."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/topic-extraction"},"children":["Learn more about obtaining a topic extraction report in the API reference guide"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-5-create-and-test-a-simple-application","__idx":7},"children":["Step 5: Create and test a simple application"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Using the code samples shown previously, it's possible to create a simple application that accepts a JSON transcript and returns a list of topics detected in it, as shown below:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const main = async (jsonData) => {\n  const job = await submitTopicExtractionJobJson(jsonData);\n  console.log(`Job submitted with id: ${job.id}`);\n\n  await new Promise((resolve, reject) => {\n    const interval = setInterval(() => {\n      getTopicExtractionJobStatus(job.id)\n        .then(r => {\n          console.log(`Job status: ${r.status}`);\n          if (r.status !== 'in_progress') {\n            clearInterval(interval);\n            resolve(r);\n          }\n        })\n        .catch(e => {\n          clearInterval(interval);\n          reject(e);\n        });\n    }, 15000);\n  });\n\n  const jobResult = await getTopicExtractionJobResult(job.id);\n  console.log(jobResult);\n};\n\n// extract topics from example Rev AI JSON transcript\nhttp.get('https://www.rev.ai/FTC_Sample_1_Transcript.json')\n  .then(response => main(response.data));\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This example application begins by fetching Rev AI's example JSON transcript and passing it to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["main()"]}," function as input to be analyzed. The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["main()"]}," function submits this data to the Topic Extraction API using the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["submitTopicExtractionJobJson()"]}," method. It then uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["setInterval()"]}," to repeatedly poll the API every 15 seconds to obtain the status of the job. Once the job status is no longer ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["in_progress"]},", it uses the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["getTopicExtractionJobResult()"]}," method to retrieve the job result and prints it to the console."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here is an example of the output returned by the code above:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"Job submitted with id: xgKIzeODYYba\nJob status: completed\n{\n  topics: [\n    { topic_name: 'quick overview', score: 0.9, informants: [Array] },\n    { topic_name: 'concert tickets', score: 0.9, informants: [Array] },\n    { topic_name: 'dividends', score: 0.9, informants: [Array] },\n    { topic_name: 'quick background', score: 0.6, informants: [Array] }\n  ]\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The code listing above polls the API repeatedly to check the status of the topic extraction job. This is presented only for illustrative purposes and is ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["strongly recommended against"]}," in production scenarios. For production scenarios, use ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/topic-extraction/webhooks"},"children":["webhooks"]}," to asynchronously receive notifications once the topic extraction job completes."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"next-steps","__idx":8},"children":["Next steps"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Learn more about the topics discussed in this tutorial by visiting the following links:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Documentation: ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/topic-extraction"},"children":["Topic Extraction API reference"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Documentation: ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/topic-extraction/webhooks"},"children":["Topic Extraction API webhooks"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Tutorial: ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/api/topic-extraction/get-started"},"children":["Get Started with Topic Extraction"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Tutorial: ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/resources/tutorials/get-started-api-webhooks"},"children":["Get Started with Rev AI Webhooks"]}]}]}]},"headings":[{"value":"Integrate Rev AI's Topic Extraction API with a Node.js Application","id":"integrate-rev-ais-topic-extraction-api-with-a-nodejs-application","depth":1},{"value":"Introduction","id":"introduction","depth":2},{"value":"Assumptions","id":"assumptions","depth":2},{"value":"Step 1: Install Axios","id":"step-1-install-axios","depth":2},{"value":"Step 2: Submit transcript for topic extraction","id":"step-2-submit-transcript-for-topic-extraction","depth":2},{"value":"Step 3: Check job status","id":"step-3-check-job-status","depth":2},{"value":"Step 4: Retrieve topic extraction report","id":"step-4-retrieve-topic-extraction-report","depth":2},{"value":"Step 5: Create and test a simple application","id":"step-5-create-and-test-a-simple-application","depth":2},{"value":"Next steps","id":"next-steps","depth":2}],"frontmatter":{"title":"Integrate Rev AI's Topic Extraction API with a Node.js Application","date":"2022-06-13T00:00:00.000Z","byline":"Vikram Vaswani, Developer Advocate","disableLastModified":false,"toc":{"enable":true},"seo":{"title":"Integrate Rev AI's Topic Extraction API with a Node.js Application"}},"lastModified":"2026-02-24T14:47:49.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/resources/tutorials/integrate-topic-extraction-api-nodejs","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}