İçeriğe geç

Admin API

Markdown

Panelin kullandığı yönetim endpoint'lerine sunucu anahtarıyla istek gönderilmesi; izinler ve ortak liste sözleşmesi.

Panelin kullandığı endpoint’lere (/admin/v1/…) sunucudan sunucuya da istek gönderilebilir; örneğin yorumları kendi veri ambarınıza aktarmak ya da denetim raporunu otomatik olarak oluşturmak için.

GET https://api.sayproof.example/admin/v1/reviews?status=published
Authorization: Api-Key sp_<önek>_<gizli>

Anahtarın hangi endpoint’leri kullanabileceği izinlerine bağlıdır:

Anahtar izni Kapsadığı işlemler
Yorumları okuma (read) Yorumları, davetleri, gönderim ve bağlantı kayıtlarını ve istatistikleri görüntüleme
Yorumlara karar verme (moderate) Okuma işlemleri ile onay, ret ve toplu işlem
Dosya indirme (export) Okuma işlemleri ile denetim raporu, işlem geçmişi ve dosya dışa aktarımları (CSV, Excel, JSON)
Ayarları değiştirme (write) Okuma işlemleri ve ayarlar. Bu izni yalnızca Sayproof ekibi verebilir.
Sayfayı sunucuda hazırlama (ssr) Yalnızca SSR ve oturum açmış müşteri endpoint’leri
Sipariş gönderme (orders) Yalnızca sipariş ve teslimat aktarımı endpoint’leri (/v1/ingest/orders, /v1/ingest/deliveries)
  • Panelden oluşturulan sunucu anahtarları “Sipariş gönderme” (orders) ve “Sayfayı sunucuda hazırlama” (ssr) izinlerini taşır ve Admin API’yi kullanamaz. Panel oturumunda POST /admin/v1/channels isteğine {"kind": "api_key", "label": "…"} gönderilip scopes verilmediğinde de anahtar bu iki izinle oluşturulur. Panel izin seçtirmez; okuma, karar verme ya da dosya indirme izni olan bir anahtar, panel oturumunda aynı isteğe scopes eklenerek oluşturulur (örneğin "scopes": ["read", "export"]). Boş liste 400 invalid / scopes_required, tanınmayan izin 400 invalid / unknown_scope: <izin> döner. Ayarları değiştirme (write) iznini yalnızca Sayproof ekibi verebilir; markanın panelinden istendiğinde 400 invalid / scope_reserved: write döner.
  • Kullanıcı, kanal, anahtar, kişisel veri talebi ve sipariş bağlantısı endpoint’leri hiçbir anahtarla kullanılamaz; bu işlemler yalnızca panel oturumunda ve kullanıcının rolüne göre yapılabilir. Böylece ele geçirilen bir anahtarla yeni anahtar oluşturulamaz, kullanıcı eklenemez ve kişisel veri talebi işlenemez. Bu endpoint’lere anahtarla istek gönderildiğinde 403 döner: kullanıcı, kanal, anahtar ve kişisel veri talebi endpoint’lerinde forbidden / scope_missing; sipariş bağlantısı endpoint’lerinde anahtarın write izni varsa forbidden / panel_session_required, yoksa forbidden / scope_missing.
  • Davet gönderim ayarları (invite_delivery, reminder_delivery, webhook_url, support_url, sender_address) da yalnızca panel oturumunda değiştirilebilir. POST /admin/v1/settings isteği bu alanlardan birini anahtarla değiştirmeye çalışırsa 403 refused / panel_session_required yanıtı alır; diğer ayarlar değiştirilebilir.
  • İzin dışındaki istekler 403, kimlik bilgisi içermeyen ya da geçersiz anahtarla gönderilen istekler 401 yanıtı alır. Anahtarla yapılan her değişiklik İşlem geçmişi ekranına anahtarın adıyla kaydedilir. Kişisel veri gösteren okumalar (yorum ayrıntısı, yorum geçmişi, davet ve mesaj kayıtları, sorular, e-posta adresiyle arama, ret listesi sorgusu) da İşlem geçmişi › Kişisel veri erişimleri sekmesine anahtarın adıyla yazılır.
