Leitfaden für Publisher
Produkte veröffentlichen
Bei prodid zu veröffentlichen heißt, zwei Dateien ins Web und einen Eintrag ins DNS zu stellen. Auf der eigenen Domain gibt es keine Registrierung und keinen Schlüssel: Die Domain ist der Nachweis, und Sie ändern oder ziehen zurück, was Sie veröffentlichen, indem Sie die Dateien ändern.
Wie veröffentlichen Sie?
Identität und Hosting sind getrennt. Ihre Identität ist eine Domain, die Sie kontrollieren; wo die Dokumente tatsächlich liegen, ist ein Detail, das Sie später ändern können, ohne Ihre Identität oder eine Kennung zu ändern, die prodid Ihren Produkten zugewiesen hat. Drei Wege, die alle genau dieselben Datensätze erzeugen.
Weg 1
Sie können Dateien auf Ihrer eigenen Domain ausliefern.
Liefern Sie das Discovery-Dokument auf der Domain aus und veröffentlichen Sie einen TXT-Eintrag, der die Domain selbst nennt.
- Identität
- die Domain
- Vertrauen
- verified
Weg 2
Sie besitzen eine Domain, können dort aber keine Dateien ausliefern.
Veröffentlichen Sie unter einem gehosteten Slug und lassen Sie einen TXT-Eintrag auf Ihrer Domain auf diesen Host zeigen.
- Identität
- die Domain, per DNS nachgewiesen
- Vertrauen
- verified
Weg 3
Sie haben gar keine Domain.
Veröffentlichen Sie unter einem gehosteten Slug. Fügen Sie später eine Domain hinzu, ohne etwas zu verlieren.
- Identität
- der Slug-Host
- Vertrauen
- unverified
Die Wege 2 und 3 nutzen den gehosteten Veröffentlichungsdienst unter <slug>.prodid.org. Melden Sie sich bei publish.prodid.org mit einem Link an, der an Ihre E-Mail geht, legen Sie eine Site an, laden Sie Ihre Datei hoch und verbinden Sie eine Domain, falls Sie eine haben. Dort können Sie jederzeit alles exportieren oder die Site löschen.
Weg 1
Auf der eigenen Domain veröffentlichen
Zwei Dateien und ein DNS-Eintrag. Eine Plattform, die für Händler veröffentlicht, tut dasselbe auf jeder Händlerdomain, sodass jeder Händler seine eigene Identität und seine eigene Vertrauensstufe behält.
Das Discovery-Dokument ausliefern
Eine Datei unter einem festen Pfad, die auflistet, wo Ihre Produkt-Feeds liegen:
https://acme.example/.well-known/prodid.json.well-known/prodid.jsonapplication/json{ "$type": "org.prodid.feed", "version": 1, "publisher": { "name": "Acme Tekstil", "contact": "data@acme.example" }, "license": "CC0-1.0", "feeds": ["https://acme.example/prodid/items.ndjson"] }Das Beispiel aus spec/fixtures/v1/examples/prodid.json, direkt aus der Datei gerendert. $typePflicht: ja- Immer org.prodid.feed.
versionPflicht: ja- 1. Ein Dokument mit 0 wird von Crawls akzeptiert, die vor 2027-01-26 00:00 UTC beginnen, und danach als definitiv negativ abgelehnt.
publisher.namePflicht: ja- Der Name, den ein Mensch neben Ihren Claims sehen soll.
publisher.contactPflicht: nein- Eine E-Mail-Adresse, die jemand wirklich liest. Dorthin schreibt der Index, wenn Ihre Quelle in Lapse geht; es ist die einzige Warnung, die Sie bekommen.
licensePflicht: ja- SPDX-Kennung für die Angaben in Ihren Feeds, etwa CC0-1.0.
feedsPflicht: ja- Bis zu 100 https-URLs, alle auf demselben Host wie dieses Dokument.
domainPflicht: bei Delegation- Die Domain, für die dieses Dokument spricht. Pflicht, sobald das Dokument über einen TXT-Eintrag erreicht wird, der einen anderen Host nennt, und dann muss sie dieser Domain entsprechen. Optional, wenn die Domain das Dokument selbst ausliefert; ist sie angegeben, muss sie trotzdem passen.
Liefern Sie es über HTTPS auf dem Standardport mit gültigem Zertifikat als
application/jsonaus, oder als beliebigesapplication/…+json. Leiten Sie nicht auf einen anderen Host weiter: Die eine Weiterleitung, der der Crawler folgt, istacme.examplenachwww.acme.example.Den Feed ausliefern
Ein Feed ist NDJSON: ein vollständiges JSON-Objekt pro Zeile, UTF-8, durch Zeilenumbrüche getrennt. Kein Array drumherum, keine Kommas zwischen den Zeilen. So lässt sich ein Feed mit zwei Millionen Produkten Zeile für Zeile streamen, und eine kaputte Zeile kostet Sie nur diese Zeile, nicht den Rest.
prodid/items.ndjsonapplication/x-ndjson{"$type":"org.prodid.item","key":"TJ-2041-NVY-M","brand":"Acme","name":"Trail Jacket","lang":"en","group":"TJ-2041","variant":{"color":"navy","size":"M"},"identifiers":[{"scheme":"gtin","value":"09506000134352"},{"scheme":"mpn","value":"TJ-2041-NVY-M"}],"markets":["TR","DE"],"properties":{"material":"100% recycled polyester","madeIn":"TR","weight":{"value":480,"unit":"g"}},"media":[{"url":"https://acme.example/img/tj2041-navy.webp","license":"CC-BY-4.0","kind":"image"}]} {"$type":"org.prodid.item","key":"TJ-2041-NVY-L","brand":"Acme","name":"Trail Jacket","lang":"en","group":"TJ-2041","variant":{"color":"navy","size":"L"},"identifiers":[{"scheme":"gtin","value":"09506000134406"},{"scheme":"mpn","value":"TJ-2041-NVY-L"}],"markets":["TR","DE"],"properties":{"material":"100% recycled polyester","madeIn":"TR","weight":{"value":505,"unit":"g"}},"media":[{"url":"https://acme.example/img/tj2041-navy.webp","license":"CC-BY-4.0","kind":"image"}]} {"$type":"org.prodid.item","key":"TJ-2041-OLV-M","brand":"Acme","name":"Trail Jacket","lang":"en","group":"TJ-2041","variant":{"color":"olive","size":"M"},"identifiers":[{"scheme":"gtin","value":"09506000134413"},{"scheme":"mpn","value":"TJ-2041-OLV-M"}],"markets":["TR"],"properties":{"material":"100% recycled polyester","madeIn":"TR","weight":{"value":480,"unit":"g"}},"media":[{"url":"https://acme.example/img/tj2041-olive.webp","license":"CC-BY-4.0","kind":"image"}]}Drei Varianten eines Produkts aus spec/fixtures/v1/examples/items.ndjson. Sie teilen sich eine group, also baut der Index daraus eine Familie mit drei Varianten. Feeds liegen auf demselben Host wie das Dokument, das sie auflistet. Ein Discovery-Dokument, das einen Feed auf einem anderen Host nennt, wird ganz abgelehnt, nicht teilweise: Sie verlieren die ganze Quelle, nicht einen Feed, und es zählt als definitiv negativ, startet also die Lapse-Uhr weiter unten. Das JSON von der eigenen Website und das NDJSON von einem separaten CDN-Hostnamen auszuliefern ist ein naheliegender Wunsch und wird in v1 nicht unterstützt. Legen Sie beides auf einen Host.
Die erste dieser Zeilen, lesbar formatiert:
ein org.prodid.item-Datensatz{ "$type": "org.prodid.item", "key": "TJ-2041-NVY-M", "brand": "Acme", "name": "Trail Jacket", "lang": "en", "group": "TJ-2041", "variant": { "color": "navy", "size": "M" }, "identifiers": [ { "scheme": "gtin", "value": "09506000134352" }, { "scheme": "mpn", "value": "TJ-2041-NVY-M" } ], "markets": ["TR", "DE"], "properties": { "material": "100% recycled polyester", "madeIn": "TR", "weight": { "value": 480, "unit": "g" } }, "media": [{ "url": "https://acme.example/img/tj2041-navy.webp", "license": "CC-BY-4.0", "kind": "image" }] }$typePflicht: ja- Immer org.prodid.item.
keyPflicht: ja- Ihr stabiler Name für diesen Datensatz innerhalb des Feeds. Wird derselbe key erneut veröffentlicht, ersetzt er den alten.
brandPflicht: ja- Die Marke, wie sie auf dem Produkt steht. Sie wird normalisiert, bevor sie eine mpn eingrenzt, sodass ARÇELİK und Arçelik eine Marke sind, nicht zwei.
namePflicht: ja- Der Produktname ohne die Variantenachsen.
identifiersPflicht: ja- Mindestens ein { scheme, value }, und mindestens eines, das der Index speichern kann. Werte haben an keinem Ende Leerraum und sind nicht leer. Eine gtin muss 8, 12, 13 oder 14 Ziffern mit korrekter Prüfziffer haben und darf nicht nur aus Nullen bestehen; eine mpn braucht eine brand, die zu etwas normalisiert, denn darin ist sie eindeutig; eine gtin mit eingeschränkter Zirkulation wird behalten, aber nur als Ihre eigene rcn. Ein Datensatz ohne speicherbare Kennung identifiziert nichts und wird übersprungen.
langPflicht: nein- BCP-47-Tag für den lesbaren Text in diesem Datensatz.
groupPflicht: nein- Ihr eigener Gruppierungsschlüssel. Items mit demselben Wert sind Varianten einer Familie.
variantPflicht: nein- Die Achsen, die dieses Item innerhalb der Gruppe unterscheiden: Farbe, Größe, Kapazität.
categoryPflicht: nein- GS1-GPC-Brick-Code, geschrieben als gpc: gefolgt von acht Ziffern.
marketsPflicht: nein- ISO-3166-1-alpha-2-Codes der Märkte, in denen dieses Item verkauft wird.
propertiesPflicht: nein- Strings, Zahlen, Booleans, Listen oder { value, unit } für einen Messwert.
mediaPflicht: nein- Bis zu 20 https-URLs, jeweils mit einem kind und einer SPDX-Lizenz aus der Liste der aufnehmbaren. Anders als Feeds dürfen sie auf beliebigen Hosts liegen.
Senden Sie flache Items. Sie bauen nie selbst Familien oder Varianten und senden nie eine
opid: Der Index leitet das Erste ausgroupab und vergibt das Zweite. Wenn Sie bereits einen Google-Merchant-Feed erzeugen, istgroupIhreitem_group_id.Zwei Dinge über Barcodes sollten Sie vor dem Export wissen. Eine
gtinaus lauter Nullen ist kein Barcode, sondern ein Katalogplatzhalter, und ein Datensatz damit wird wie bei einer falschen Prüfziffer abgelehnt. Eine Nummer mit eingeschränkter Zirkulation, also die Bereiche für den Ladengebrauch, wird gespeichert und Ihnen zugeschrieben, identifiziert aber global nichts; sie führt Ihr Produkt also nie mit dem eines anderen zusammen, und/01/löst sie nicht auf.Die Identität im DNS beanspruchen
Sobald die Dateien online sind, veröffentlichen Sie einen Eintrag, der Ihre eigene Domain als Host nennt.
_prodid.acme.example TXT_prodid.acme.example. IN TXT "v=prodid0; host=acme.example"Er zeigt genau auf das, was die Discovery ohnehin gefunden hätte, an Ihren Daten ändert sich also nichts. Was sich ändert, ist, was jemand mit reinem Hinzufügerecht in Ihrem DNS tun kann. Ohne Eintrag übernimmt ein von ihm hinzugefügter Eintrag Ihre Identität stillschweigend, denn DNS gewinnt gegen die Datei. Steht Ihr Eintrag bereits, lässt ein zweiter die Discovery mit mehr als ein Eintrag scheitern: ein Lapse, der sichtbar ist, gemeldet wird und sich beheben lässt.
Delegieren Sie
_prodidnie an einen Dienstleister. Schreibzugriff auf_prodid.<domain>ist Kontrolle über Ihre Identität, genau wie bei DKIM oder einer ACME-DNS-01-Challenge. Eine Domain mit geteiltem DNS ist eine geteilte Identität. Geben Sie einer Agentur den Feed, nicht den Eintrag.Stellen Sie die Dateien vor dem Eintrag online, nicht danach: Ein Eintrag, der auf ein noch nicht vorhandenes Dokument zeigt, ist eine gescheiterte Discovery. Werte werden ohne Beachtung der Groß- und Kleinschreibung gelesen, und ein abschließender Punkt ist in Ordnung, also sind
ACME.Example.undacme.examplederselbe Host.Dem Index die Änderung melden
Optional. Jede bekannte Domain wird regelmäßig neu gecrawlt; ein Ping zieht nur den nächsten Crawl vor.
den Index bitten, die Discovery jetzt auszuführencurl -X POST https://prodid.org/ping \ -H 'content-type: application/json' \ -d '{"domain": "acme.example"}' HTTP/1.1 202 Accepted Content-Type: application/json {"status":"accepted"}{"domains": [...]}nimmt bis zu 1000 auf einmal; so stellt eine Plattform jeden gehosteten Händler vor. Es gibt keinen Schlüssel, denn der Ping gibt dem Aufrufer keinen Einfluss auf Inhalte, und202ist alles, was er je sagt. Er verrät nicht, ob die Domain bekannt war, ob etwas gefunden wurde oder ob jemand anderes sie vor einer Minute gepingt hat. Ein429heißt nur, dass Sie Ihr eigenes Anfragebudget überschritten haben, und Fehler kommen alsapplication/problem+json. Was mit Ihrer Domain passiert ist, steht in Ihrem Quellstatus, nicht im Ping.
Weg 2
Hosting delegieren, Identität behalten
Viele Hersteller besitzen eine Domain und können keine Datei darauf legen. Der Feed wird anderswo gehostet und die Domain per DNS nachgewiesen, sodass die Identität der Quelle weiter die Domain ist und die Vertrauensstufe weiter verified. Legen Sie bei publish.prodid.org eine Site an, geben Sie Ihre Domain ein, und Sie sehen genau den Eintrag, den Sie hinzufügen müssen; geprüft wird er für Sie.
So sieht es aus
Ein Katalog, hochgeladen unter einem gehosteten Slug
, etwa
acme.prodid.org, der sowohl das Discovery-Dokument als auch den Feed ausliefert.Ein TXT-Eintrag auf Ihrer Domain
, der diesen Host nennt. Ein Host, nie eine URL, sodass ein Eintrag den Crawler nie auf eine beliebige Adresse richten kann.
_prodid.acme.example TXT_prodid.acme.example. IN TXT "v=prodid0; host=acme.prodid.org"Ein Dokument, das Ihre Domain zurück nennt.
DNS sagt mein Dokument liegt dort drüben; das Dokument sagt ich spreche für diese Domain. Ein delegiertes Dokument ohne
domainwird abgelehnt: Fehlen gilt nie als Zustimmung, und genau das verhindert, dass jemand einen Eintrag auf den Feed eines anderen richtet.acme.prodid.org/.well-known/prodid.jsonapplication/json{ "$type": "org.prodid.feed", "version": 1, "domain": "acme.example", "publisher": { "name": "Acme Tekstil", "contact": "data@acme.example" }, "license": "CC0-1.0", "feeds": ["https://acme.prodid.org/feeds/items.ndjson"] }Aus spec/fixtures/v1/examples/prodid.delegated.json. Der einzige Unterschied zu Weg 1 ist das Feld domain, und hier ist es Pflicht. Legen Sie Ihre Seite an
Der gehostete Publisher schreibt
domainerst ins Dokument, nachdem er Ihren TXT-Eintrag selbst gesehen hat; es gibt also keinen Moment, in dem ein Dokument eine Domain beansprucht, die nicht darum gebeten hat.
Weg 3
Ohne Domain veröffentlichen
Legen Sie Ihre Seite an
Ein Erzeuger ganz ohne Domain veröffentlicht unter einem gehosteten Slug,
<slug>.prodid.org, unter eigenem Namen. Sichern Sie sich einen bei publish.prodid.org. Die Identität der Quelle ist der Slug-Host und die Vertrauensstufeunverified, weil über eine Domain nichts nachgewiesen ist. Die Datensätze sind echte Datensätze: Kennungen, Auflösung, Zuschreibung.Die meisten Publisher in dieser Lage pflegen bereits eine Google-Merchant-Produktdatei; deshalb ist die Zuordnung von einer solchen Datei zu
org.prodid.item-Datensätzen in der Spezifikation Spalte für Spalte ausgeschrieben, samt dem, was bewusst wegfällt: Preis, Verfügbarkeit, Versand und Zustand gehören zu einem Verkäufer an einem Tag, nicht zum Produkt. Einen Merchant-Feed importieren lohnt die Lektüre vor dem Export: publish.prodid.org wandelt die hochgeladene CSV- oder TSV-Datei genau mit dieser Zuordnung um. Vier Dinge darin bestimmen, wie Ihre Tabelle aussehen muss:- Vier Spalten werden zu Variantenachsen:
color,size,materialundpattern, zwischen denen ein Käufer innerhalb eineritem_group_idwählt.gender,age_group,size_typeundsize_systembleiben gewöhnliche Eigenschaften: Sie beschreiben die ganze Gruppe, und als Achsen würden sie ein Produkt in mehrere aufspalten, sobald jemand einen davon auf zwei Arten schreibt. - Ein wiederholtes Attribut ist kommagetrennt oder hat wiederholte Kopfzeilen, pro Datei, nicht pro Zelle. Eine Zelle wird nur dann an Kommas getrennt, wenn ihre Kopfzeile in der ganzen Datei einmal vorkommt; wiederholen Sie die Kopfzeile, wird jede Zelle darunter als Ganzes genommen. Nur so lässt sich ein Wert mit Komma transportieren, und Sie entscheiden das einmal für die Datei. Es gilt für
additional_image_link,product_type,product_highlight,product_detailundcertification; alles andere, auch einedescriptionvoller Kommas, wird so oder so als Ganzes genommen. - Ein
product_detailüberschreibt nie etwas. Sein mittleres Unterattribut wird zum Eigenschaftsschlüssel, der Abschnittsname entfällt, und der erste Wert für einen Schlüssel gewinnt. Ein späteres Detail mit demselben Schlüssel, oder eines, das auf einem schon von der Zuordnung erzeugten Schlüssel landet, wird verworfen und mit seiner Zeile gemeldet; eine Detail-Spalte kann also nie stillschweigend umdeuten, was der Rest der Zeile sagt. - Eine Medienlizenz muss angegeben werden. Das Merchant-Format hat keine Spalte dafür, und ohne Lizenz wird nichts aufgenommen; ein Import gibt daher eine einzige aufnehmbare SPDX-Kennung für alle Bilder und Dokumente der Datei an. Eine eigene
license-Spalte überschreibt sie Zeile für Zeile, und eine Datei mit nicht aufnehmbarer Lizenz erzeugt Datensätze ohne Medien statt fehlschlagender Datensätze.
Eine Zeile, die kein Datensatz werden kann (keine brauchbare Kennung, eine GTIN mit falscher Prüfziffer), wird übersprungen und mit ihrer Tabellenzeilennummer gemeldet, wobei die Kopfzeile Zeile 1 ist; eine schlechte Zeile kostet also diese Zeile und nicht den Import. Eine Beispieldatei zum Abgleichen liegt unter /spec/fixtures/merchant: eine CSV, die Datensätze, die sie ergeben muss, und die Zeile, die übersprungen werden muss.
Für eine Entscheidung von heute zählt vor allem, was später passiert. Ein TXT-Eintrag auf einer Domain, die Sie erwerben und die denselben Host nennt, macht beim nächsten Crawl aus dem Slug die Domain: dieselbe Quelle, dieselben Datensätze, jede
opidbleibt, und das Vertrauen steigt vonunverifiedaufverified. Ihresku-Kennungen gelten für die Quelle selbst, nicht für ihren Namen, und überstehen den Umzug. Auf publish.prodid.org ist das dasselbe Domain-Feld, das Weg 2 nutzt.- Vier Spalten werden zu Variantenachsen:
Prüfen Sie Ihre Domain
Fertig mit dem Veröffentlichen? Geben Sie Ihre Domain ein. Der Index wird gebeten, sie jetzt anzusehen, und Sie landen auf seiner Live-Statusseite.
Bevor Sie live gehen
Dateien vor dem Ping prüfen
prodid-batch check validiert Ihr Discovery-Dokument und jeden Feed genau so, wie der Index es täte, ohne Token und ohne den Index zu fragen. Es läuft aus einem Klon des Repositorys mit Bun 1.4.4. Geben Sie ihm die Dateien selbst: Ein Pfad auf .json wird als ein Dokument gelesen, jeder andere als NDJSON-Feed.
git clone https://github.com/productdevbook/prodid
cd prodid
bun install --frozen-lockfile
curl -fsSo prodid.json https://acme.example/.well-known/prodid.json
curl -fsSo items.ndjson https://acme.example/prodid/items.ndjson
bun apps/batch/src/cli.ts check prodid.json items.ndjson
prodid.json: ok, 1 record
items.ndjson: ok, 3 recordsEine Datei ohne Problem gibt ok und die Anzahl der Datensätze aus, die der Index daraus übernehmen würde. Sonst gibt es pro Problem eine Zeile im Format items.ndjson:12: message mit der betroffenen Feed-Zeile aus und endet mit einem Exit-Code ungleich null. Es liest die Dateien, nicht Ihr DNS oder Ihren Server; TXT-Eintrag, Content-Type und Cache-Header aus der Liste oben müssen Sie also weiterhin selbst prüfen.
Die Regeln, gegen die ein Datensatz validiert wird, stehen in der Spezifikation, die Schemas liegen unter /spec/schemas/v1, und /spec/fixtures/v1 enthält maschinenlesbare Vektoren, gegen die Sie Ihren Exporter laufen lassen können, bevor jemand ihn crawlt.
Die Spezifikation erscheint nur auf Englisch, und der englische Text ist der maßgebliche.
Stand: Spec v1. Der Index und der gehostete Publisher laufen auf prodid.org. Jeder kann veröffentlichen, auf der eigenen Domain oder gehostet. Die Dateiformate auf dieser Seite sind die, die der Index liest, wenn Sie ihn pingen.
Referenz
Gut zu wissen, bevor Sie irgendetwas anderes tun, denn es entscheidet, welcher der drei Wege unten Ihrer ist. Discovery läuft bei jedem Crawl von vorn, DNS zuerst, und nichts über den Weg zu Ihren Daten wird zwischen Crawls gespeichert.
Zuerst
Ein DNS-TXT-Eintrag unter
_prodid.acme.exampleGibt es dort einen
v=prodid0-Eintrag, wird ausschließlich ihm gefolgt, auch wenn er Ihre eigene Domain nennt. Der Eintrag nennt einen Host; das Dokument liegt immer unterhttps://<host>/.well-known/prodid.json.Nur wenn es keinen solchen Eintrag gibt
https://acme.example/.well-known/prodid.jsonDas Dokument auf der Domain selbst. Wer die Domain über HTTPS ausliefert, spricht für sie.
DNS kommt zuerst, weil es der stärkere Nachweis ist: Wer eine Datei auf einen Host legen kann, ist nicht immer der Inhaber der Domain, und der Inhaber muss das überstimmen können. Deshalb sollten Sie den Eintrag auch dann schreiben, wenn Sie die Datei selbst ausliefern; Weg 1, Schritt 3 erklärt, was Ihnen das bringt.
Genau ein Eintrag, und nichts dahinter. Mehr als ein v=prodid0-Eintrag unter diesem Namen ist ein Fehler, keine Auswahl, und ein einzelner fehlerhafter oder zu langer ist ebenfalls ein Fehler. Es gibt keinen Rückfall: Sobald ein Eintrag existiert, beendet ein nicht funktionierender Eintrag die Discovery, statt den Crawler zu Ihrer Domain zu schicken. Wenn Sie den Host wechseln, ersetzen Sie den Eintrag; fügen Sie nie einen zweiten hinzu. Die Grammatik mit Testvektoren steht in der Spezifikation.
Was als Antwort zählt. HTTP 200 nach höchstens einer Weiterleitung, ein JSON-Content-Type, ein Body, der gegen das Feed-Schema validiert, und ein domain, der die gesuchte Domain nennt. Eine Website, die unbekannte Pfade mit einer HTML-Seite und 200 beantwortet, antwortet nicht, ebenso wenig ein Dokument, das als text/html ausgeliefert wird.
Vertrauen ist eine Eigenschaft der Quelle, nicht eines Claims. Es sagt, was darüber nachgewiesen ist, wer spricht, und nichts darüber, ob eine bestimmte Angabe stimmt. Was daraus folgt, entscheidet, wer die Daten nutzt.
| Stufe | Bedeutung |
|---|---|
| authoritative | Domainkontrolle nachgewiesen und Inhaberschaft der Marke bestätigt. |
| verified | Domainkontrolle nachgewiesen, per TXT-Eintrag oder dadurch, dass die Domain das Dokument ausliefert. |
| unverified | Ein gehosteter Slug ohne Domain, ein Datensatzimport oder ein Community-Beitrag. |
Nur eine Quelle, deren Identität eine Domain ist, kann mehr als unverified sein. verified kommt aus dem Crawl. authoritative nicht, denn kein Crawl kann beweisen, wem eine Marke gehört: Der Betreiber des Index vergibt es, und nur auf Nachweis.
Der Nachweis ist Ihr GS1-Firmenpräfix.
Das GS1-Firmenpräfix der GTINs, die Ihre Quelle unter der Marke veröffentlicht, muss an die Organisation lizenziert sein, die Ihre Domain kontrolliert, wie die öffentliche Abfrage „Verified by GS1“ zeigt. Die URL dieser Abfrage wird als Nachweis bei der Freigabe gespeichert.
Eine Freigabe nennt eine Marke, und jede kann widerrufen werden.
Die Marke wird in ihrer normalisierten Form gespeichert. Eine Quelle kann Freigaben für mehrere Marken halten, und der Betreiber widerruft jede einzeln.
Eine Freigabe überlebt den Nachweis darunter nicht.
Ihre Quelle ist genau so lange
authoritative, wie die Kontrolle über ihre Domain nachgewiesen ist, sie nicht lapsed ist und sie mindestens eine nicht widerrufene Freigabe hält. Verlieren Sie den Domainnachweis oder gehen Sie in Lapse, fällt sie sofort auf das zurück, was der verbleibende Nachweis trägt:verifiedwährend des Lapse, tiefer, wenn auch der Domainnachweis fehlt, ohne dass jemand eingreift. Sobald alle drei wieder gelten, ist sie wiederauthoritative.Sie deckt die Quelle ab, nicht die Marke.
Vertrauen bleibt eine Eigenschaft der Quelle: Eine Freigabe für eine Marke macht jeden Claim Ihrer Quelle
authoritative, auch Claims über Marken, für die sie keine Freigabe hat.
Um sie zu beantragen, veröffentlichen Sie zuerst auf Ihrer eigenen Domain und fragen dann mit dem Antragsformular an, mit Ihrer Domain, der Marke und einer Verified-by-GS1-Abfrage für eine ihrer GTINs. Der Betreiber prüft die GTINs, die Ihre Quelle unter dieser Marke veröffentlicht, in Verified by GS1. Der Antrag ist öffentlich.
Ein Datensatz mit einem bereits vorhandenen key ersetzt den vorigen. Es gibt keinen Update-Endpunkt, denn der Feed ist der Zustand.
Ein key, der aus einem vollständig abgerufenen Feed verschwindet, markiert Ihre Claims dazu als zurückgezogen. Die Entität und ihre Kennung bleiben: Links anderer darauf funktionieren weiter, ebenso die Claims anderer Quellen.
Liest ein Crawl ein Dokument, das eine Ihrer Feed-URLs nicht mehr nennt, wird jeder aktive Datensatz aus diesem Feed sofort zurückgezogen, als wären alle seine keys verschwunden, und die URL wird nicht mehr abgerufen. Die siebentägige Schonfrist weiter unten gilt hier nicht: Eine URL zu streichen heißt, dass die Datei weg ist, und der Index nimmt Sie beim Wort. Wird sie später wieder aufgeführt, kommt sie zurück und wird von vorn gelesen. Liefern Sie das Dokument nach Möglichkeit mit einem ETag aus: Ein 304 heißt, dass sich die Liste nicht geändert hat, also wird nichts stillgelegt.
Eine Zeile über 64 KiB, nicht parsebar oder ungültig, wird übersprungen und gezählt. Weil der key einer übersprungenen Zeile unbekannt ist, zieht ein Feed mit übersprungenen Zeilen sieben Tage lang nichts zurück. Danach werden fehlende keys wie üblich zurückgezogen. Der Zähler ist öffentlich, ein Feed, der still Zeilen verliert, bleibt also nicht still.
Ein Crawl gelingt nur, wenn alles, was das Dokument auflistet, gelesen wurde: ein akzeptables Dokument, und jeder Feed darin antwortet mit 200 oder 304. Ein Feed mit Timeout kostet Sie nicht die anderen (die antwortenden Feeds werden aufgenommen, und bei einem gescheiterten Crawl wird nichts zurückgezogen), aber der Crawl zählt als Transportfehler, und feeds_failed zeigt das in Ihrem Status. Ein völlig gesundes Dokument mit einer dauerhaft toten Feed-URL geht deshalb nach derselben Sieben-Tage-Uhr in Lapse wie eine Domain, die gar nicht mehr antwortet, und verliert dreißig Tage später den Katalog. Eine Feed-URL, die Sie nicht mehr ausliefern, gehört aus dem Dokument entfernt, nicht dem Verfall überlassen.
Ein definitiv negatives Ergebnis, also eine Discovery ohne akzeptables Dokument (kein Eintrag und kein Dokument; ein fehlerhafter, zu langer oder doppelter Eintrag; oder ein Dokument, das nicht 200, nicht JSON, nicht gültig ist, bei domain nicht mehr übereinstimmt oder einen Feed außerhalb seines Hosts nennt), versetzt die Quelle sofort in Lapse. Ein Transportfehler (DNS-Timeout, 5xx, 429, erreichtes Limit, beim Dokument oder bei einem Feed) ändert für sich nichts, aber sieben aufeinanderfolgende Tage, an denen jeder Versuch so endet, versetzen Sie ebenfalls in Lapse; dauerhaft Fehler auszuliefern ist also kein Weg, Ihre Claims einzufrieren.
Dieser Vertrauensvorschuss gehört einem Host, nicht Ihnen. Er gilt nur auf einem Host, auf dem Ihre Quelle bereits verifiziert war. Auf einem Host, auf dem sie nie verifiziert war (ein neuer Slug, ein Host, auf den Sie _prodid gerade umgestellt haben, alles unter Weg 2 und 3), ist jeder Fehler, auch ein Timeout oder ein 5xx, definitiv negativ und versetzt Sie sofort in Lapse. Das ist Absicht: Sonst könnte eine verifizierte Quelle ihren Eintrag auf einen fremden Host richten und daran, ob ihr Lapse heute oder in einer Woche beginnt, ablesen, ob dieser Host erreichbar ist. Ein Hostwechsel kostet Sie dadurch nichts. Der erste erfolgreiche Crawl auf dem neuen Host setzt alles zurück, und ein Lapse bleibt die 30 Tage lang behebbar, bevor etwas zurückgezogen wird.
Eine Quelle in Lapse nimmt keine neuen Claims an, wird Lesern als lapsed angezeigt, und ihr publisher.contact wird benachrichtigt. Ein Crawl einer Quelle in Lapse schreibt nichts, bis er vollständig gelungen ist; erst dann wird der Lapse aufgehoben. Nach 30 Tagen ununterbrochenem Lapse werden Ihre Datensätze und ihre aktiven Claims gemeinsam zurückgezogen und bleiben als Verlauf erhalten. Diese 30 Tage sind Ihr Zeitfenster zur Wiederherstellung; deshalb muss die Kontaktadresse eine sein, die jemand liest.
Zurückkommen erfordert keine Änderung. Liefern Sie dasselbe Dokument und denselben Feed wie immer aus, und alles, was Sie veröffentlichen, wird in dem Moment wieder geltend gemacht, in dem die Discovery gelingt, ob sich ein Byte geändert hat oder nicht: Solange der Index nichts Aktives von Ihnen hält, verzichtet er auf bedingte Anfragen, eine unveränderte Datei ist also nie ein Grund, zurückgezogen zu bleiben.
Jeder Claim, den ein Leser sieht, trägt seen_at: nicht, wann die Angabe irgendwo zuerst veröffentlicht wurde, sondern seit wann diese Quelle diesen Wert ohne Unterbrechung behauptet. Er übersteht jeden erneuten Crawl, der denselben Wert findet, darum geht es. Ein Zurückziehen übersteht er nicht. Bleibt Ihre Quelle länger als 30 Tage in Lapse, beginnt das Datum jeder Angabe ab dem Tag Ihrer Rückkehr neu, weil während der Lücke niemand Überprüfbares dahinterstand. Die zurückgezogenen Zeilen bleiben, also zeigt ?history=1 die Lücke, statt sie zu verbergen; was ein Leser sieht, steht in der Spezifikation.
/source/acme.example zeigt Ihnen, dass etwas nicht stimmt: das Ergebnis des letzten Crawls, welchen Weg die Discovery genommen hat, wie viele Datensätze sich geändert haben, wie viele Zeilen übersprungen wurden, wie viele Feeds nicht lesbar waren und ob Sie in Lapse sind und seit wann. Sie meldet nur, was Ihre Domain veröffentlicht und wann der Index nachgesehen hat, nie, wer einen Crawl angefordert hat.
{
"$type": "org.prodid.source",
"version": 1,
"name": "acme.example",
"kind": "domain",
"trust": "verified",
"verified_by": "dns-txt",
"verified_at": "2026-09-14T09:12:03Z",
"lapsed": false,
"license": "CC0-1.0",
"last_crawl": {
"at": "2026-09-19T06:00:11Z",
"via": "dns-txt",
"document_url": "https://acme.prodid.org/.well-known/prodid.json",
"outcome": "success",
"http_status": 200,
"records_seen": 3,
"records_changed": 1,
"lines_skipped": 0,
"feeds_failed": 0,
"media_failed": 0
}
}Der Typ wird durch Lesen der Bytes bestimmt; Ihr Content-Type ist nur ein Hinweis. Sechs Typen werden gespeichert, sonst nichts: JPEG, PNG, GIF, WebP und AVIF als image, PDF als document. Kein SVG, kein HTML, keine Archive, keine Office-Dateien; ein Datenblatt geht als PDF raus. Der erkannte Typ und das kind des Eintrags müssen übereinstimmen, sonst wird der Eintrag übersprungen.
| Was | Limit |
|---|---|
| Ein Bild | 20 MiB |
| Ein Dokument | 50 MiB |
| Ein Medienabruf | 60 s |
| Medieneinträge in einem Datensatz | 20 |
Die Lizenz wird als String geprüft, bevor etwas abgerufen wird, und sie muss genau eine von sieben SPDX-Kennungen sein: jene, die jedem erlauben, die Datei unverändert weiterzugeben, und genau das tut der Index damit:
CC0-1.0 CC-BY-4.0 CC-BY-SA-4.0 CC-BY-ND-4.0
CC-BY-3.0 CC-BY-SA-3.0 CC-BY-ND-3.0Alles hier gilt pro Eintrag. Ein abgelehnter, zu großer oder unerreichbarer Eintrag kostet diesen Eintrag und sonst nichts: Ihr Datensatz ist nie wegen seiner Medien ungültig, seine übrigen Claims bleiben, und kein Medienfehler versetzt Sie in Lapse. Er wird in media_failed gezählt und beim nächsten Crawl dieses Datensatzes erneut versucht. Eines funktioniert umgekehrt wie bei Feeds: Die Gleicher-Host-Regel gilt hier nicht, Ihre Bilder können also auf einem CDN liegen. Was aufgenommen wird und die Lizenzliste enthalten die Begründung.
Händler, Register, offene Datensätze und Beitragende sind Quellen wie alle anderen. Ihre Claims werden ihnen zugeschrieben und überschreiben Ihre nie; wo Sie sich widersprechen, sind beide Claims mit ihren Quellen nebeneinander sichtbar.