The previous projects each called one or two APIs and used the answers directly. Real features are often a chain: one call produces something, the next call consumes it, and the thing you show the user only exists at the end. The code that connects those calls is where most of the engineering lives. Which steps depend on which? What happens when the third step fails but the first two worked? How much did the whole run cost?
You will build a command-line pipeline that takes one or more URLs and, for each, extracts the page's text, summarises it, and scores its tone. It is the core of a dozen real tools: a reading-list digest, a competitor-news monitor, a review triage queue. The three APIs are almost incidental. The structure is the lesson.
The three steps and their contracts
Every link in a chain has a contract: what goes in, what comes out, and what the next step needs from it. Write those down before writing code, because the mismatches between them are where pipelines break.
Step 1: Website to Text (websitetotext). A POST with one required body field, url. It returns text (the page's body copy with the HTML stripped), plus title, description, date, language, publisher and url. The catalog lists it at 25 credits.
curl -X POST "https://api.apiverve.com/v1/websitetotext" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://en.wikipedia.org/wiki/QR_code"}'text is long: tens of thousands of characters for a full article. That matters for the next step.
When we ran that call, text was over 76,000 characters, and the extracted title and date were not the article's title and date. Metadata extraction is a best guess on pages that do not mark it up cleanly. The body text is the dependable output; treat the rest as optional and fall back to the URL when a title looks wrong or is missing.
Step 2: Text Summarizer (textsummarizer). A POST taking text (up to 5,000 characters) and an optional sentences count, default 3. It returns summary. The word counts and reduction percentage (originalWords, summaryWords, percentDifference) are premium. 20 credits.
curl -X POST "https://api.apiverve.com/v1/textsummarizer" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"A QR code is a two-dimensional matrix barcode invented in 1994 by Masahiro Hara of Denso Wave for labelling automobile parts. It is read by cameras and decoded using Reed-Solomon error correction. QR codes store data in four encoding modes: numeric, alphanumeric, byte and kanji. They are used to open web pages, add contacts, join wireless networks and make payments.","sentences":2}'The summary is extractive: it picks existing sentences rather than writing new ones.
The summary is extractive. It selects the sentences that carry the most weight and returns them as written, which means it never invents a claim the page did not make. It also means a sentence that starts with "It" may lose its subject. Worth knowing before you show it to users.
Step 3: Sentiment Analysis (sentimentanalysis). A POST taking text. It returns sentiment (a summed word score), comparative (that score divided by the number of words), sentimentText (a label), and the booleans isPositive and isNegative; normalizedScore is premium. 10 credits.
curl -X POST "https://api.apiverve.com/v1/sentimentanalysis" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"The package arrived late and the box was broken."}'Compare sentimentText with isNegative and the numeric score.
Run that one and look closely. When we called it, sentiment was -1, isNegative was true, and sentimentText was neutral. The label is a band over the score, and a mildly negative sentence falls inside the neutral band. Neither field is wrong; they answer different questions. If your feature sorts by tone, sort by comparative, which is comparable across texts of different lengths. Use the label only for display.
The cost of one URL through the whole chain is the sum of its steps: 25 + 20 + 10 = 55 credits. Calls that fail are not billed, so a run where step 3 errors costs 45. You will make the pipeline report that number itself, rather than leaving it as arithmetic you do once and forget.
The shape of the pipeline
Draw the dependencies before you write anything:
url ──► websitetotext ──► excerpt ─┬─► textsummarizer ──► summary
└─► sentimentanalysis ──► toneStep 1 must finish before anything else can start. Steps 2 and 3 both need the excerpt, but neither needs the other, so they run at the same time. That turns the pipeline's latency from the sum of three calls into the first call plus the slower of the other two.
The excerpt step in the middle is not an API. It is your code adapting one contract to the next: the summariser takes at most 5,000 characters, and a full article can be fifteen times that. You cut the text at a sentence boundary under the limit and strip noise like citation markers. Every real pipeline has glue like this, and it deserves the same care as the calls.
Failures follow the same picture. If step 1 fails there is nothing to analyse, so that URL fails as a whole. If step 2 or 3 fails, the other's result is still useful, so you return a partial result with a clear marker rather than throwing away work you paid for.
Step 1 succeeds, then the summarizer times out while sentiment analysis succeeds. What should the pipeline return for that URL?
Answer the check above to continue.
Harden it
Cache the expensive step. Step 1 is the most expensive call, and pages you have already read rarely change within the hour. Cache page.text by URL; a re-run then costs 30 credits per URL instead of 55, and cached URLs also skip the slowest call.
Consider a cheaper first step. URL to Markdown is listed at 10 credits rather than 25 and returns markdown and wordCount. Markdown carries heading and list syntax, so you would strip that in the excerpt step. It is a real trade-off worth measuring on your own pages, not a free swap.
Budget before you run. You know the maximum cost before any call: 55 credits times the number of URLs. Print it and ask for confirmation above a threshold. A pipeline that can spend a few thousand credits in one command should say so first.
Stop on an empty balance. When a step fails with "out of credits", every later call will fail the same way. Check for it in the runner and stop the pool rather than collecting two hundred identical errors.
Keep the ledger. Writing each run's ledger to a file gives you the latency and failure rate of every step over time, which is how you find out which link in a chain is the weak one.
For the full set of retryable and non-retryable errors, see error handling. For limits on parallel calls per plan, see making requests.
Ideas to extend it
- Feed in a feed. Put RSS to JSON in front of step 1 to turn a news feed into the URL list, and you have a daily digest.
- Add a language gate.
websitetotextreturnslanguage. Skip the summary and sentiment steps for languages your audience does not read, and save 30 credits per page. - Rank by tone. Sort a batch of product reviews by
comparativeto put the most negative at the top of a support queue. - More workflows. The recipes collection has more multi-API chains to take apart and rebuild.
That completes the five projects. You have built a signup gate, a weather widget, a currency converter, a QR check-in system and a multi-step pipeline, and each one taught a habit that carries over: decide what failure means, keep the key on the server, cache by what the answer depends on, and count what you spend. When you are ready to prove it, take the APV-100 certification exam.