Endpoint İzin İşlevi
GET /admin/v1/reviews read Yorum listesi; satırlar katalogdaki ürün adını product_name olarak taşır (katalogda yoksa boş). q başlıkta, yorum metninde, ürün adında ve kodunda, sipariş numarasında, yazanın adında ve e-posta adresinde arar; tam yorum kimliği verilirse o yorumu döner. ?export=csv, ?export=xlsx ya da ?export=json ile aynı alanları taşıyan CSV, Excel ya da JSON dosyası döner (export izni gerekir). Satırlardaki flag_open, yorumda karar bekleyen bir otomatik kontrol bulgusu olduğunu söyler; source, pazaryerinden aktarılan yorumda {"platform", "name"} (örneğin {"platform": "trendyol", "name": "Trendyol"}), diğer yorumlarda null olur. entry_point=import yalnız aktarılan yorumları listeler.
GET /admin/v1/reviews/<id> read Yorum ayrıntısı: yazanın girdiği ad (author, her zaman tam ad) ve yazan adının sitede gizlenmesini isteyip istemediği (name_hidden), satın alma kanıtı, geçmiş, otomatik kontroller, bildirimler ve yapılabilecek işlemler (available_events). Fotoğraf ve video adresleri (media[].url, poster_url, srcset) aşağıdaki dosya endpoint’ini gösterir.
GET /admin/v1/reviews/<id>/media/<dosya kimliği>/<dosya adı> read Yorumun fotoğraf ya da videosu (özgün dosya, küçük boyutlar, video kapağı). Yorum yayında olmasa da açılır; yanıt önbelleğe alınmaz (Cache-Control: private, no-store) ve Range header’ı ile parça parça istenebilir. Bilinmeyen dosya ya da başka bir yorumun dosyası 404 not_found döner.
DELETE /admin/v1/reviews/<id>/media/<dosya kimliği> moderate Body {"reason"}: yorumun tek bir fotoğrafını ya da videosunu kaldırır. reason personal_data, profanity, data_subject_request ve legal_order değerlerinden biridir (aynı liste GET /admin/v1/reasons yanıtındaki review_media_removal altında ve yorum ayrıntısındaki media_removal_reasons içindedir); gerekçe yoksa ya da tanınmıyorsa 400 invalid / reason_required ya da 400 invalid / reason döner. Dosya hem herkese açık hem kapalı alandan kalıcı olarak silinir; yorumun metni, puanı ve durumu değişmez. Yanıt 204’tür. Kaldırma yorumun geçmişine ve İşlem geçmişi’ne yazılır. Bilinmeyen, daha önce kaldırılmış ya da başka bir yorumun dosyası 404 not_found döner.
POST /admin/v1/reviews/<id>/transition moderate Body {"event", "reason"}: onay, ret, gizleme, kaldırma gibi işlemler
GET /admin/v1/moderation/queue moderate Onay bekleyen yorumlar; product_name, source ve q araması yorum listesindekiyle aynı. channel=<kanal kodu> verilirse liste ve counters yalnızca o kanalın yorumlarını kapsar; counters.elsewhere (reviews, responses) diğer kanallarda onay bekleyen yorum ve satıcı yanıtı sayısıdır (channel verilmezse ikisi de 0).
POST /admin/v1/moderation/bulk moderate Body {"ids", "action": "approve" | "reject", "reason"}; tek istekte en fazla 200 yorum. Onay beklemeyen yorumlar değiştirilmeden atlanır. Yanıt {"count", "skipped"}: işlenen ve atlanan yorum sayısı.
GET /admin/v1/reviews/<id>/trace export Yorumun dosyası: {"review", "timeline"}. timeline satırları yorumun ve satıcı yanıtının adımlarını, bildirimleri, çözüm notunu ve ret bildirimlerini (subject_type: "notice") zaman sırasıyla taşır. ?format=csv|xlsx|json dosya olarak indirir ve İşlem geçmişi’ne review_history.downloaded yazar. CSV ve Excel’in yorum bölümünde Panelde aç satırı paneli bu yorum açık hâlde açan adresi taşır; JSON’da bu alan yoktur.
POST /admin/v1/reviews/<id>/reports/resolve moderate Body {"note"} (isteğe bağlı, en fazla 1000 karakter): yorumun açık bildirimlerini kapatır. Yanıt {"closed"} kapatılan bildirim sayısıdır.
GET /admin/v1/reasons read Gerekçe listeleri, istenen dilde; review_media_removal tek bir fotoğrafı ya da videoyu kaldırma gerekçelerini taşır
GET /admin/v1/metrics, GET /admin/v1/insights read İstatistikler. channel=<kanal kodu> verilirse sayılar yalnızca o kanalı kapsar; tanınmayan kanal kodu 400 invalid / channel alır. GET /admin/v1/insights isteğinde market ile birlikte verilen kanal o pazara ait değilse 400 invalid / channel_market_mismatch döner. GET /admin/v1/insights yanıtındaki ai alanı yapay zekâ paketinin dönem özetidir (v2 ile gelecek; şu an null döner).
GET /admin/v1/invites, GET /admin/v1/send-logs read Davetler ve mesaj kayıtları. Davet listesinde sent=1 yalnızca e-postası gönderilmiş davetleri getirir; channel=<kanal kodu> verilirse liste ve counters o kanalın siparişleriyle sınırlanır. Mesaj kayıtlarında q alıcının adresinde de arar; channel_kind (email ya da webhook; whatsapp v2 ile gelecek, şu an bu yolla mesaj gönderilmez) gönderim yoluna göre süzer; channel=<kanal kodu> liste ve counters’ı o kanalın mesajlarıyla sınırlar (davet siparişin, ret bildirimi yorumun, cevap bildirimi sorunun kanalına göre). Müşterinin kişisel verileri KVKK talebiyle silinmişse recipient boş, recipient_erased true döner. Davetlerin counters.conversion değeri gönderilmiş davetlerden en az bir ürünü yorumlanmış olanların oranıdır.
POST /admin/v1/invites/retry write “Gönderilemedi” durumundaki davetleri yeniden sıraya alır. Body isteğe bağlıdır: {"ids": […]} (en fazla 500 davet) ve {"channel": "<kanal kodu>"} (yalnızca o kanalın davetleri); ikisi de gönderilmezse tümü. Bağlantısının süresi dolmuş davetler atlanır. Yanıt {"queued", "expired"}.
GET /admin/v1/diagnostics read Bağlantı kayıtları
POST /admin/v1/opt-outs/check read Body {"addresses": […]} (tek istekte en fazla 1.000 adres): listedeki adreslerden e-posta almak istemeyenleri döndürür: {"opted_out": [{"address", "channel_kind", "reason", "created_at"}]}. Telefon numarası uluslararası (+905321112233) ya da kanallarınızın pazarındaki yerel yazımla (0532 111 22 33) verilebilir; yanıtta gönderdiğiniz yazım döner.
GET /admin/v1/opt-outs/export export E-posta almak istemeyenler listesinin tamamını indirir; ?format=csv (varsayılan), ?format=xlsx ya da ?format=json. Dosya adresin kendisini değil, küçük harfe çevrilmiş e-posta adresinin SHA-256 değerini taşır (address_hash, channel_kind, reason, created_at). WhatsApp satırlarındaki (v2 ile gelecek; şu an liste telefon satırı içermez) telefon numaraları Sayproof’a özgü anahtarlı bir karmayla saklanır ve dosyada bu değerle yer alır; telefon listenizi eşleştirmek için POST /admin/v1/opt-outs/check ucunu kullanın. Her indirme İşlem geçmişi’ne kaydedilir.
GET /admin/v1/policies read Markanın gördüğü pazar kuralı sürümleri (profiles; Sayproof kuralları ve markanın kendi sürümleri, own, in_force, scheduled) ve pazar başına sınırlar (limits). channel=<kanal kodu> verilirse yalnızca o kanalın pazarının ve o kanalın kuralları döner. Yeni sürüm (POST) yalnızca panel oturumunda, “Pazar kurallarını yönetebilir” izniyle açılır: Kuralların güncellenmesi.
GET /admin/v1/method-statement read Her açık kanal ve dil için yöntem beyanı satırları (rows) ve kendi sayfanız için kullanılabilecek doğrulanmış alan adları (domains). Her satır channel, channel_label, market, language, state, external_url, hosted_url, effective_url, current_fingerprint, confirmed ve beyan metnini (statement) taşır. ?channel=<kanal kodu>&lang=tr tek kanalın beyanını ve kendi sayfanızın durumunu döner. Tanınmayan kanal kodu 400 invalid / channel alır.
POST /admin/v1/method-statement, POST /admin/v1/method-statement/confirm write Kendi sayfanızın adresini kaydeder: body {"channel", "language", "external_url"}; boş external_url bağlantıyı Sayproof sayfasına döndürür. Onay: body {"channel", "language", "fingerprint"}; fingerprint satırdaki current_fingerprint değeridir, metin bu arada değiştiyse 409 statement_changed döner. Tanınmayan kanal kodu 400 invalid / channel alır.
POST /admin/v1/audit-file export Body {"market", "channel", "start", "end"}: denetim raporunu oluşturur ve saklar. market ve channel boşsa rapor bütün kanalları, yalnız market verilirse o pazarın bütün kanallarını, channel verilirse yalnızca o kanalı kapsar; pazar kanaldan alınır. Tanınmayan kanal kodu 400 invalid / channel, kanalın pazarıyla uyuşmayan market 400 invalid / channel_market_mismatch alır. Saklanan rapor ve dosya adı kanal kodunu taşır; önceki raporlar listesi channel filtresiyle süzülür.
GET /admin/v1/audit-file/<id>?format=json|csv|xlsx export Saklanan raporu indirir; X-Sayproof-Fingerprint header’ı doğrulama kodudur. CSV ve Excel’de kaldırılan ve gizlenen yorumların satırlarında Panelde aç sütunu bulunur; Excel’de adresler tıklanabilir.
GET /admin/v1/audit-log export İşlem geçmişi. Paneldeki İndir menüsü dosyayı POST /admin/v1/audit-log/export ile Sayproof’a ürettirir: body {"format", "title", "filters", "columns", "labels", "changes"}. Satırlar sunucuda, listedeki filtrelerin (filters) aynısıyla bu kayıtlardan okunur; en fazla 10.000 kayıt. columns sekiz sütunun adını, labels işlem, rol ve hedef kodlarının ekrandaki adlarını (action, role, target) ve system sözcüğünü, changes kayıt numarasına göre Ne değişti metnini taşır; son sütun işlemin kodudur. İndirme aynı istekte İşlem geçmişi’ne audit_log.downloaded işlemi olarak biçimi, satır sayısı ve dosyanın SHA-256 hash’iyle (fingerprint) kaydedilir. Bozuk istek 400 invalid / rows, 10.000’i aşan kayıt 400 invalid / rows_over_limit döner.
GET /admin/v1/access-log export Kişisel veri erişimleri (İşlem geçmişi › Kişisel veri erişimleri). Satırlar action (review.viewed, reviews.searched, review_history.viewed, invites.listed, send_logs.listed, questions.listed, question.viewed, subject_requests.listed, subject_request.viewed, subject_request.previewed, users.listed, opt_out.checked, imported_reviews.listed), actor_id, actor_role, via (session, api_key, support, console), target_type, target_id, count (o okumada dönen ve kişisel veri taşıyan kayıt sayısı) ve at taşır. Süzgeçler action, actor, via; q kişide ve kayıt numarasında arar. Kayıtlar değiştirilemez ve 365 gün sonra silinir.
GET|POST /admin/v1/invite-templates write Davet e-postası şablonları. Satırlar channel alanını taşır (kanal kodu; tüm kanallar için hazırlanmış şablonda boş). Kayıtta channel verilirse şablon yalnız o kanalın siparişlerinde kullanılır ve market kanaldan alınır; tanınmayan kanal kodu 400 invalid / channel alır.
GET /admin/v1/questions read Soru listesi. Süzgeçler: state, market, channel, unanswered=1, answers_waiting=1; q soru metninde, soranın adında ve e-posta adresinde, ürün kodunda arar. Yanıt ayrıca counters (waiting, unanswered, answers_waiting) ve markanın soru-cevabı açık mı (enabled) bilgisini taşır.
GET /admin/v1/questions/<id> read Soru ayrıntısı: soranın adı (asker_name, tam ad) ve adının sitede gizli kalıp kalmayacağı (name_hidden), cevaplar (her biri author_name ve name_hidden taşır), her cevabın soran kişiye giden e-postasının sonucu (notice), yapılabilecek işlemler (available_events) ve geçmiş (ledger)
POST /admin/v1/questions/<id>/transition, POST /admin/v1/answers/<id>/transition moderate Body {"event", "reason"}: onay, ret, yeniden inceleme, gizleme ve yeniden gösterme
POST /admin/v1/questions/<id>/answer moderate Body {"body"}: yayındaki soruya marka cevabı yazar ve hemen yayınlar; yanıt 201 ile cevabın satırıdır. Cevap denetimden geçmezse 409 answer_refused (text_steering, text_health_claim, text_personal_data, text_profanity, question_not_published).
POST /admin/v1/reviews/<id>/seller-response/draft moderate Yapay zekâ paketiyle satıcı yanıtı taslağı (v2 ile gelecek; şu an 409 seller_response_refused döner, detail ai_package_off ya da ai_feature_closed): body {"tone"} isteğe bağlı (formal ya da warm; verilmezse markanın varsayılan tonu), yanıt {"draft"}. Taslak kaydedilmez.
GET /admin/v1/ai read Yapay zekâ paketinin durumu (v2 ile gelecek; şu an 404 döner). Paket talebi POST /admin/v1/ai/requests de v2 ile gelecek; şu an 404 döner.
GET|POST /admin/v1/settings write Ayarlar. Yanıttaki time_zone, gönderim saatlerinin uygulandığı saat dilimidir (örneğin Europe/Istanbul). Diğer alanlar arasında questions_enabled, reply_tone (formal ya da warm), ai_translation_enabled, ai_summary_enabled (bu üçü v2 ile gelecek; şu an kaydedilir ama etkisi yoktur), syndication_enabled, reminder_consent (not_required ya da required) ve kurulumda seçilebilen gönderim yolları (deliveries) bulunur. Gönderim yolu alanları (invite_delivery, reminder_delivery, webhook_url, support_url, sender_address) yalnızca panel oturumunda değiştirilir; anahtarla 403 refused / panel_session_required. Kurulumda kapalı bir yol seçilirse 400 invalid / invite_delivery_unavailable ya da reminder_delivery_unavailable.

