I Built a News API Before I Had Users. Here's What I'm Learning.
The API went live on a Tuesday. I had no idea who would use it. I was building NewTqnia, a bilingual technology publication in English and Arabic, and the requirements kept expanding. Website, RSS, JSON API, embeddable
The API went live on a Tuesday. I had no idea who would use it.
I was building NewTqnia, a bilingual technology publication in English and Arabic, and the requirements kept expanding. Website, RSS, JSON API, embeddable widget, browser new-tab page, structured timelinesβeach one wanted the same content delivered differently.
That raised a question I still donβt have a clean answer to:
How do you support six delivery surfaces without building six disconnected products?
This is not a success story. Itβs a set of tradeoffs, some working, some questionable, and a few Iβm actively looking to undo.
The API: small on purpose
The first public version of the Daily Digest API does almost nothing.
curl "https://newtqnia.com/v1/news/today?locale=en&limit=5"
Thatβs it. today, latest, two query params, no API key. Sixty requests per minute, ETag support, sensible Cache-Control.
I could have shipped categories, tags, search, recommendations, and analytics endpoints on day one. But a large API with unstable contracts is just a private API that happens to have public documentation. I wanted the opposite: a small surface that would not embarrass me if someone actually built against it.
The awkward part? Developers canβt ask for endpoints they donβt know are possible. So βwait for demandβ is a safe strategy, but maybe not the right one. Iβm still figuring out where the line is between βprudently smallβ and βuselessly small.β
The widget problem: isolation is expensive
Some people just want headlines on their site without writing HTTP clients. So I built a script:
<script
async
src="https://newtqnia.com/news-widget.js"
data-count="5"
data-locale="en"
data-layout="cards"
data-orientation="horizontal"
data-theme="auto"
data-accent="#03c0f9"
data-order="latest"
data-show-image="true"
data-show-summary="true">
</script>
The widget builder generates this and shows a live preview.
Here is the part nobody warned me about: every isolation strategy moves complexity somewhere else.
- Iframe? Strong style isolation, but responsive sizing becomes a negotiation with the host page.
- Shadow DOM? Protects against CSS leaks, but theming and accessibility traversal get weird.
-
Plain script with scoped CSS? Familiar to embedders, but one
!importantrule on the host side and your layout collapses.
I went with the simple script and data-* attributes for now. Iβm not convinced itβs the long-term answer. If youβve shipped an embeddable widget, Iβd genuinely like to know: did you regret not using Web Components from the start?
Timelines are not articles
A news article describes a moment. A timeline has to explain how moments relate across years.
We publish timelines on things like the evolution of generative AI and the history of the Internet. Internally, these are not long articles. They are collections of events with fields like:
- Exact or approximate dates
- Event types and importance levels
- Primary and secondary sources
- Related links
- Event-specific media
- Bilingual captions and alt text
- Attribution and licensing
This makes the content reusable, but it also introduces editorial problems that code canβt solve. What do you do when two reputable sources disagree on a date? How do you mark a timeline as incomplete without undermining it? How do you represent a source that is credible but secondary?
Iβm also unsure about the public format. Custom JSON is easy to design. JSON-LD or an existing event vocabulary is harder but more interoperable. If you were consuming timeline data from an API, which would you prefer?
Bilingual support starts in the data model
Arabic is not βEnglish with different words.β It needs RTL layout, different typography, localized dates, and interface decisions that donβt always mirror the English side.
For structured content, the simplest model is explicit bilingual fields:
{
"title_en": "The Transformer rewrites the architecture of language AI",
"title_ar": "Ψ¨ΩΩΨ© Ψ§ΩΩ
ΨΩΩΨ§Ψͺ ΨͺΨΉΩΨ― Ψ΅ΩΨ§ΨΊΨ© ΩΩΨ―Ψ³Ψ© Ψ§ΩΨ°ΩΨ§Ψ‘ Ψ§ΩΨ§Ψ΅Ψ·ΩΨ§ΨΉΩ Ψ§ΩΩΨΊΩΩ"
}
This is easy to query and validate when you have exactly two languages. It becomes ugly at five or ten. A normalized translation table scales better, but it adds joins, fallback logic, and publishing-state complexity that I donβt need yet.
My current rule: reconsider the model before adding a third language, not before. Premature normalization is still premature optimization.
Media became a subsystem by accident
Once timelines started using event-specific images, storing a single URL wasnβt enough. A useful media record now needs:
- A stable internal ID
- Processing status and responsive variants
- Dimensions and file type
- Bilingual alt text and captions
- Original source, attribution, and licensing
- A relationship to either a timeline or an individual event
Images are processed into multiple sizes and formats. Events reference the internal asset, not an external URL. This keeps accessibility metadata attached to the thing it describes, and it avoids tying published pages to the uptime of some third-party host.
The part I canβt automate: whether the alt text is actually good. Validation checks for presence. It does not check for usefulness.
Distribution creates an attribution boundary
The more portable you make content, the less control you have over how itβs used.
Return only a title and URL, and the API is barely useful. Return full articles, and youβre inviting unattributed republication. Summaries are a middle ground, but even summaries get aggregated into faceless feeds.
Right now the API asks consumers to preserve article URLs and display visible attribution. That is a social contract, not a technical one. Iβve looked at signed content, stricter terms, metered access, and API keys. Each one raises the cost of legitimate experimentation.
If youβve designed a public content API, how did you decide how much to give away?
What I would do differently
- Start with the timeline data model earlier. Treating timelines as articles first meant a migration I could have avoided.
- Question the embed strategy harder. A script tag feels like the easy path until youβre debugging CSS specificity on a site you donβt control.
- Document the APIβs philosophy, not just its endpoints. Developers need to know why itβs small before they decide whether to build on it.
Questions Iβm stuck on
If you were reviewing this system, Iβd value your take on:
- Scope creep: At what point does a small REST API need categories, tags, or search?
- Push vs. pull: Would webhooks for new stories be useful, or does RSS already solve that?
-
Embed interfaces: Is a
data-*script still a good integration format in 2026? - Web Components: Do they actually solve the widget isolation problem, or just shift it?
- Timeline formats: How would you represent sourced historical events in a public API?
- Multilingual models: What is the least complicated model that still supports future expansion?
- Content boundaries: How much article content should a public news API return?
- Versioning: Which caching or contract mistakes should I fix before the API grows?
You can poke at the current implementation through the developer page, the widget builder, and the live timeline collection.
If one part of this system deserves to be simplified, replaced, or avoided entirely, which one is it?
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.