Storefront API
MarkdownMağaza sayfasının ve mağaza sunucusunun istek gönderdiği endpoint'ler.
Sürüm v1. Endpoint yollarının başına eklenecek Sayproof API adresi panelde Entegrasyon ekranında gösterilir.
Kimlik doğrulama
Bölüm başlığı “Kimlik doğrulama”| Çağıran | Yöntem |
|---|---|
| Tarayıcı (mağaza sayfası) | Site anahtarı: okuma isteklerinde ?key= parametresi, yazma isteklerinde X-Sayproof-Site-Key header’ı. İstek doğrulanmış bir alan adından gelmelidir: alan adı Origin header’ından, Origin yoksa Referer header’ından okunur. |
| Mağaza sunucusu | Authorization: Bearer <sunucu anahtarı> header’ı ve ?channel=<kanal kodu> parametresi |
Hiçbir endpoint tarayıcı oturumunu (cookie) kullanmaz; istekler cookie olmadan gönderilir.
Ortak kurallar
Bölüm başlığı “Ortak kurallar”- İstek ve yanıt body’leri JSON biçimindedir.
- Hata yanıtının biçimi tüm endpoint’lerde aynıdır:
{"error": "<kod>", "detail": "<kod>"}.detailde bir cümle değil, koddur; kullanıcıya gösterilecek metne kendi tarafınızda dönüştürülür. Kodların listesi için: Hata kodları. - Dil sırasıyla body’deki
languagealanından (yazma istekleri),?lang=tr|enparametresinden ya da kanalın dilinden belirlenir.Accept-Languageheader’ı dikkate alınmaz. Desteklenmeyen bir dil istenirse kanalın dili kullanılır. - Her yanıt
X-Request-Idheader’ını taşır; destek talebinde bu değeri iletin. - Anahtar, kanal ya da alan adıyla ilgili sorunlarda
403 refusedyanıtı döner vedetailnedeni belirtir (örneğinorigin_unverified: www.markaniz.com,unknown_site_key,channel_inactive).origin_unverifiedayrıntısı isteğin geldiği alan adını taşır. Rate limit aşıldığında429 rate_limiteddöner.
Yorum listesi
Bölüm başlığı “Yorum listesi”GET /v1/reviews/list — yayındaki yorumları, özeti ve zorunlu öğeleri döndürür.
| Parametre | Varsayılan | Kural |
|---|---|---|
key |
Site anahtarı | |
product |
Zorunlu; en fazla 128 karakter | |
scope |
variant |
variant ya da group |
sort |
Pazarın varsayılanı | İzin verilen liste dışındaki değer 400 sort_not_allowed yanıtı alır |
page, page_size |
1, 10 |
page 1–1000, page_size 1–50; aralık dışındaki değerler en yakın sınıra çekilir |
rating |
1–5; aralık dışındaki değer 400 invalid / rating yanıtı alır |
|
verified |
1: yalnızca satın alma kanıtı olan yorumlar |
|
media |
1: yalnızca fotoğraf ya da video içeren yorumlar |
|
q |
Başlık ve metinde arama; en fazla 100 karakter. Tüm kelimeler geçmelidir. Büyük/küçük harf ve ı/i farkı dikkate alınmaz. | |
topic |
Tek kelime (en fazla 40 harf); bu kelimeyle başlayan bir kelime içeren yorumlar (rahat → rahatlık) |
|
lang |
Kanalın dili | tr ya da en |
via |
Script script gönderir. Yorumları kendi kodunuzla okuyorsanız göndermeyin; panelin Mağaza görünümü ekranı bu sayfaları sitenizin kendi tasarımı olarak sayar. |
Yanıt:
{ "reviews": [ { "id": "…", "rating": 5, "title": "…", "body": "…", "author": "Ayşe K.", "anonymous": false, "language": "tr", "published_at": "…", "verified": true, "verification_method": "tokenized_invite", "helpful_count": 3, "unhelpful_count": 1, "aspects": [{ "key": "size", "label": "Beden", "scale": "fit", "value": 2, "position": 0.5, "step_label": "Yeterli" }], "aspect_scores": { "size": 2 }, "aspect_template": "footwear", "media": [{ "id": "…", "kind": "image", "url": "…", "srcset": "… 320w, … 640w, … 1280w", "width": 1280, "height": 960, "alt_text": "", "poster_url": "" }], "seller_response": { "body": "…", "published_at": "…" }, "resolution": { "body": "…", "created_at": "…" }, "origin": "own", "origin_market": "", "experience": "product", "translations": {} } ], "total": 200, "page": 1, "pages": 20, "page_size": 10, "sort": "date", "shared": 0, "ai_summary": null, "sorts": [{ "code": "date", "label": "En yeni" }, { "code": "rating", "label": "Puana göre" }, { "code": "seller", "label": "Satıcı yanıtı olanlar" }], "aggregate": { "count": 200, "average": 4.1, "stars_filled": 4, "distribution": { "1": 5, "5": 120 }, "verified_count": 200 }, "aspects": [{ "key": "size", "label": "Beden", "scale": "fit", "steps": ["Düşük", "Yeterli", "Yüksek"], "average": 2.1, "position": 0.55, "step_label": "Yeterli", "count": 48 }], "topics": [{ "word": "rahat", "count": 31 }], "gallery": [{ "id": "…", "kind": "image", "url": "…", "srcset": "…", "width": 1280, "height": 960, "alt_text": "", "poster_url": "", "review_id": "…", "rating": 5, "author": "Ayşe K.", "anonymous": false }], "media_reviews": 14, "style": "cards", "theme": "warm", "applied": { "q": "", "topic": "", "rating": null, "media": false, "verified": false }, "core": { "method_statement": { "url": "…", "label": "Yorumları nasıl topluyoruz", "required": true }, "sort": { "allowed": ["date", "rating", "seller"], "default": "date", "locked": true }, "verification_badge": { "label": "Doğrulanmış alıcı", "required": true }, "source_label_required": true, "streams_together": true, "resolution_inline": true, "aggregate": { "…": "…" }, "policy_version": 1, "market": "TR" }, "language": "tr", "words": { "verified": "Doğrulanmış alıcı", "…": "…" }, "report_reasons": [{ "code": "suspected_fake", "label": "…" }], "questions_enabled": false, "privacy_url": "https://markaniz.com/kvkk-aydinlatma-metni", "limits": { "media_count": 6, "title_length": 200, "body_length": 5000, "name_length": 120, "alt_text_length": 300, "image_bytes": 12582912, "video_bytes": 209715200, "video_seconds": 60, "reviews_per_call": 20, "order_reference_length": 128, "email_length": 254, "report_note_length": 1000 }}aggregate.stars_filled: dolu yıldız sayısı; yarım değerler yukarı yuvarlanır (4,5 → 5).aspects(üst düzey): basamaklı ölçekli değerlendirme başlıklarının ortalamaları.position0 ile 1 arasındadır,step_labelen yakın basamağın etiketidir. Filtreler bu değerleri değiştirmez.topics: yorumlarda en sık geçen en fazla 5 kelime ve her birinin kaç yorumda geçtiği. Kelimeler en az 4 harfli olmalı ve en az 2 yorumda geçmelidir; değerler doğrudantopicparametresinde kullanılabilir.gallery: ürünün yayındaki yorumlarına eklenmiş ve işlenmesi tamamlanmış en fazla 12 fotoğraf ya da video; en yeni yorumdan başlar. Her öğemediaalanlarını ve ait olduğu yorumunreview_id,rating,authorveanonymousdeğerlerini taşır. Filtreler bu listeyi değiştirmez.media_reviews: fotoğraf ya da video içeren yayındaki yorum sayısı;media=1filtresinin tek başına döndürdüğü yorum sayısıdır. Filtreler bu değeri değiştirmez.style: kanalın panelde seçilen düzeni,cardsya dasidebar.theme: kanalın panelde seçilen tasarımı:warm,trust,editorial,minimal,soft,bold,naturalya danight.applied: uygulanan filtreler.experience:product(ürün yorumu) ya daprocess(siparişi iptal edilen ya da ürünü iade eden müşterinin o aşamaya kadarki deneyimi).processyorumlarıwords.experience_processetiketiyle gösterilmelidir; varsayılan bileşen bu etiketi kendisi gösterir.limits: yorum formunun uyguladığı sınırlar: dosya sayısı (media_count), metin uzunlukları (title_length,body_length,name_length,alt_text_length), dosya boyutları byte olarak (image_bytes,video_bytes), video süresi saniye olarak (video_seconds), tek istekteki ürün sayısı (reviews_per_call), sipariş numarası ve e-posta uzunluğu (order_reference_length,email_length) ve bildirim notu uzunluğu (report_note_length).core.method_statement.url: isteğin kanalı ve dili için geçerli yöntem beyanının adresi (kanal için bağlanan kendi sayfanız ya da Sayproof’un sayfası).- Yanıt
Cache-Control: private, max-age=30header’ını taşır. questions_enabled: markanın soru-cevabı açık mı; ayrıntılar için Soru-cevap.privacy_url: isteğin kanalında panelde girilen aydınlatma metni bağlantısı; girilmemişse boş. Script bu adresi yorum, soru ve cevap formlarının altında Kişisel verilerin işlenmesi hakkında aydınlatma metni bağlantısı olarak gösterir (words.privacy_notice).origin,origin_market:ownmarkanın bu pazardaki yorumudur. Markanızda pazarlar arası paylaşım açıksa (Ayarlar › Yayınlama › Diğer pazarlardan yorumlar) liste aynı ürünün diğer pazarlarınızdaki satın alma kanıtlı yorumlarını da taşır: bu satırlardaoriginsyndicated,origin_marketgeldiği pazardır. Bu yorumlar ortalamaya, puan dağılımına ve yapılandırılmış veriye girmez;sharedlistede kaç tane olduklarını söyler.origin_label,origin_url: kaynağıownolmayan her yorumda hazır etiket metni (sunucu, ziyaretçinin dilinde ve doğru Türkçe ekleriyle yazar; script yalnız gösterir). Pazaryerinden aktarılmış yorumda (origin: "imported") etiket “Trendyol’da satın alındı · Trendyol’dan otomatik aktarıldı” gibidir,origin_urlkaynaktaki yorumun adresidir (yoksa boş) veverifiedher zamanfalse,verification_methodboştur. Bu yorumlarverified_onlysüzgecine girmez, ortalamaya, puan dağılımına ve yorum sayısına katılır, yapılandırılmış veriye ve Google ürün yorumu dosyasına girmez. Ayrıntılar için Pazaryeri yorumları.aggregate.imported_count,aggregate.imported_label: aktarılmış yorum sayısı ve özet satırının hazır metni (“4 yorumun 3’ü Trendyol’dan”); aktarılmış yorum yoksa0ve boş metin.aggregate.verified_countaktarılmış yorumları saymaz.translations(v2 ile gelecek; şu an her yorumda boş nesne{}döner): yapay zekâ paketinde çeviri açıksa yorumun diğer dillerdeki çevirileri, dil koduna göre{"en": {"title", "body"}}. Script, yorum ziyaretçinin dilinde değilse çeviriyi gösterir ve aslını gösterme bağlantısı ekler.ai_summary(v2 ile gelecek; şu an her zamannulldöner): yapay zekâ paketinde yorum özeti açıksa ve ürünün yeterli yorumu varsa özet:text, dayandığı yorum sayısı (review_count), oluşturulma zamanı (created_at) ve öne çıkan konular (topics[]:topic,sentiment,count); yoksanull. Varsayılan bileşen özeti etiketiyle birlikte gösterir; özet bölümü gizlenemez.
Server-side rendering (SSR)
Bölüm başlığı “Server-side rendering (SSR)”GET /v1/ssr — hazır HTML’i, liste yanıtıyla aynı içerikteki state alanını ve yapılandırılmış veriyi döndürür. Parametreler: product, channel, scope, name, lang, sort, style (cards ya da sidebar; başka bir değer 400 invalid / style yanıtı alır), theme (warm, trust, editorial, minimal, soft, bold, natural ya da night; başka bir değer 400 invalid / theme yanıtı alır). Kullanım ve yanıt alanları için: Server-side rendering (SSR).
- Yanıt
ETagveCache-Controlheader’larını taşır: sunucu anahtarıyla gönderilen istekteprivate, max-age=60, site anahtarıyla gönderilen istektepublic, max-age=60.If-None-Matchile gönderilen istekte içerik değişmemişse304döner. - Kanalın kullanımda bir site anahtarı yoksa
409 refused / no_site_keydöner.
Oturum açmış müşteri
Bölüm başlığı “Oturum açmış müşteri”GET /v1/viewer — yalnızca sunucu anahtarıyla kullanılabilir. Müşterinin e-posta adresi X-Sayproof-Customer header’ında gönderilir. Parametreler: product, scope, lang, channel. Yanıttaki state değeri can_write, written ya da none olur; yanıt ayrıca reviews, limits, müşteri yorum yazabiliyorsa token ile products ve marka soru-cevabı açtıysa asker (token, name) alanlarını içerir. Soruyla gösterilecek ad isteğe bağlı X-Sayproof-Customer-Name header’ıyla, UTF-8 percent-encode edilerek gönderilir. Yanıt Cache-Control: no-store header’ını taşır. Ayrıntılar için: Oturum açmış müşteri.
Sipariş detayındaki değerlendirme
Bölüm başlığı “Sipariş detayındaki değerlendirme”GET /v1/viewer/order — oturum açmış müşterinin sipariş detayı sayfası için siparişin ürünlerini ve her birinin yorum durumunu döndürür. Yalnızca sunucu anahtarıyla kullanılabilir; tarayıcıdan site anahtarıyla gönderilen istek 403 refused / server_only yanıtı alır. Müşterinin e-posta adresi X-Sayproof-Customer header’ında gönderilir. Parametreler: order (sipariş numarası, en fazla 128 karakter), channel, lang.
{ "order": "100245", "token": "…", "lines": [ { "line_reference": "1", "variant_key": "URUN-38", "group_key": "URUN", "title": "Koşu ayakkabısı", "aspects": [{ "key": "size", "label": "Beden", "kind": "product", "required": false, "scale": "fit", "steps": ["Düşük", "Yeterli", "Yüksek"] }], "state": "can_write" }, { "line_reference": "2", "variant_key": "CORAP-2", "group_key": "CORAP", "title": "Koşu çorabı", "aspects": [], "state": "pending", "rating": 4 } ], "limits": { "media_count": 6, "body_length": 5000, "…": "…" }, "language": "tr", "theme": "warm", "privacy_url": "https://markaniz.com/kvkk-aydinlatma-metni", "words": { "order_title": "Ürünleri değerlendirin", "…": "…" }}lines[].state:can_write,pending,published,rejected,removed,waitingya daclosed. Anlamları için: Oturum açmış müşteri › Sipariş detayı sayfası.privacy_url: kanalın aydınlatma metni bağlantısı; girilmemişse boş. Script bağlantıyı formların altında gösterir.token: yorum yazılabilen satırlar için tek bir yazma token’ı; yazılabilen satır yoksa boş.aspectsyalnızcacan_writesatırlarında dolu gelir;ratingyalnızca yorumu yazılmış satırlarda bulunur.- Sipariş bulunamazsa ya da başka bir müşteriye aitse yanıt yine
200olur velinesboş döner; yanıttan siparişin var olup olmadığı anlaşılmaz. ordergönderilmezse400 invalid / order,X-Sayproof-Customerheader’ı eksikse ya da geçerli bir adres değilse400 invalid / customerdöner.- Yanıt
Cache-Control: no-storeheader’ını taşır. Rate limitGET /v1/viewerile ortaktır.
“Faydalı” oyu
Bölüm başlığı ““Faydalı” oyu”POST /v1/reviews/<id>/helpful — body: {"vote": "up" | "down" | "none", "visitor_key": "…"}.
{ "vote": "down", "counted": true, "helpful_count": 3, "unhelpful_count": 1 }- Her ziyaretçi bir yorum için tek oy verebilir. Aynı yönde yeniden oy verilirse
counted: falsedöner; yön değiştirilirse oy yeni yöne taşınır;noneoyu geri alır (vote: null). visitor_keyyalnızca tekrarları ayıklamak için kullanılır; rate limit IP adresine göre uygulanır.
Yorum bildirme
Bölüm başlığı “Yorum bildirme”POST /v1/reviews/<id>/report — body: {"reason": "…", "note": "…", "visitor_key": "…"}. Gerekçe, liste yanıtındaki report_reasons alanından seçilir; liste dışındaki değer 400 invalid_reason yanıtı alır. Not en fazla 1000 karakter olabilir. Başarılı istekte 201 {"id"} döner. Yalnızca yayındaki yorumlar bildirilebilir. Aynı ziyaretçinin (visitor_key, gönderilmezse IP adresi) aynı yoruma ilişkin açık bir bildirimi varsa yeni kayıt oluşturulmaz; yanıt mevcut bildirimin id değerini döndürür.
Ürün görüntülenmesi
Bölüm başlığı “Ürün görüntülenmesi”POST /v1/views?key=… — body, text/plain içerik türüyle gönderilen JSON’dur: {"product": "…", "scope": "variant" | "group"}. Script ayrıca yorumların nasıl gösterildiğini de bildirir: shown (default varsayılan bileşen, coded görünümü kodda seçilmiş, headless), kodda seçildiyse style ve theme, ve yorum alanının piksel genişliği width. Sayproof genişliği yalnızca dört aralıktan birine çevirerek saklar; bu alanlar yoksa ya da geçersizse yalnızca görüntülenme sayılır. Başarılı istekte body içermeyen 204 döner. Script bu isteği kendisi gönderir; headless kullanımda da script sayfada yüklü olduğu sürece ayrıca göndermeniz gerekmez. Otomatik istemcilerden (bot, bağlantı önizleme aracı) ve önceden yükleme (prefetch) isteklerinden gelen görüntülenmeler sayılmaz. Uygulama içi tarayıcılar (örneğin Pinterest, Telegram, Slack, Discord) ve adında “bot” geçen CUBOT gibi telefon markaları sayılır. Önceden hazırlanan (prerender) bir sayfada script, görüntülenmeyi sayfa gerçekten gösterildiğinde bildirir.
Yöntem beyanı
Bölüm başlığı “Yöntem beyanı”GET /v1/method-statement?key=…&lang=tr|en — herkese açık sayfa; alan adı doğrulaması gerektirmez (yeni sekmede açılır). format=json parametresiyle makine tarafından okunabilir biçimde döner. Sayfa, site anahtarının kanalına ait beyanı gösterir; metin o kanalın kurallarından ve yayınlama yönteminden hazırlanır ve panelde o kanal için gösterilen metinle aynıdır.
Yorum yazma akışının endpoint’leri
Bölüm başlığı “Yorum yazma akışının endpoint’leri”Aşağıdaki endpoint’leri script kullanır. Yorum yazma akışı headless kullanımda da script’te kaldığı için bu endpoint’lere doğrudan istek göndermeniz gerekmez.
| Endpoint | İşlevi |
|---|---|
POST /v1/eligibility |
Sipariş numarası ve e-posta adresiyle uygunluğu denetler. Müşteri uygunsa tek kullanımlık bir yazma token’ı döner; değilse tek ve genel bir ret yanıtı döner. |
POST /v1/eligibility/token |
Davet, alışveriş deneyimi daveti ya da düzeltme bağlantısındaki token’ı doğrular. Yanıttaki mode değeri write, feedback ya da revise olur. feedback yanıtındaki ürünler değerlendirme başlığı içermez. revise yanıtı düzeltilecek yorumu, yazanın girdiği adı (review.author_name), adın sitede gizlenip gizlenmediğini (review.hide_name) ve yoruma ekli dosyaları (review.media: id, kind) içerir. Bağlantı başka bir pazarın kanalında açılırsa 403 token_refused / token_foreign_market döner. |
POST /v1/media |
Fotoğraf ya da video yükler (jpeg, png, webp: en fazla 12 MB; mp4, mov: en fazla 200 MB ve 60 saniye). Dosya güvenlik taramasından geçirilir; konum ve cihaz bilgileri silinir. Süresi sınırı aşan video yüklenirken reddedilir: 422 refused / video_too_long: 60. 3840×2160’tan (dikeyde 2160×3840) büyük, saniyede 60 kareden fazla ya da H.264, HEVC, MPEG-4, VP9, AV1 dışında kodlanmış video da reddedilir. Yanıt dosyanın adresini taşımaz; dosya ancak eklendiği yorum yayındayken herkese açık adreste durur. |
POST /v1/reviews |
Yorumları gönderir (bir istekte en fazla 20 ürün). Ürün daveti ve alışveriş deneyimi daveti token’larını kabul eder; alışveriş deneyimi daveti token’ıyla yazılan yorum experience: "process" olarak kaydedilir. Her satır isteğe bağlı author_name (en fazla 120 karakter) ve hide_name (true ya da false; varsayılan false) alanlarını taşıyabilir. hide_name: true olduğunda ad sitede, yapılandırılmış veride ve Google dosyasında her sözcüğün ilk harfi ile *** olarak görünür (Ayşe Kaya yerine A*** K***); adın tamamı yalnızca markanın panelinde görünür. hide_name mantıksal değer değilse 400 invalid / hide_name döner. |
POST /v1/reviews/revise |
Reddedilen yorumu düzeltilmiş hâliyle yeniden gönderir. Body’deki kept_media, yorumda kalacak mevcut dosyaların kimlik listesidir; alan gönderilmezse mevcut dosyaların hepsi kalır. Kalan ve yeni eklenen dosyalar birlikte en fazla 6 olabilir. author_name ve hide_name gönderilirse yorumdaki değerlerin yerine geçer (boş author_name adı siler); gönderilmezse mevcut değerler korunur. |
Rate limit değerleri için: Limitler.
Soru-cevap
Bölüm başlığı “Soru-cevap”Marka panelde Ayarlar › Yayınlama › Soru-cevap seçeneğini açtığında kullanılabilir; kapalıyken üç endpoint de 403 refused / questions_disabled döner ve liste yanıtındaki questions_enabled değeri false olur. Script bölümü yalnızca bu değer true iken yükler.
| Endpoint | İşlevi |
|---|---|
GET /v1/questions |
Ürünün yayındaki sorularını ve her sorunun yayındaki cevaplarını döndürür. Parametreler: key, product (zorunlu), scope (variant ya da group), page (1–1000), page_size (varsayılan 5, en fazla 20), lang. Sunucu anahtarıyla channel parametresiyle de okunabilir. |
POST /v1/questions |
Ziyaretçinin sorusunu kaydeder. Body: product, scope, name (isteğe bağlı, en fazla 120 karakter), email (isteğe bağlı; yoksa cevap geldiğinde e-posta gitmez), body (zorunlu, en fazla 1000 karakter), hide_name (isteğe bağlı mantıksal değer; true ise ad sitede her sözcüğün ilk harfi ile *** olarak görünür), language. Oturum açmış müşteride name ve email yerine GET /v1/viewer yanıtındaki asker.token değeri asker alanında gönderilir; ad ve e-posta adresi token’dan okunur. Satın alma gerekmez. Başarılı istekte 201 {"id", "state"} döner. |
POST /v1/questions/<id>/answers |
Ürünü satın almış müşterinin cevabını kaydeder. Yazma token’ı X-Sayproof-Token header’ında gönderilir; davet ya da sipariş doğrulamasıyla alınan token geçerlidir, yorum yazmak için kullanılmış olması cevap yazmayı engellemez. Body: body (zorunlu, en fazla 2000 karakter), name (isteğe bağlı), hide_name (isteğe bağlı mantıksal değer; true ise ad sitede her sözcüğün ilk harfi ile *** olarak görünür), language. Başarılı istekte 201 {"id", "state"} döner. |
GET /v1/questions yanıtı:
{ "questions": [ { "id": "…", "author": "Deniz", "body": "Geniş ayağa uyar mı?", "published_at": "…", "answers": [ { "id": "…", "kind": "brand", "author": "Örnek Marka", "verified": false, "body": "…", "published_at": "…" }, { "id": "…", "kind": "buyer", "author": "Ali", "verified": true, "body": "…", "published_at": "…" } ] } ], "total": 4, "page": 1, "pages": 1, "page_size": 5, "limits": { "question_length": 1000, "answer_length": 2000, "name_length": 120, "email_length": 254 }, "language": "tr"}- Sorular pazara göre birleştirilir: aynı pazardaki kanallarda sorulan sorular birlikte gösterilir. En yeni yayınlanan soru önce gelir; cevaplar yayına alınma sırasıyla listelenir.
kind:brand(markanın cevabı;authorkanalın marka adıdır) ya dabuyer(ürünü satın almış müşterinin cevabı;verified: true, “Doğrulanmış alıcı” etiketiyle gösterilir). Sorunun ve cevabın e-posta adresi yanıtta yer almaz.- Soru ve müşteri cevabı yayına çıkmadan önce onaylanır. Kişisel bilgi, küfür ya da sağlık iddiası içeren metin reddedilmez, onaya düşer. Yayınlama yöntemi Otomatik ya da Karma ise ve metin bu kontrollerden geçerse kendiliğinden yayınlanır.
- Doğrulama eksikse
400 invaliddöner vedetailalanı nedeni belirtir:body_required,body_too_long,email_invalid,email_too_long,name_too_long,asker_too_long,product_required,product_too_long. askertoken’ının süresi (1 saat) dolduysa403 token_refused / asker_expired, token geçersizse ya da başka bir markaya aitse403 token_refused / asker_invaliddöner.- Token’ın siparişinde sorunun ürünü (aynı varyant ya da aynı ürün grubu) yoksa
403 token_refused / not_a_buyerdöner. Token yoksa401 token_required; soru yayında değilse ya da başka pazarınsa404 not_founddöner. - Cevap yayına çıktığında, soruda e-posta adresi varsa soruyu soran kişiye markanın adıyla bir e-posta gider. Adres, markanın e-posta almak istemeyenler listesindeyse e-posta gönderilmez.
GET /v1/questionsyanıtıCache-Control: private, max-age=30header’ını taşır.
Örnek istekler
Bölüm başlığı “Örnek istekler”Yorum listesini komut satırından denemek (istek doğrulanmış bir alan adından geliyormuş gibi Origin header’ı eklenir):
curl -s "https://api.sayproof.example/v1/reviews/list?key=SITE-ANAHTARINIZ&product=URUN-38&sort=date&page=1&lang=tr" \ -H "Origin: https://www.markaniz.com"Tarayıcıdan yorum bildirmek:
export async function reportReview(reviewId, reason, note) { const answer = await fetch(`https://api.sayproof.example/v1/reviews/${encodeURIComponent(reviewId)}/report`, { method: "POST", credentials: "omit", headers: { "Content-Type": "application/json", "X-Sayproof-Site-Key": "SITE-ANAHTARINIZ" }, body: JSON.stringify({ reason, note }), }); if (answer.status === 201) return answer.json(); const problem = await answer.json().catch(() => ({})); throw new Error(problem.detail || problem.error || `sayproof_report_${answer.status}`);}