Kişisel veri talebi endpoint’leri hiçbir anahtarla kullanılamaz; yalnızca panel oturumunda ve “KVKK taleplerini yürütebilir” izni olan kullanıcıyla çalışır. Talep kaydı müşterinin e-posta adresini düz olarak saklamaz; erişim talebinde hazırlanan verilerin kopyası da saklanmaz.

Talep satırları (GET /admin/v1/subject-requests listesindeki satırlar ve talep yanıtları) can_copy alanını taşır. Değer true ise talep tamamlanmış bir erişim talebidir ve kopyası yeniden alınabilir.

POST /admin/v1/subject-requests/<id>/copy, tamamlanmış bir erişim talebinin kopyasını güncel kayıtlardan yeniden hazırlar. Body’de talepteki müşterinin e-posta adresi gönderilir:

POST https://api.sayproof.example/admin/v1/subject-requests/<id>/copy
Content-Type: application/json
{"identifier": "ayse@ornek.com", "format": "xlsx"}

format gönderilmezse yanıt JSON gövdesidir; csv, xlsx ya da json gönderilirse aynı içerik dosya olarak döner (CSV ve Excel düzeni: Erişim dosyası).

Yanıt Anlamı
200 Talebin bilgileri (id, kind, state, received_at, completed_at, affected_reviews, purged_media) ile export ve export_details alanları. Talebe yazılan not ve talebi işleyen kullanıcı kopyaya girmez; içerik için: Erişim dosyası.
400 invalid / identifier_required identifier gönderilmemiş ya da boş
400 identifier_mismatch Adres, talep kaydındaki adresle eşleşmiyor; kopya verilmez
400 invalid / format format değeri csv, xlsx ya da json değil
404 not_found Bu kimlikte bir talep yok
409 not_copyable Talep tamamlanmış bir erişim talebi değil

