Stories
Read stories with their research, follow and repeat their enrichment, push them to your newsroom system, and manage their photos and dismissed items.
x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
limit?integerMaximum items per page (1–100, default 25)
1 <= value <= 10025cursor?stringOpaque cursor from a prior nextCursor
include?|array<string>Repeat for each sideload, each keyed by story id under included: contributingPublishers (the sources chip) and signals (the row signals: NRCS state, key claims, story checks, outputs). Omitted by default, so the ordinary list pays no extra query.
A page of stories, most recent activity (updatedAt) first
application/json- response
items*array<>pagination*sort*filters*facets?Value/count breakdown for each field requested via ?facets=. Present only when facets were requested.
included?curl -X GET 'https://api.nuvelics.com/api/tenant/v1/stories'{ "items": [ { "id": "string", "orgId": "string", "source": "pitch", "newsdeskId": "string", "pitchId": "string", "title": "string", "summary": "string", "whyItMatters": "string", "contentLanguage": "string", "enrichmentStatus": "pending", "enrichmentAttempts": 0, "lastEnrichmentError": "string", "origin": "string", "nrcsDropped": "archived", "enrichedContentSha": "string", "storyType": "PLANNED", "lifecyclePhase": "DEVELOPING", "phaseEnteredAt": "2019-08-24T14:15:22Z", "sequenceNumber": 0, "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z" } ], "pagination": { "nextCursor": "string" }, "sort": { "applied": "string", "default": "string", "available": [ "string" ] }, "filters": { "applied": { "property1": null, "property2": null }, "available": [ { "field": "string", "kind": "string", "facetable": true } ] }, "facets": { "property1": { "values": [ { "value": "string", "count": 0 } ], "capped": true }, "property2": { "values": [ { "value": "string", "count": 0 } ], "capped": true } }, "included": { "contributingPublishers": { "property1": { "publishers": [ { "publisherKey": "string", "name": "string", "iconUrl": "string" } ], "sourceCount": 0 }, "property2": { "publishers": [ { "publisherKey": "string", "name": "string", "iconUrl": "string" } ], "sourceCount": 0 } }, "signals": { "property1": { "nrcs": { "state": "string", "externalUpdatedAt": "2019-08-24T14:15:22Z", "hydrated": true }, "keyClaims": { "state": "confirmed", "counts": { "confirmed": 0, "unverified": 0, "contested": 0 } }, "checks": { "flagged": 0, "state": "current" }, "outputs": [ { "id": "string", "type": "web_article", "status": "pending", "needsAttention": true } ] }, "property2": { "nrcs": { "state": "string", "externalUpdatedAt": "2019-08-24T14:15:22Z", "hydrated": true }, "keyClaims": { "state": "confirmed", "counts": { "confirmed": 0, "unverified": 0, "contested": 0 } }, "checks": { "flagged": 0, "state": "current" }, "outputs": [ { "id": "string", "type": "web_article", "status": "pending", "needsAttention": true } ] } } }}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
bucket*string"day""month"groupBy?"newsdesk""newsdesk"The caller's own org's enrichment runs bucketed by day or month, optionally grouped by newsdesk
application/json- response
rows*array<>capped*booleancurl -X GET 'https://api.nuvelics.com/api/tenant/v1/stories/enrichment-summary?bucket=day'{ "rows": [ { "bucket": "string", "key": "string", "count": 0 } ], "capped": true}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$The story with its seven enrichment blocks
application/json- response
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$orgId*stringOwning organization identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$source?stringWhere the story came from: an approved pitch or the newsroom system (NRCS)
"pitch""pitch""nrcs"newsdeskId*stringOwning newsdesk; null for a story minted from the NRCS, which has no pitch
^[0-7][0-9A-HJKMNP-TV-Z]{25}$pitchId*stringMinting pitch; null for a story minted from the NRCS
^[0-7][0-9A-HJKMNP-TV-Z]{25}$title*stringStory title, inherited from the minting pitch or kept in sync from the NRCS record
summary*stringThe story's summary: the minting pitch's, read through at request time, or the NRCS story's own
whyItMatters*stringThe story's rationale: the minting pitch's, read through at request time, or the NRCS story's own
contentLanguage?stringLanguage code of the story's content; present only on an NRCS story (a pitch story's lives on its pitch)
enrichmentStatus*stringClaim-loop status of the enrichment worker
"pending""running""enriched""failed"enrichmentAttempts*integerTransient-failure retry count; enrichment_status lands failed once this hits the ceiling
0 <= valuelastEnrichmentError?stringFailure reason from the most recent enrichment run; present only when enrichmentStatus is failed and a run captured an error (absent for failures predating this field or terminal retry-ceiling failures with no captured run error)
origin?stringWhere the story came from: engine for a pitch the engine generated, manual for a pitch a person created, or the vendor of the NRCS record (for example saga) for a story minted from the NRCS. Derived on read; present on list and detail reads
nrcsDropped?stringWhy the newsroom system dropped this story, archived or deleted; null while it is live and always null for a pitch story. Present on list and detail reads. A dropped story refuses new and regenerated outputs and leaves the default list
"archived""deleted"nullenrichedContentSha?stringDigest of the NRCS text the story's enrichment was last computed from; null until an NRCS story is first enriched and always null for a pitch story. Present on a detail read. Compared with an NRCS record's contentSha to tell whether the enrichment is outdated
storyType*stringSOM story_type, stored verbatim
"PLANNED""ACTIVE""KILLED""SPIKED""ARCHIVED""ORPHAN"lifecyclePhase?stringSOM lifecycle_phase; present if and only if storyType is ACTIVE
"DEVELOPING""READY_TO_AIR""BREAKING""PUBLISHED"phaseEnteredAt?stringISO 8601 timestamp the story entered its current lifecycle phase
date-timesequenceNumber*integerMonotonic SOM sequence_number, bumped on every consumer-ordered mutation
0 <= valuecreatedAt*stringISO 8601 creation timestamp
date-timeupdatedAt*stringISO 8601 timestamp of the most recent update
date-timesources*array<>Both source origins: frozen originals plus research-discovered additional sources
meaning?5W1H meaning block; absent until the story has been enriched
factCheck?Overall fact-check assessment; absent until the story has been enriched
claims*array<>Key claims with fact-check status and cited sources; empty until enriched
entities*array<>Key entities; empty until enriched
timeline*array<>Chronologically ordered story events; empty until enriched
quotes*array<>Key quotes in rank order, dismissed ones included and flagged; empty until enriched, and for a story enriched before quotes existed
media*array<>Related media projected from the contributing articles; empty until enriched
ugcPosts*array<>Candidate eyewitness/UGC posts surfaced by the UGC search step, dismissed ones included and flagged; empty until enriched
mamAssets*array<>Photos and videos surfaced from the org's own MAM archive, dismissed ones included and flagged; empty until enriched, and empty for an org with no MAM connection
nrcsPushes*array<>NRCS connections this story has been pushed to; empty until pushed at least once
nrcsRecords?array<>The newsroom-system records behind this story, oldest first; present on GET /stories/{id}, empty for a pitch story never pushed
enrichmentPlan*The research plan computed for this story's latest completed enrichment run; null for a pre-enrichment story or one enriched before this field existed
enrichmentFreshness?||Where the story's enrichment stands (dropped, running, not_enriched, failed, outdated, no_sources, current); present on GET /stories/{id}
curl -X GET 'https://api.nuvelics.com/api/tenant/v1/stories/string'{ "id": "string", "orgId": "string", "source": "pitch", "newsdeskId": "string", "pitchId": "string", "title": "string", "summary": "string", "whyItMatters": "string", "contentLanguage": "string", "enrichmentStatus": "pending", "enrichmentAttempts": 0, "lastEnrichmentError": "string", "origin": "string", "nrcsDropped": "archived", "enrichedContentSha": "string", "storyType": "PLANNED", "lifecyclePhase": "DEVELOPING", "phaseEnteredAt": "2019-08-24T14:15:22Z", "sequenceNumber": 0, "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z", "sources": [ { "id": "string", "storyId": "string", "origin": "original", "articleId": "string", "url": "string", "title": "string", "publisher": "string", "publisherKey": "string", "snippet": "string", "excerpt": "string", "publishedAt": "2019-08-24T14:15:22Z", "fetched": true, "position": 0, "useAsMedia": true, "articleAcquiredVia": "datasource", "seedAddedAt": "2019-08-24T14:15:22Z", "iconUrl": "string", "recall": { "kind": "kill", "note": "string" } } ], "meaning": { "who": "string", "what": "string", "when": "string", "where": "string", "why": "string", "how": "string", "summary": "string", "confidence": 0 }, "factCheck": { "assessment": "confirmed", "summary": "string" }, "claims": [ { "claim": "string", "status": "confirmed", "note": "string", "sourceIds": [ "string" ], "assertions": [ { "sourceId": "string", "value": "string", "quote": "string", "fragmentMatches": true } ] } ], "entities": [ { "type": "person", "name": "string", "description": "string", "role": "string", "isPrimary": true } ], "timeline": [ { "headline": "string", "day": "2019-08-24", "occurredAt": "2019-08-24T14:15:22Z", "status": "confirmed", "sourceIds": [ "string" ] } ], "quotes": [ { "text": "string", "original": { "text": "string", "language": "string" }, "version": { "kind": "rendering", "text": "string", "sourceId": "string", "publisher": "string" }, "spokenLanguage": "string", "speaker": "string", "speakerRole": "string", "entity": "string", "isPrimarySpeaker": true, "context": "string", "saidOn": "2019-08-24", "kind": "spoken", "origin": "passage", "fragment": true, "soundbite": { "partUrl": "string", "posterUrl": "string", "startMs": 0, "endMs": 0 }, "sourceIds": [ "string" ], "ugcPostUrl": "string", "rank": 0, "dismissed": true, "dismissedVia": "quote" } ], "media": [ { "mediaType": "image", "assetUrl": "string", "posterUrl": "string", "caption": "string", "width": 0, "height": 0, "durationMs": 0, "credit": "string", "usageTerms": [ "string" ], "sourceArticleId": "string", "assetId": "string", "photoVendor": true, "dismissed": true, "dismissKey": "string" } ], "ugcPosts": [ { "source": "x", "postUrl": "string", "authorHandle": "string", "authorName": "string", "text": "string", "postedAt": "2019-08-24T14:15:22Z", "hasMedia": true, "mediaType": "string", "rank": 0, "possibleReuse": true, "possibleReuseNote": "string", "dismissed": true } ], "mamAssets": [ { "mamConfigId": "string", "itemId": "string", "itemType": "image", "title": "string", "description": "string", "mediaCreatedOn": "2019-08-24T14:15:22Z", "durationMs": 0, "whyRelevant": "string", "matchedFields": [ "string" ], "thumbnailUrl": "string", "thumbnailUrlExpiresAt": "2019-08-24T14:15:22Z", "rank": 0, "itemUrl": "string", "dismissed": true } ], "nrcsPushes": [ { "id": "string", "storyId": "string", "orgId": "string", "nrcsConfigId": "string", "vendor": "string", "externalId": "string", "pushedBy": "string", "pushedAt": "2019-08-24T14:15:22Z" } ], "nrcsRecords": [ { "id": "string", "vendor": "saga", "nrcsConfigId": "string", "externalId": "string", "entityType": "story", "state": "string", "assignedMemberIds": [ "string" ], "bodyText": "string", "externalUrl": "string", "contentSha": "string", "status": "active" } ], "enrichmentPlan": { "research": "full", "researchRule": "string", "ugcSearch": "searched", "ugcRule": "string", "researchOutcome": "query-gen-failed", "mamSearch": "searched", "mamRule": "string", "quotesRequested": true, "quotesFailed": true, "synthesisSections": [ "meaning" ] }, "enrichmentFreshness": { "state": "dropped" }}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$Every check applicable to the story, ordered by createdAt ascending (tie-broken by id), each carrying its current-content run and its last completed run; empty for a story with no NRCS record
application/json- response
contentSha*stringSHA-256 hex digest of the story's current processable content
items*array<>curl -X GET 'https://api.nuvelics.com/api/tenant/v1/stories/string/checks'{ "contentSha": "string", "items": [ { "id": "string", "name": "string", "outputKind": "findings", "currentRun": { "status": "running", "contentSha": "string", "checkVersion": 0, "completedAt": "2019-08-24T14:15:22Z", "result": { "verdict": "pass", "findings": [ { "severity": "inform", "title": "string", "detail": "string", "excerpt": "string" } ], "truncated": true } }, "lastCompletedRun": { "status": "running", "contentSha": "string", "checkVersion": 0, "completedAt": "2019-08-24T14:15:22Z", "result": { "verdict": "pass", "findings": [ { "severity": "inform", "title": "string", "detail": "string", "excerpt": "string" } ], "truncated": true } }, "awaitingRun": true } ]}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$itemId*stringThe vendor item id an ap-media: or afp: media reference the story shows
1 <= length <= 200The image behind an ap-media: or afp: reference of the story, fetched from the vendor with the datasource's own credential at view time
response?fileimage/*binarycurl -X GET 'https://api.nuvelics.com/api/tenant/v1/stories/string/media/string'"string"x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$cursor?stringOpaque cursor from a previous response's logsCursor -- returns only log rows after it, so a poll doesn't re-fetch lines it already has. Omit to get the earliest rows of the run, up to limit. See the response's logsTruncated for whether more rows exist past what's returned.
limit?integerMaximum log rows to return (server default when omitted, hard cap 1000). See the response's logsTruncated for whether more rows existed past this limit.
0 <= value <= 1000The latest enrichment run with its counters and log entries — the progress feed. run is null when the story has never been claimed yet.
application/json- response
run*The latest run, or null when the story has never been claimed
logs*array<>Log rows the latest run has accumulated, oldest first — up to limit rows since the request's cursor (or since the start of the run when it carried none). See logsTruncated for whether more rows exist past what's returned here.
logsCursor*stringOpaque cursor for the last log row returned; feed it back as ?cursor= on the next poll to fetch only newer rows. Null when there is no run yet to bind a cursor to.
logsTruncated*booleanTrue when more log rows existed past logs than the request's limit allowed — the next poll's cursor still picks up where this response left off, so a caller that never surfaces this flag just sees the rest arrive over subsequent polls.
curl -X GET 'https://api.nuvelics.com/api/tenant/v1/stories/string/enrichment'{ "run": { "id": "string", "storyId": "string", "attempt": 1, "status": "running", "model": "string", "newsdeskVersion": 0, "promptVersion": "string", "startedAt": "2019-08-24T14:15:22Z", "finishedAt": "2019-08-24T14:15:22Z", "error": "string", "queriesGenerated": 0, "sourcesSearched": 0, "sourcesFetched": 0, "entitiesCount": 0, "claimsCount": 0, "mediaProjected": 0 }, "logs": [ { "id": "string", "runId": "string", "occurredAt": "2019-08-24T14:15:22Z", "step": "string", "level": "info", "message": "string" } ], "logsCursor": "string", "logsTruncated": true}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$Re-enrichment requested; the story returns to pending
application/json- response
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$orgId*stringOwning organization identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$source?stringWhere the story came from: an approved pitch or the newsroom system (NRCS)
"pitch""pitch""nrcs"newsdeskId*stringOwning newsdesk; null for a story minted from the NRCS, which has no pitch
^[0-7][0-9A-HJKMNP-TV-Z]{25}$pitchId*stringMinting pitch; null for a story minted from the NRCS
^[0-7][0-9A-HJKMNP-TV-Z]{25}$title*stringStory title, inherited from the minting pitch or kept in sync from the NRCS record
summary?stringStory summary; present only on an NRCS story (a pitch story's lives on its pitch)
whyItMatters?stringWhy the story matters; present only on an NRCS story (a pitch story's lives on its pitch)
contentLanguage?stringLanguage code of the story's content; present only on an NRCS story (a pitch story's lives on its pitch)
enrichmentStatus*stringClaim-loop status of the enrichment worker
"pending""running""enriched""failed"enrichmentAttempts*integerTransient-failure retry count; enrichment_status lands failed once this hits the ceiling
0 <= valuelastEnrichmentError?stringFailure reason from the most recent enrichment run; present only when enrichmentStatus is failed and a run captured an error (absent for failures predating this field or terminal retry-ceiling failures with no captured run error)
origin?stringWhere the story came from: engine for a pitch the engine generated, manual for a pitch a person created, or the vendor of the NRCS record (for example saga) for a story minted from the NRCS. Derived on read; present on list and detail reads
nrcsDropped?stringWhy the newsroom system dropped this story, archived or deleted; null while it is live and always null for a pitch story. Present on list and detail reads. A dropped story refuses new and regenerated outputs and leaves the default list
"archived""deleted"nullenrichedContentSha?stringDigest of the NRCS text the story's enrichment was last computed from; null until an NRCS story is first enriched and always null for a pitch story. Present on a detail read. Compared with an NRCS record's contentSha to tell whether the enrichment is outdated
storyType*stringSOM story_type, stored verbatim
"PLANNED""ACTIVE""KILLED""SPIKED""ARCHIVED""ORPHAN"lifecyclePhase?stringSOM lifecycle_phase; present if and only if storyType is ACTIVE
"DEVELOPING""READY_TO_AIR""BREAKING""PUBLISHED"phaseEnteredAt?stringISO 8601 timestamp the story entered its current lifecycle phase
date-timesequenceNumber*integerMonotonic SOM sequence_number, bumped on every consumer-ordered mutation
0 <= valuecreatedAt*stringISO 8601 creation timestamp
date-timeupdatedAt*stringISO 8601 timestamp of the most recent update
date-timecurl -X POST 'https://api.nuvelics.com/api/tenant/v1/stories/string/reenrich'{ "id": "string", "orgId": "string", "source": "pitch", "newsdeskId": "string", "pitchId": "string", "title": "string", "summary": "string", "whyItMatters": "string", "contentLanguage": "string", "enrichmentStatus": "pending", "enrichmentAttempts": 0, "lastEnrichmentError": "string", "origin": "string", "nrcsDropped": "archived", "enrichedContentSha": "string", "storyType": "PLANNED", "lifecyclePhase": "DEVELOPING", "phaseEnteredAt": "2019-08-24T14:15:22Z", "sequenceNumber": 0, "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z"}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$application/json- body
nrcsConfigId*stringNRCS connection identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$Story pushed to the NRCS connection
application/json- response
id*stringStory-to-NRCS push record identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$storyId*stringPushed story identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$orgId*stringOwning organization identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$nrcsConfigId*stringTarget NRCS connection identifier; null once the connection has been deleted
^[0-7][0-9A-HJKMNP-TV-Z]{25}$vendor*stringNRCS vendor snapshotted at push time (e.g. saga)
externalId*stringIdentifier the vendor returned for the created Pitch
pushedBy*stringUser who performed the push
^[0-7][0-9A-HJKMNP-TV-Z]{25}$pushedAt*stringISO 8601 timestamp the push completed
date-timecurl -X POST 'https://api.nuvelics.com/api/tenant/v1/stories/string/push' \ -H 'Content-Type: application/json' \ -d '{ "nrcsConfigId": "string"}'{ "id": "string", "storyId": "string", "orgId": "string", "nrcsConfigId": "string", "vendor": "string", "externalId": "string", "pushedBy": "string", "pushedAt": "2019-08-24T14:15:22Z"}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$application/json- body
kind*"quote""quote"original*stringThe quote's original text, as returned in StoryKeyQuote.original.text
1 <= length <= 10000The element is dismissed (a no-op when it already was); the story is returned with it flagged dismissed, and outputs no longer use it
application/json- response
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$orgId*stringOwning organization identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$source?stringWhere the story came from: an approved pitch or the newsroom system (NRCS)
"pitch""pitch""nrcs"newsdeskId*stringOwning newsdesk; null for a story minted from the NRCS, which has no pitch
^[0-7][0-9A-HJKMNP-TV-Z]{25}$pitchId*stringMinting pitch; null for a story minted from the NRCS
^[0-7][0-9A-HJKMNP-TV-Z]{25}$title*stringStory title, inherited from the minting pitch or kept in sync from the NRCS record
summary*stringThe story's summary: the minting pitch's, read through at request time, or the NRCS story's own
whyItMatters*stringThe story's rationale: the minting pitch's, read through at request time, or the NRCS story's own
contentLanguage?stringLanguage code of the story's content; present only on an NRCS story (a pitch story's lives on its pitch)
enrichmentStatus*stringClaim-loop status of the enrichment worker
"pending""running""enriched""failed"enrichmentAttempts*integerTransient-failure retry count; enrichment_status lands failed once this hits the ceiling
0 <= valuelastEnrichmentError?stringFailure reason from the most recent enrichment run; present only when enrichmentStatus is failed and a run captured an error (absent for failures predating this field or terminal retry-ceiling failures with no captured run error)
origin?stringWhere the story came from: engine for a pitch the engine generated, manual for a pitch a person created, or the vendor of the NRCS record (for example saga) for a story minted from the NRCS. Derived on read; present on list and detail reads
nrcsDropped?stringWhy the newsroom system dropped this story, archived or deleted; null while it is live and always null for a pitch story. Present on list and detail reads. A dropped story refuses new and regenerated outputs and leaves the default list
"archived""deleted"nullenrichedContentSha?stringDigest of the NRCS text the story's enrichment was last computed from; null until an NRCS story is first enriched and always null for a pitch story. Present on a detail read. Compared with an NRCS record's contentSha to tell whether the enrichment is outdated
storyType*stringSOM story_type, stored verbatim
"PLANNED""ACTIVE""KILLED""SPIKED""ARCHIVED""ORPHAN"lifecyclePhase?stringSOM lifecycle_phase; present if and only if storyType is ACTIVE
"DEVELOPING""READY_TO_AIR""BREAKING""PUBLISHED"phaseEnteredAt?stringISO 8601 timestamp the story entered its current lifecycle phase
date-timesequenceNumber*integerMonotonic SOM sequence_number, bumped on every consumer-ordered mutation
0 <= valuecreatedAt*stringISO 8601 creation timestamp
date-timeupdatedAt*stringISO 8601 timestamp of the most recent update
date-timesources*array<>Both source origins: frozen originals plus research-discovered additional sources
meaning?5W1H meaning block; absent until the story has been enriched
factCheck?Overall fact-check assessment; absent until the story has been enriched
claims*array<>Key claims with fact-check status and cited sources; empty until enriched
entities*array<>Key entities; empty until enriched
timeline*array<>Chronologically ordered story events; empty until enriched
quotes*array<>Key quotes in rank order, dismissed ones included and flagged; empty until enriched, and for a story enriched before quotes existed
media*array<>Related media projected from the contributing articles; empty until enriched
ugcPosts*array<>Candidate eyewitness/UGC posts surfaced by the UGC search step, dismissed ones included and flagged; empty until enriched
mamAssets*array<>Photos and videos surfaced from the org's own MAM archive, dismissed ones included and flagged; empty until enriched, and empty for an org with no MAM connection
nrcsPushes*array<>NRCS connections this story has been pushed to; empty until pushed at least once
nrcsRecords?array<>The newsroom-system records behind this story, oldest first; present on GET /stories/{id}, empty for a pitch story never pushed
enrichmentPlan*The research plan computed for this story's latest completed enrichment run; null for a pre-enrichment story or one enriched before this field existed
enrichmentFreshness?||Where the story's enrichment stands (dropped, running, not_enriched, failed, outdated, no_sources, current); present on GET /stories/{id}
curl -X POST 'https://api.nuvelics.com/api/tenant/v1/stories/string/dismissals' \ -H 'Content-Type: application/json' \ -d '{ "kind": "quote", "original": "string"}'{ "id": "string", "orgId": "string", "source": "pitch", "newsdeskId": "string", "pitchId": "string", "title": "string", "summary": "string", "whyItMatters": "string", "contentLanguage": "string", "enrichmentStatus": "pending", "enrichmentAttempts": 0, "lastEnrichmentError": "string", "origin": "string", "nrcsDropped": "archived", "enrichedContentSha": "string", "storyType": "PLANNED", "lifecyclePhase": "DEVELOPING", "phaseEnteredAt": "2019-08-24T14:15:22Z", "sequenceNumber": 0, "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z", "sources": [ { "id": "string", "storyId": "string", "origin": "original", "articleId": "string", "url": "string", "title": "string", "publisher": "string", "publisherKey": "string", "snippet": "string", "excerpt": "string", "publishedAt": "2019-08-24T14:15:22Z", "fetched": true, "position": 0, "useAsMedia": true, "articleAcquiredVia": "datasource", "seedAddedAt": "2019-08-24T14:15:22Z", "iconUrl": "string", "recall": { "kind": "kill", "note": "string" } } ], "meaning": { "who": "string", "what": "string", "when": "string", "where": "string", "why": "string", "how": "string", "summary": "string", "confidence": 0 }, "factCheck": { "assessment": "confirmed", "summary": "string" }, "claims": [ { "claim": "string", "status": "confirmed", "note": "string", "sourceIds": [ "string" ], "assertions": [ { "sourceId": "string", "value": "string", "quote": "string", "fragmentMatches": true } ] } ], "entities": [ { "type": "person", "name": "string", "description": "string", "role": "string", "isPrimary": true } ], "timeline": [ { "headline": "string", "day": "2019-08-24", "occurredAt": "2019-08-24T14:15:22Z", "status": "confirmed", "sourceIds": [ "string" ] } ], "quotes": [ { "text": "string", "original": { "text": "string", "language": "string" }, "version": { "kind": "rendering", "text": "string", "sourceId": "string", "publisher": "string" }, "spokenLanguage": "string", "speaker": "string", "speakerRole": "string", "entity": "string", "isPrimarySpeaker": true, "context": "string", "saidOn": "2019-08-24", "kind": "spoken", "origin": "passage", "fragment": true, "soundbite": { "partUrl": "string", "posterUrl": "string", "startMs": 0, "endMs": 0 }, "sourceIds": [ "string" ], "ugcPostUrl": "string", "rank": 0, "dismissed": true, "dismissedVia": "quote" } ], "media": [ { "mediaType": "image", "assetUrl": "string", "posterUrl": "string", "caption": "string", "width": 0, "height": 0, "durationMs": 0, "credit": "string", "usageTerms": [ "string" ], "sourceArticleId": "string", "assetId": "string", "photoVendor": true, "dismissed": true, "dismissKey": "string" } ], "ugcPosts": [ { "source": "x", "postUrl": "string", "authorHandle": "string", "authorName": "string", "text": "string", "postedAt": "2019-08-24T14:15:22Z", "hasMedia": true, "mediaType": "string", "rank": 0, "possibleReuse": true, "possibleReuseNote": "string", "dismissed": true } ], "mamAssets": [ { "mamConfigId": "string", "itemId": "string", "itemType": "image", "title": "string", "description": "string", "mediaCreatedOn": "2019-08-24T14:15:22Z", "durationMs": 0, "whyRelevant": "string", "matchedFields": [ "string" ], "thumbnailUrl": "string", "thumbnailUrlExpiresAt": "2019-08-24T14:15:22Z", "rank": 0, "itemUrl": "string", "dismissed": true } ], "nrcsPushes": [ { "id": "string", "storyId": "string", "orgId": "string", "nrcsConfigId": "string", "vendor": "string", "externalId": "string", "pushedBy": "string", "pushedAt": "2019-08-24T14:15:22Z" } ], "nrcsRecords": [ { "id": "string", "vendor": "saga", "nrcsConfigId": "string", "externalId": "string", "entityType": "story", "state": "string", "assignedMemberIds": [ "string" ], "bodyText": "string", "externalUrl": "string", "contentSha": "string", "status": "active" } ], "enrichmentPlan": { "research": "full", "researchRule": "string", "ugcSearch": "searched", "ugcRule": "string", "researchOutcome": "query-gen-failed", "mamSearch": "searched", "mamRule": "string", "quotesRequested": true, "quotesFailed": true, "synthesisSections": [ "meaning" ] }, "enrichmentFreshness": { "state": "dropped" }}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$application/json- body
kind*"quote""quote"original*stringThe quote's original text, as returned in StoryKeyQuote.original.text
1 <= length <= 10000The element's dismissal is removed (a no-op when it was not dismissed); the story is returned
application/json- response
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$orgId*stringOwning organization identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$source?stringWhere the story came from: an approved pitch or the newsroom system (NRCS)
"pitch""pitch""nrcs"newsdeskId*stringOwning newsdesk; null for a story minted from the NRCS, which has no pitch
^[0-7][0-9A-HJKMNP-TV-Z]{25}$pitchId*stringMinting pitch; null for a story minted from the NRCS
^[0-7][0-9A-HJKMNP-TV-Z]{25}$title*stringStory title, inherited from the minting pitch or kept in sync from the NRCS record
summary*stringThe story's summary: the minting pitch's, read through at request time, or the NRCS story's own
whyItMatters*stringThe story's rationale: the minting pitch's, read through at request time, or the NRCS story's own
contentLanguage?stringLanguage code of the story's content; present only on an NRCS story (a pitch story's lives on its pitch)
enrichmentStatus*stringClaim-loop status of the enrichment worker
"pending""running""enriched""failed"enrichmentAttempts*integerTransient-failure retry count; enrichment_status lands failed once this hits the ceiling
0 <= valuelastEnrichmentError?stringFailure reason from the most recent enrichment run; present only when enrichmentStatus is failed and a run captured an error (absent for failures predating this field or terminal retry-ceiling failures with no captured run error)
origin?stringWhere the story came from: engine for a pitch the engine generated, manual for a pitch a person created, or the vendor of the NRCS record (for example saga) for a story minted from the NRCS. Derived on read; present on list and detail reads
nrcsDropped?stringWhy the newsroom system dropped this story, archived or deleted; null while it is live and always null for a pitch story. Present on list and detail reads. A dropped story refuses new and regenerated outputs and leaves the default list
"archived""deleted"nullenrichedContentSha?stringDigest of the NRCS text the story's enrichment was last computed from; null until an NRCS story is first enriched and always null for a pitch story. Present on a detail read. Compared with an NRCS record's contentSha to tell whether the enrichment is outdated
storyType*stringSOM story_type, stored verbatim
"PLANNED""ACTIVE""KILLED""SPIKED""ARCHIVED""ORPHAN"lifecyclePhase?stringSOM lifecycle_phase; present if and only if storyType is ACTIVE
"DEVELOPING""READY_TO_AIR""BREAKING""PUBLISHED"phaseEnteredAt?stringISO 8601 timestamp the story entered its current lifecycle phase
date-timesequenceNumber*integerMonotonic SOM sequence_number, bumped on every consumer-ordered mutation
0 <= valuecreatedAt*stringISO 8601 creation timestamp
date-timeupdatedAt*stringISO 8601 timestamp of the most recent update
date-timesources*array<>Both source origins: frozen originals plus research-discovered additional sources
meaning?5W1H meaning block; absent until the story has been enriched
factCheck?Overall fact-check assessment; absent until the story has been enriched
claims*array<>Key claims with fact-check status and cited sources; empty until enriched
entities*array<>Key entities; empty until enriched
timeline*array<>Chronologically ordered story events; empty until enriched
quotes*array<>Key quotes in rank order, dismissed ones included and flagged; empty until enriched, and for a story enriched before quotes existed
media*array<>Related media projected from the contributing articles; empty until enriched
ugcPosts*array<>Candidate eyewitness/UGC posts surfaced by the UGC search step, dismissed ones included and flagged; empty until enriched
mamAssets*array<>Photos and videos surfaced from the org's own MAM archive, dismissed ones included and flagged; empty until enriched, and empty for an org with no MAM connection
nrcsPushes*array<>NRCS connections this story has been pushed to; empty until pushed at least once
nrcsRecords?array<>The newsroom-system records behind this story, oldest first; present on GET /stories/{id}, empty for a pitch story never pushed
enrichmentPlan*The research plan computed for this story's latest completed enrichment run; null for a pre-enrichment story or one enriched before this field existed
enrichmentFreshness?||Where the story's enrichment stands (dropped, running, not_enriched, failed, outdated, no_sources, current); present on GET /stories/{id}
curl -X POST 'https://api.nuvelics.com/api/tenant/v1/stories/string/dismissals/restore' \ -H 'Content-Type: application/json' \ -d '{ "kind": "quote", "original": "string"}'{ "id": "string", "orgId": "string", "source": "pitch", "newsdeskId": "string", "pitchId": "string", "title": "string", "summary": "string", "whyItMatters": "string", "contentLanguage": "string", "enrichmentStatus": "pending", "enrichmentAttempts": 0, "lastEnrichmentError": "string", "origin": "string", "nrcsDropped": "archived", "enrichedContentSha": "string", "storyType": "PLANNED", "lifecyclePhase": "DEVELOPING", "phaseEnteredAt": "2019-08-24T14:15:22Z", "sequenceNumber": 0, "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z", "sources": [ { "id": "string", "storyId": "string", "origin": "original", "articleId": "string", "url": "string", "title": "string", "publisher": "string", "publisherKey": "string", "snippet": "string", "excerpt": "string", "publishedAt": "2019-08-24T14:15:22Z", "fetched": true, "position": 0, "useAsMedia": true, "articleAcquiredVia": "datasource", "seedAddedAt": "2019-08-24T14:15:22Z", "iconUrl": "string", "recall": { "kind": "kill", "note": "string" } } ], "meaning": { "who": "string", "what": "string", "when": "string", "where": "string", "why": "string", "how": "string", "summary": "string", "confidence": 0 }, "factCheck": { "assessment": "confirmed", "summary": "string" }, "claims": [ { "claim": "string", "status": "confirmed", "note": "string", "sourceIds": [ "string" ], "assertions": [ { "sourceId": "string", "value": "string", "quote": "string", "fragmentMatches": true } ] } ], "entities": [ { "type": "person", "name": "string", "description": "string", "role": "string", "isPrimary": true } ], "timeline": [ { "headline": "string", "day": "2019-08-24", "occurredAt": "2019-08-24T14:15:22Z", "status": "confirmed", "sourceIds": [ "string" ] } ], "quotes": [ { "text": "string", "original": { "text": "string", "language": "string" }, "version": { "kind": "rendering", "text": "string", "sourceId": "string", "publisher": "string" }, "spokenLanguage": "string", "speaker": "string", "speakerRole": "string", "entity": "string", "isPrimarySpeaker": true, "context": "string", "saidOn": "2019-08-24", "kind": "spoken", "origin": "passage", "fragment": true, "soundbite": { "partUrl": "string", "posterUrl": "string", "startMs": 0, "endMs": 0 }, "sourceIds": [ "string" ], "ugcPostUrl": "string", "rank": 0, "dismissed": true, "dismissedVia": "quote" } ], "media": [ { "mediaType": "image", "assetUrl": "string", "posterUrl": "string", "caption": "string", "width": 0, "height": 0, "durationMs": 0, "credit": "string", "usageTerms": [ "string" ], "sourceArticleId": "string", "assetId": "string", "photoVendor": true, "dismissed": true, "dismissKey": "string" } ], "ugcPosts": [ { "source": "x", "postUrl": "string", "authorHandle": "string", "authorName": "string", "text": "string", "postedAt": "2019-08-24T14:15:22Z", "hasMedia": true, "mediaType": "string", "rank": 0, "possibleReuse": true, "possibleReuseNote": "string", "dismissed": true } ], "mamAssets": [ { "mamConfigId": "string", "itemId": "string", "itemType": "image", "title": "string", "description": "string", "mediaCreatedOn": "2019-08-24T14:15:22Z", "durationMs": 0, "whyRelevant": "string", "matchedFields": [ "string" ], "thumbnailUrl": "string", "thumbnailUrlExpiresAt": "2019-08-24T14:15:22Z", "rank": 0, "itemUrl": "string", "dismissed": true } ], "nrcsPushes": [ { "id": "string", "storyId": "string", "orgId": "string", "nrcsConfigId": "string", "vendor": "string", "externalId": "string", "pushedBy": "string", "pushedAt": "2019-08-24T14:15:22Z" } ], "nrcsRecords": [ { "id": "string", "vendor": "saga", "nrcsConfigId": "string", "externalId": "string", "entityType": "story", "state": "string", "assignedMemberIds": [ "string" ], "bodyText": "string", "externalUrl": "string", "contentSha": "string", "status": "active" } ], "enrichmentPlan": { "research": "full", "researchRule": "string", "ugcSearch": "searched", "ugcRule": "string", "researchOutcome": "query-gen-failed", "mamSearch": "searched", "mamRule": "string", "quotesRequested": true, "quotesFailed": true, "synthesisSections": [ "meaning" ] }, "enrichmentFreshness": { "state": "dropped" }}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$include?|array<string>Relations to sideload. uploadedBy populates included.users with the users who attached the photos.
The photos uploaded to the story, oldest first, each with a preview URL
application/json- response
items*array<>included?curl -X GET 'https://api.nuvelics.com/api/tenant/v1/stories/string/photos'{ "items": [ { "assetId": "string", "storyId": "string", "credit": "string", "caption": "string", "width": 0, "height": 0, "uploadedBy": "string", "createdAt": "2019-08-24T14:15:22Z", "previewUrl": "string" } ], "included": { "users": { "property1": { "id": "string", "name": "string", "email": "string" }, "property2": { "id": "string", "name": "string", "email": "string" } } }}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$application/json- body
assetId*stringAsset identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$credit?stringCredit line as entered, e.g. a photographer's name; shown on a card with a prefix
1 <= length <= 200caption?stringWhat the photo shows; read as the photo's caption and to write alt text from
1 <= length <= 500The completed upload is attached; its size was read from the stored bytes
application/json- response
assetId*stringAsset identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$storyId*stringUUID v7, base32-encoded (26 Crockford chars)
^[0-7][0-9A-HJKMNP-TV-Z]{25}$credit*stringCredit line as entered, e.g. a photographer's name; shown on a card with a prefix
1 <= length <= 200caption*stringWhat the photo shows; read as the photo's caption and to write alt text from
1 <= length <= 500width*integerPixel width read from the stored image's header
0 <= valueheight*integerPixel height read from the stored image's header
0 <= valueuploadedBy*stringUser who attached the photo; null for a service key
^[0-7][0-9A-HJKMNP-TV-Z]{25}$createdAt*stringdate-timecurl -X POST 'https://api.nuvelics.com/api/tenant/v1/stories/string/photos' \ -H 'Content-Type: application/json' \ -d '{ "assetId": "string"}'{ "assetId": "string", "storyId": "string", "credit": "string", "caption": "string", "width": 0, "height": 0, "uploadedBy": "string", "createdAt": "2019-08-24T14:15:22Z"}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$application/json- body
url*stringA publicly reachable https URL of a JPEG, PNG or WebP image, at most 20 MiB. Fetched once; not stored
urilength <= 2048credit?stringCredit line as entered, e.g. a photographer's name; shown on a card with a prefix
1 <= length <= 200caption?stringWhat the photo shows; read as the photo's caption and to write alt text from
1 <= length <= 500The image was fetched, stored as a story photo and attached; its size was read from the bytes
application/json- response
assetId*stringAsset identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$storyId*stringUUID v7, base32-encoded (26 Crockford chars)
^[0-7][0-9A-HJKMNP-TV-Z]{25}$credit*stringCredit line as entered, e.g. a photographer's name; shown on a card with a prefix
1 <= length <= 200caption*stringWhat the photo shows; read as the photo's caption and to write alt text from
1 <= length <= 500width*integerPixel width read from the stored image's header
0 <= valueheight*integerPixel height read from the stored image's header
0 <= valueuploadedBy*stringUser who attached the photo; null for a service key
^[0-7][0-9A-HJKMNP-TV-Z]{25}$createdAt*stringdate-timecurl -X POST 'https://api.nuvelics.com/api/tenant/v1/stories/string/photos/from-url' \ -H 'Content-Type: application/json' \ -d '{ "url": "http://example.com"}'{ "assetId": "string", "storyId": "string", "credit": "string", "caption": "string", "width": 0, "height": 0, "uploadedBy": "string", "createdAt": "2019-08-24T14:15:22Z"}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$application/json- body
assetId*stringAsset identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$A caption a model suggests for the photo, for a person to review before it is attached. Nothing is stored
application/json- response
caption*stringWhat the photo shows; read as the photo's caption and to write alt text from
1 <= length <= 500curl -X POST 'https://api.nuvelics.com/api/tenant/v1/stories/string/photos/caption-suggestion' \ -H 'Content-Type: application/json' \ -d '{ "assetId": "string"}'{ "caption": "string"}x-api-key<token>A service key (nvs_...) in the x-api-key header. A service key belongs to one organization: an X-Org-Id header is optional and, when sent, must name that organization. This header also accepts any credential the bearer scheme does, and when a request sends both headers, this one is used.
id*stringStory identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$assetId*stringAsset identifier
^[0-7][0-9A-HJKMNP-TV-Z]{25}$The photo and its file are removed
curl -X DELETE 'https://api.nuvelics.com/api/tenant/v1/stories/string/photos/string'