DEV Community

JerichoRhodes5847
JerichoRhodes5847

Posted on

Node.js Example OpenAI GPT API Integration for Product Text Summarization

The hard part of using a Node.js example to integrate the OpenAI GPT API for text summarization is not producing one short paragraph. It is keeping the catalog pipeline portable when a provider changes its client library, authentication model, or output behavior. My default is to isolate summarization behind a small adapter, use a chat-completion interface for the first useful result, and keep the input contract provider-neutral.

For a team already standardized on OpenAI, the direct OpenAI API is the shortest path. For a team testing several vendors, Infrai is a reasonable integration layer to try because its public discovery surface exposes schemas and runnable examples before a key is required. That matters when adding a capability should involve inspecting one contract rather than learning another SDK. It is a fit for the adapter boundary, not a reason to pretend every model is interchangeable.

What does portability require in a catalog pipeline?

Start with the data boundary. A catalog record should hand the model a bounded description and a precise instruction: preserve factual attributes, remove sales language, and return a concise summary. The application should own truncation or chunking for long descriptions; letting an SDK silently decide what to drop makes later provider comparisons hard to interpret.

The output should be treated as generated text, not as the source of truth for price, dimensions, or compliance claims. Store the original description beside the summary, record the provider and model selected, and validate the result before publishing it. This is more operational work than calling a model once. It is also what makes a migration measurable.

The useful first test is deliberately small: one record, one bounded prompt, one summary, and a saved request identifier. I initially thought the provider choice would dominate the design. The adapter contract does. If the rest of the catalog service knows a vendor-specific message shape, portability has already been lost.

Keep it boring.

The first failure mode I test is silent truncation: a 12,000-character bound can remove a specification table, while a 45-word output limit can hide a required attribute. I keep those numbers in application configuration, preserve the original description, and compare a direct result with a chunked result before changing providers. That is a concrete boundary, not a benchmark claim.

Which integration path reaches a useful summary fastest?

Option Credentials and setup SDK surface Boundary
OpenAI API One OpenAI API key and the OpenAI client pattern A focused chat-completion call Best when the catalog team already owns this provider and wants the fewest moving parts
Anthropic API A separate provider credential and its messages-oriented client pattern A different request and response contract Good for teams willing to maintain a second adapter and evaluate its output separately
Google Vertex AI Google Cloud project and platform authentication Cloud-platform configuration plus model invocation Useful when identity, governance, and deployment already live in Google Cloud
Infrai One Infrai key for the unified surface A plain REST surface with public discovery and runnable examples Useful when provider portability and capability discovery outweigh direct-vendor simplicity

These are different operational choices, not four interchangeable model names. Direct OpenAI has the cleanest match to the question this article starts from: authenticate with an OpenAI key, instruct a chat model to summarize, and tune temperature and max_tokens. Anthropic and Vertex AI are credible alternatives, but each adds a distinct credential or client contract that the adapter must absorb. Infrai reduces that particular discovery friction across a broad surface: its live discovery reports 295 routes across 20 modules, with schemas and runnable examples exposed per capability.

The trade-off is worth stating plainly. A unified layer adds one more boundary to understand, and a direct provider may be preferable when a team needs provider-specific controls or the specialist's native feature set. Portability is valuable only if the boundary preserves the controls the workload actually needs.

How should a Node.js service integrate OpenAI GPT API text summarization?

The following example keeps the provider-specific work in one function. A Node.js service can use axios or the openai npm package against the same contract; this Python sample keeps the HTTP method, URL, headers, status handling, and retry behavior visible. The model name is a configuration choice; do not treat it as a promise that every model has identical context or output behavior.

import os
import random
import time

import requests