Her başarılı istek İşlem geçmişi’ne subject_request.copied işlemiyle kaydedilir; ekranda “KVKK erişim talebinin kopyası indirildi” olarak görünür.

Her talebin kaydı GET /admin/v1/subject-requests/<id> ile okunur; ?format=csv, ?format=xlsx ya da ?format=json kaydı dosya olarak indirir. Bu indirme İşlem geçmişi’ne subject_request.downloaded işlemiyle (“KVKK talebinin kaydı indirildi”) yazılır.

Akinon, Shopify ve WooCommerce gibi platformlardan sipariş okuyan bağlantıların endpoint’leri hiçbir anahtarla kullanılamaz; yalnızca panel oturumunda ve “Ayarları değiştirebilir” izni olan kullanıcıyla çalışır. Paneldeki karşılığı ve okuma kuralları: Akinon siparişleri, Shopify siparişleri, WooCommerce siparişleri.

Endpoint İşlevi
GET /admin/v1/order-sources Bağlantılar (items) ve hazır bağlantısı olan platformlar (platforms; her platformun bağlantı alanları fields içinde)
POST /admin/v1/order-sources Bağlantı kurar. Body: platform, channel ve platformun bağlantı alanları (Akinon: base_url, remote_channel, username, password; Shopify: base_url, client_secret, isteğe bağlı client_id; WooCommerce: base_url, consumer_key, consumer_secret); isteğe bağlı backfill_days (1–365, varsayılan 30), interval_minutes (5–1440, varsayılan 15) ve enabled
POST /admin/v1/order-sources/check Kaydetmeden dener. Body kurulumla aynıdır, channel gerekmez.
GET|PATCH|DELETE /admin/v1/order-sources/<id> Bağlantıyı gösterir, değiştirir (enabled, interval_minutes, backfill_days ve platformun bağlantı alanları; giriş bilgileri yalnızca gönderilirse değişir, base_url başka bir adrese değişirse giriş bilgileri de yeniden gönderilmelidir) ya da kaldırır
POST /admin/v1/order-sources/<id>/check Kayıtlı bilgilerle dener
POST /admin/v1/order-sources/<id>/run Okumayı hemen başlatır ve 202 döner; duraklatılmış bağlantıda 409 source_inactive, kanal kapalıyken 409 channel_inactive

