NewsSourceItem news.source-item@1
Generated at from
openvibe-contracts v0.53.0 and
openvibe-sdk v0.11.0.
- Version
- 1.0.0
- Owner
- news
- Visibility
- first-party
- Status
- active
- Compatibility
- backward
- Schema
https://openvibe.network/contracts/news/source-item.v1.json
news.source-item@1: one source item as OpenVibe.News shows it to editors (server/http/api.js itemDto): the normalised OpenVibe.Sources item — headline, URL, outlet, authors, the date the source states and a licensed short summary, never a body — with its dedupe outcome, cluster and the stored explanation of its membership, and its upstream state.
Fields
| Field | Type | Required | Description | Constraints |
|---|---|---|---|---|
id | string | yes |
| |
sources_item | common.entity-ref | yes | The OpenVibe.Sources item and the revision these fields came from. | |
source_key | string | yes | ||
headline | string | yes | ||
url | string | null | yes | ||
outlet | string | yes | ||
authors | array of string | yes | ||
published_at | string | null | yes | As the source states it; null when it does not. | |
summary | string | null | yes | A short summary, stored only when the source's terms allow it. | |
summary_basis | string | null | yes | Why a summary is (not) stored. | |
license_note | string | null | yes | ||
terms_note | string | null | yes | ||
status | enum | yes |
| |
duplicate_of | string | null | yes | ||
dedupe | object | null | yes | { rule, detail } when the item is a duplicate. | |
cluster_id | string | null | yes | ||
cluster_reason | object | null | yes | Why the item is in its cluster: { rule (shared_terms, new_cluster, duplicate_of, merged, split, …), shared_entities, shared_terms, score, … }. | |
retrieved_at | string | null | yes | ||
first_seen_at | string | yes |
| |
upstream_updated_at | string | null | yes |
| |
removed | object | null | yes | Set once the source removed the item upstream. |
Examples
From the contract's own test fixtures: valid ones validate, rejected ones must fail.
Valid: item
{
"id": "nsi_01JAB2Z7Y6X5W4V3T2S1R0QPNM",
"sources_item": {
"service": "sources",
"type": "item",
"id": "itm_01JAB2Y8K9M1N2P3Q4R5S6T7VW",
"revision": 1
},
"source_key": "harbour-gazette",
"headline": "Harbour bridge closes for inspection after cracks found",
"url": "https://harbourgazette.example/bridge-closure",
"outlet": "Harbour Gazette",
"authors": [
"M. Okafor"
],
"published_at": "2026-09-24T07:30:00+01:00",
"summary": null,
"summary_basis": "terms do not allow a stored summary",
"license_note": null,
"terms_note": "Headline and link only",
"status": "active",
"duplicate_of": null,
"dedupe": null,
"cluster_id": "clu_01JAB2X3C4D5E6F7G8H9J0KMNP",
"cluster_reason": {
"rule": "new_cluster",
"cluster": "clu_01JAB2X3C4D5E6F7G8H9J0KMNP",
"terms": [
"bridge",
"harbour",
"inspection"
],
"entities": [
"Harbour Bridge"
]
},
"retrieved_at": "2026-09-24T08:15:00.000Z",
"first_seen_at": "2026-09-24T08:15:00.000Z",
"upstream_updated_at": null,
"removed": null
}Rejected: bad-status
{
"id": "nsi_01JAB2Z7Y6X5W4V3T2S1R0QPNM",
"sources_item": {
"service": "sources",
"type": "item",
"id": "itm_01JAB2Y8K9M1N2P3Q4R5S6T7VW",
"revision": 1
},
"source_key": "harbour-gazette",
"headline": "Harbour bridge closes for inspection after cracks found",
"url": "https://harbourgazette.example/bridge-closure",
"outlet": "Harbour Gazette",
"authors": [
"M. Okafor"
],
"published_at": "2026-09-24T07:30:00+01:00",
"summary": null,
"summary_basis": "terms do not allow a stored summary",
"license_note": null,
"terms_note": "Headline and link only",
"status": "hidden",
"duplicate_of": null,
"dedupe": null,
"cluster_id": "clu_01JAB2X3C4D5E6F7G8H9J0KMNP",
"cluster_reason": {
"rule": "new_cluster",
"cluster": "clu_01JAB2X3C4D5E6F7G8H9J0KMNP",
"terms": [
"bridge",
"harbour",
"inspection"
],
"entities": [
"Harbour Bridge"
]
},
"retrieved_at": "2026-09-24T08:15:00.000Z",
"first_seen_at": "2026-09-24T08:15:00.000Z",
"upstream_updated_at": null,
"removed": null
}Validate
const contracts = require('openvibe-contracts');
contracts.validate('news.source-item@1', value); // { valid, errors: [{ path, message }] }