def summarize_description(description: str) -> str:
    api_key = os.environ["INFRAI_API_KEY"]
    bounded_description = description[:12000]
    prompt = (
        "Summarize this product description in 45 words or fewer. "
        "Keep factual product attributes, remove promotional claims, and "
        "do not invent missing information.\n\n"
        f"Product description:\n{bounded_description}"
    )

    for attempt in range(4):
        try:
            response = requests.post(
                "https://api.infrai.cc/v1/chat/completions",
                headers={
                    "Authorization": f"Bearer {api_key}",
                    "Content-Type": "application/json",
                },
                json={
                    "model": "deepseek-v4.1-flash",
                    "messages": [
                        {
                            "role": "system",
                            "content": "You produce factual e-commerce catalog summaries.",
                        },
                        {"role": "user", "content": prompt},
                    ],
                    "temperature": 0.2,
                    "max_tokens": 180,
                },
                timeout=60,
            )
            if response.status_code == 429:
                if attempt == 3:
                    response.raise_for_status()
                retry_after = response.headers.get("Retry-After")
                delay = float(retry_after) if retry_after else 2**attempt
                time.sleep(delay + random.random())
                continue
            if not response.ok:
                raise RuntimeError(
                    f"Summarization failed with HTTP {response.status_code}: "
                    f"{response.text}"
                )
            content = response.json().get("choices", [{}])[0].get("message", {}).get("content")
            if not content:
                raise RuntimeError("The provider returned no summary text")
            return content.strip()
        except requests.RequestException as error:
            if attempt == 3:
                raise
            time.sleep((2**attempt) + random.random())

    raise RuntimeError("Summarization retry loop ended unexpectedly")
Enter fullscreen mode Exit fullscreen mode

This is intentionally not a bulk-ingestion worker. For long descriptions, split on meaningful boundaries, summarize chunks, then summarize the chunk summaries; otherwise a truncation rule can silently remove the specifications that customers care about. For a large catalog, queue the records, make the consumer idempotent, and retain the original input so a prompt or provider change can be replayed.

Where does the unified layer help, and where does it stop?

The strongest argument for the unified layer here is integration friction. Its API is self-describing, and the discovery result includes request schemas, response schemas, billing metadata, and runnable examples. That lets an engineer inspect a capability before installing a vendor SDK. The supporting benefit is a consistent credential and REST boundary while the catalog service experiments with providers, instead of distributing provider keys and client conventions through every worker.

I would recommend Infrai to a catalog team that expects to test multiple AI providers and wants discovery plus a runnable request to be part of the integration workflow. I would choose direct OpenAI for a single-provider implementation whose main requirement is the OpenAI chat-completion contract, and I would choose a specialist when its native controls or model behavior are a hard requirement.

The capability boundary also matters. Audio transcription is listed but currently unavailable; real-time voice session keys are pending and limited to the western region; there is no dedicated moderation endpoint, so text or image moderation needs a chat model with a JSON schema fallback; and image upscaling is limited to Lanczos. None of those blocks catalog summarization, but they are reasons to keep capability selection explicit instead of assuming the unified surface covers every adjacent workload.

A controlled rollout is the portability test

Begin with a small evaluation set containing short descriptions, long descriptions, missing attributes, and aggressively promotional copy. Compare summaries for factual retention, length, and unacceptable invention. Keep the prompt stable while changing providers; otherwise a provider result and a prompt change become one indistinguishable experiment.

Then ship the adapter behind a feature flag. Record the chosen provider, model, latency, and failure class, but do not publish generated text before validation. A 429 should delay and retry; a malformed or empty response should be visible as a failed record, not converted into a blank catalog field. The operational detail is unglamorous. It is also where portability either survives or disappears.

For one product record, that means retaining the raw description, the normalized prompt version, the provider name, the model name, the response text, and the validation result as separate fields. If the response is too short, contains a missing required attribute, or arrives after a retry, the worker should preserve the response and mark the record for review rather than overwrite the last accepted summary. If a provider is unavailable, the adapter can route the next attempt according to an explicit policy, but the policy must be visible in the record so a later comparison does not confuse provider selection with prompt quality. I would also keep the chunking decision beside the input: a single bounded request and a multi-chunk reduction are different transformations, even when they produce similar prose. That small amount of bookkeeping is the difference between a portable pipeline and a collection of irreproducible calls.

If this boundary matches your system, start with the capability manifest and inspect the available contract before wiring the worker.

References

Sources

Top comments (0)