Yanıtlarda giriş bilgileri (parola, Client secret, Consumer key ve Consumer secret gibi) hiçbir zaman yer almaz; giriş bilgisi olmayan alanlar values içinde döner, has_credentials alanı kayıtlı giriş bilgisi olup olmadığını gösterir. channel_active bağlantının kanalının açık olup olmadığını bildirir; kanal kapalıyken bağlantı okuma yapmaz. Deneme yanıtı müşteri e-postasını içermez, yalnızca var olup olmadığını (has_email) bildirir:

{
"orders": 3,
"complete": true,
"skipped": {"status_unknown": 1},
"sample": [
{"external_id": "100234", "placed_at": "2026-09-28T10:12:00+00:00", "payment_state": "paid", "lines": 2, "states": ["delivered"], "has_email": true}
]
}

skipped okunamayan siparişleri nedene göre sayar: order_incomplete (numarası ya da tarihi eksik), status_unknown (durumu tanınmıyor), line_incomplete (ürün satırında ürün kodu eksik), order_without_lines (okunabilen ürün satırı yok) ve yalnızca Shopify’da lines_truncated (50’den fazla ürün satırı var; ilk 50 satır okundu). Bağlantının son okuma özetinde (last_report.skipped) Sayproof’a kaydedilemeyen siparişler order_refused ile sayılır.

