Wireva
Documentation

API reference

The wire speaks IPTC ninjs 3.2 — the format professional clients already parse. Registration is free: create an account, copy the key, start pulling.

Get a free key OpenAPI 3.1

Authentication

Your key has the form prefix.secret. Only the hash is stored on our side; the plaintext is shown once, when the key is created.

curl -H "Authorization: Bearer wv_xxxxxxxx.SECRET" \
     "https://wireva.mib.news/api/v1/items?language=de&limit=20"

X-Api-Key: … and ?api_key=… also work — the latter for readers that cannot set headers. Anonymous requests are allowed and deliberately trimmed: headlines, metadata and rights, but no body_html and no source trail, at 30 requests a minute.

Endpoints

PathReturns
GET /api/v1/itemsWire items as ninjs.
GET /api/v1/items/{uid}One item in full.
GET /api/v1/storiesEvents with their language versions listed.
GET /api/v1/stories/{uid}One event as a ninjs composite package.
GET /api/v1/media/{uid}A picture with licence, provenance and delivery mode.
GET /api/v1/feeds/{uid}/itemsItems of a feed you saved in your account.
GET /api/v1/topics · /publications · /languagesVocabularies for building filters.

Filters on /items

ParameterExampleMeaning
languagede,ukLanguage codes, comma-separated.
countryDE,ATCountry of the desk or of the event.
topicpolitics,healthSlugs from /topics.
publicationkernblikSlugs from /publications.
typestandard,updateEditorial type.
rightsowned,agency_originalRights class.
redistributable1Only what you may republish in full.
include_link_only0Drop monitoring items.
qBundestagFull-text search across all languages.
since · until2026-08-21T10:00:00ZWindow on publication time.
limit · offset200 · 400Pagination, 200 items maximum.
body0Omit the text — for cheap sweeps.

What an item looks like

Standard ninjs fields carry standard values. Everything ninjs has no home for — the rights decision, the production provenance, the source trail — lives in extra under the wireva: prefix, which is exactly what extra is for, and never instead of a standard field.

{
  "$schema": "https://iptc.org/std/ninjs/ninjs-schema_3.2.json",
  "uri": "urn:newsml:wireva.mib.news:item:4e74f36e-…",
  "type": "text", "profile": "standard", "version": "1",
  "pubstatus": "usable", "language": "de",
  "headline": "…",
  "usageterms": "Subscribers may republish this item in full…",
  "copyrightholder": "Haydamax OÜ",
  "subject": [{ "code": "medtop:11000000", "scheme": "…/mediatopic/" }],
  "associations": { "featuremedia": { "renditions": { "source": { "href": "…" } } } },
  "extra": {
    "wireva:rights": { "class": "agency_original", "redistribution_allowed": true,
                       "attribution_text": "Wireva / Kernblik",
                       "canonical_required": true, "canonical_url": "https://…",
                       "excerpt_max_chars": 0, "decided_by_rule": "agency_original_verified" },
    "wireva:provenance": { "production_method": "automated", "ai_stages": {…},
                           "verification_status": "multi_source", "independent_confirmations": 2,
                           "ai_disclosure_required": true, "ai_disclosure_text": "…",
                           "independence_check": { "status": "passed", "score": 0.21 },
                           "sources": [ { "url": "…", "role": "primary", "official": false } ] },
    "wireva:story": { "uri": "…", "languages": ["de","uk","fr"], "item_count": 7 }
  }
}

A monitoring item (rights.class = link_only) arrives without body_html: instead there is a body_text of at most excerpt_max_chars and a note saying so. That is not a request option — the serialiser cannot be talked into shipping the body of such an item.

What you agree to do with it

  1. Publish the credit from wireva:rights.attribution_text when attribution_required is true.
  2. Set rel=canonical to canonical_url when canonical_required is true — otherwise your reprint competes in search with the desk that filed it.
  3. Carry the AI notice from provenance.ai_disclosure_text when ai_disclosure_required is true and you publish in the EU.
  4. Respect the picture terms — redistribution_allowed, commercial_use_allowed, modifications_allowed, share_alike_required — and take the file from where delivery_mode points.
  5. Honour embargoed, and take down anything that turns up as pubstatus: canceled.

RSS and Atom

AddressContents
/feed/ · /feed/atom/Everything.
/feed/breaking/Alerts, flashes, breaking, corrections, withdrawals.
/feed/language/{code}/One language desk.
/feed/topic/{slug}/One subject.
/feed/country/{cc}/One country.
/feed/publication/{slug}/One title.
/feed/custom/{uid}/{token}/Your own saved selection.

Feeds carry the rights decision in their own namespace, so a newsroom with a reader and no developer is not left guessing: <wireva:rights_class>, <wireva:attribution>, <wireva:canonical_url>, <wireva:production_method>, <wireva:ai_disclosure>.

Webhooks

Register an HTTPS endpoint in your account and receive each new item within seconds. Events: item.published, item.updated, item.correction, item.withdrawal. Twenty consecutive failures disable the endpoint, with the reason recorded so you can see why.

POST /your/endpoint
X-Wireva-Event: item.published
X-Wireva-Signature: sha256=<hmac>

{ "event": "item.published", "item": { …ninjs… } }
import hmac, hashlib

expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, request.headers["X-Wireva-Signature"]):
    return 401

Email

Instant on every matching item, breaking only, or a digest in the morning, at midday or in the evening — in your own timezone. Set it up in your account; every subscription carries its own unsubscribe link.

Limits and errors

Free tier: 120 requests a minute, 5 000 a day, 200 items per request. Anonymous: 30 a minute without full text. Limits are values on your account, not constants in our code — write to wire@wireva.mib.news if your workflow needs more.

StatusBodyCause
401invalid_api_key · api_key_expiredKey unknown, revoked or expired.
403subscriber_disabled · forbiddenAccount disabled, or someone else's feed.
404not_foundNo such item, story or picture.
429rate_limited · quota_exceededPer-minute or per-day limit; detail says which.

Sweeping the wire politely

Do not poll /items without a window. Keep a cursor on since and page with limit=200, or register a webhook and stop polling altogether. For a nightly catch-up, body=0 gives you the list of uri cheaply; fetch the ones you actually want one by one.

Coming next

NewsML-G2 XML for professional clients, CMS plugins (WordPress first) and embeddable blocks. The internal model was shaped so those are exports, not rewrites.