Pazaryerlerinden yorum alan bağlantıların endpoint’leri hiçbir anahtarla kullanılamaz; yalnızca panel oturumunda ve “Ayarları değiştirebilir” izni olan kullanıcıyla çalışır. Yorumları listeleyen ve kaldıran iki endpoint de hiçbir anahtarla kullanılamaz; yalnızca panel oturumunda ve “KVKK taleplerini yürütebilir” izni olan kullanıcıyla çalışır. Panelde ve kuralları: Pazaryeri yorumları.

Endpoint İşlevi
GET /admin/v1/marketplace/sources Bağlantılar (items; her biri last_run, runs ve attention taşır; attention kaldırması bekletilen bağlantıda held, üst üste okunamayan bağlantıda failed türünü, sayıyı ve son hata kodunu verir, sorun yoksa null olur), pazaryerleri (platforms) ve alış yolları (routes)
POST /admin/v1/marketplace/sources Bağlantı kurar. Body: platform (trendyol, hepsiburada, amazon, n11, ciceksepeti), channel, seller_id, route (file ya da feed); feed yolunda feed_url (https) ve isteğe bağlı secret. Kurulum kimin yaptığıyla İşlem geçmişi’ne yazılır. Aynı kanal, pazaryeri ve satıcı numarası için ikinci bağlantı 409 source_exists alır.
GET|PATCH|DELETE /admin/v1/marketplace/sources/<id> Bağlantıyı gösterir, değiştirir (enabled; feed yolunda feed_url ve secret; seller_id değiştirilemez, 400 seller_id_locked) ya da kaldırır (yayında aktarılmış yorum ya da kişisel veri talebiyle kaldırılmış yorum kaydı varsa 409 source_has_reviews). secret yanıtlarda dönmez; has_secret kayıtlı olup olmadığını gösterir.
POST /admin/v1/marketplace/sources/<id>/runs Okumayı başlatır ve 202 döner. file yolunda multipart/form-data ile file (CSV, .xlsx ya da JSON; en çok 20 MB, 100.000 satır) gönderilir; dosya tam bir karşılaştırmadır. feed yolunda body: scope (new ya da full, varsayılan full). İkisinde de confirm_removals (true ise bekletilen kaldırmalar uygulanır). Başka okuma sürerken 409 run_in_progress, duraklatılmış bağlantıda ya da kapalı kanalda 409 source_inactive. Dosya okunamazsa 400 ve detail içinde column_missing: <sütun>, file_unreadable, unsupported_format, too_large ya da too_many_rows.
GET /admin/v1/marketplace/sources/<id>/runs Son okumalar; her okumanın sayıları ve report içinde eşleşme raporu
POST /admin/v1/marketplace/sources/<id>/check Hiçbir şey kaydetmeden dener: file yolunda file gönderilir, feed yolunda adres okunur. Yanıt: rows, eligible, would_import, would_update, would_remove, matched_barcodes, unmatched_barcodes, unmatched, skips.
GET /admin/v1/marketplace/imported-reviews Aktarılmış yorumları listeler; q yorum metninde, yazar adında ve pazaryeri yorum numarasında arar, platform süzer.
POST /admin/v1/marketplace/removals Seçilen aktarılmış yorumları kişisel veri talebiyle kaldırır. Body: reviews (aktarılmış yorum kimlikleri, en çok 100), isteğe bağlı note. Yanıt 201: id, reviews, media_purged, state. Talep Kişisel veri talepleri listesine silme olarak yazılır.

Okuma satırında state queued, running, succeeded, held (kaldırmalar bekletildi) ya da failed olur; error başarısız okumanın kodudur. report matched_barcodes, unmatched_barcodes, unmatched (barcode, reason: no_product, no_barcode ya da ambiguous, reviews), skips, photos_missing ve bekletilmiş okumada held_products taşır.

Liste endpoint’leri aynı parametreleri ve aynı yanıt biçimini kullanır.

Parametreler: endpoint’te tanımlı her filtrenin adı, q (arama), from ve to (tarih ya da tam zaman; yalnızca tarih verilirse o günün tamamı dahil edilir), sort, page ve page_size (en fazla 100).

{
"items": [],
"total": 0, "page": 1, "pages": 1,
"facets": { "state": [{ "value": "sent", "count": 12 }] },
"filters": [{ "name": "state", "group": "invite_state", "faceted": true, "advanced": false, "kind": "value" }],
"sorts": ["oldest", "recent"]
}
  • filters, endpoint’in kabul ettiği filtreleri listeler. kind filtrenin türünü belirtir: value (değer listesi), flag (=1) ya da choice (adlandırılmış seçenekler).
  • facets, her filtrenin değerlerini o filtrenin kendisi hariç tutularak sayar.

Yanıtlardaki değerler kod olarak döner (published, profanity vb.). Ekranda göstermek için gerekçe ve durum adlarını GET /admin/v1/reasons yanıtı ve kendi çeviri dosyalarınızla metne dönüştürün.

import os
import requests
BASE = os.environ["SAYPROOF_BASE"]
HEADERS = {"Authorization": f"Api-Key {os.environ['SAYPROOF_ADMIN_KEY']}", "Accept-Language": "tr"}
def published_reviews(since):
page = 1
while True:
answer = requests.get(
f"{BASE}/admin/v1/reviews",
params={"status": "published", "from": since, "sort": "oldest", "page": page, "page_size": 100},
headers=HEADERS,
timeout=30,
)
answer.raise_for_status()
body = answer.json()
yield from body["items"]
if page >= body["pages"]:
return
page += 1
for review in published_reviews("2026-09-01"):
print(review["id"], review["rating"])
import { createHash } from "node:crypto";
import { writeFile } from "node:fs/promises";
const base = process.env.SAYPROOF_BASE;
const headers = { Authorization: `Api-Key ${process.env.SAYPROOF_EXPORT_KEY}`, "Content-Type": "application/json" };
const created = await fetch(`${base}/admin/v1/audit-file`, {
method: "POST",
headers,
body: JSON.stringify({ market: "TR", start: "2026-09-01", end: "2026-09-30" }),
}).then((answer) => answer.json());
const download = await fetch(`${base}/admin/v1/audit-file/${created.copy.id}?format=json`, { headers });
const content = Buffer.from(await download.arrayBuffer());
const fingerprint = download.headers.get("X-Sayproof-Fingerprint");
if (createHash("sha256").update(content).digest("hex") !== fingerprint) {
throw new Error("audit_file_fingerprint_mismatch");
}
await writeFile(`denetim-${created.copy.id}.json`, content);

JSON dosyasının SHA-256 değeri doğrulama koduyla aynıdır; dosyanın indirildikten sonra değiştirilmediğini bu karşılaştırmayla gösterebilirsiniz.

E-posta almak istemeyen adresleri sorgulamak (Python)

Bölüm başlığı “E-posta almak istemeyen adresleri sorgulamak (Python)”

Kendi e-posta gönderimlerinizden önce, Sayproof’taki listede yer alan adresleri ayıklamak için adresleri 1.000’erli gruplar hâlinde sorgulayın. Yanıt yalnızca listede bulunan adresleri döndürür.

import os
import requests
BASE = os.environ["SAYPROOF_BASE"]
HEADERS = {"Authorization": f"Api-Key {os.environ['SAYPROOF_ADMIN_KEY']}"}
def opted_out(addresses):
found = set()
for start in range(0, len(addresses), 1000):
answer = requests.post(
f"{BASE}/admin/v1/opt-outs/check",
json={"addresses": addresses[start : start + 1000]},
headers=HEADERS,
timeout=30,
)
answer.raise_for_status()
found |= {row["address"] for row in answer.json()["opted_out"]}
return found