API

Seviyorum API ve MCP

Deneyimlerinizi okuyun ve yanıtlayın, üyelerin sorularını yanıtlayın, ürün vitrininizi ve kuponlarınızı yönetin, istatistiklerinizi alın. Yapay zekâ asistanınız Seviyorum’u MCP ile doğrudan kullansın; olaylar webhook ile anında sisteminize gelsin.

REST API

52 şirket ve üye işlemi, anahtarsız herkese açık marka verisi. JSON, Türkçe hata mesajları.

MCP ve OAuth

Claude, ChatGPT, Cursor ve VS Code’daki asistanlar Seviyorum girişiyle bağlanıp araçlarımızı kullanır.

Webhook

Yeni deneyim, üye sorusu, asistan talebi: imzalı, yeniden denenen bildirimler.

Hızlı başlangıç

  1. 1. Anahtar oluşturun. Şirket paneli › API ve MCP (Business ve Kurumsal planlar). “Okuma” ya da “Okuma ve yazma” yetkisini seçin; anahtar yalnızca bir kez gösterilir. Henüz şirket profiliniz yoksa Kurumsal sayfasından başlayın.
  2. 2. İlk isteği gönderin.
    Şirketiniz ve kotalarınız
    curl "https://seviyorum.com/api/company/v1/company" \
      -H "Authorization: Bearer $SEVIYORUM_API_KEY"
  3. 3. Asistanınızı bağlayın.
    claude.ai ve Claude Desktop
    Ayarlar › Bağlayıcılar › Özel bağlayıcı ekle
    URL: https://seviyorum.com/mcp/hesap
    “Bağlan”a basın, Seviyorum'a giriş yapıp kişisel hesabınızı ya da şirketinizi seçin (OAuth; anahtar gerekmez).

    Sonra asistanınıza “Yanıtsız deneyimlerimize taslak yanıt hazırla, göndermeden önce bana göster” demeniz yeterli.

  4. Anahtarsız deneyin: herkese açık marka verisi herkes için açık.
    Marka ara
    curl "https://seviyorum.com/api/company/v1/brands?q=kahve"

Kimlik doğrulama

Her şirket isteğinde Authorization: Bearer sv_live_… başlığını gönderin (ya da X-API-Key). Taban adres: https://seviyorum.com/api/company/v1.

  • Okuma yetkili anahtar hiçbir şeyi değiştiremez; Okuma ve yazma yetkili anahtar yanıt yazar, ürün ve kupon yönetir, profili günceller.
  • Anahtar, onu oluşturan ekip üyesi adına çalışır; işlemler denetim kaydına onun adıyla düşer. Kişi ekipten ayrılır ya da sahip/yönetici rolünü kaybederse anahtar durur.
  • Anahtarı yalnızca sunucunuzda saklayın; tarayıcıya ya da mobil uygulamaya koymayın. Sızdıysa panelden hemen iptal edin.
  • Biz anahtarın kendisini değil, yalnızca özetini (SHA-256) saklarız.
  • Uygulamanız kullanıcılar adına bağlanacaksa anahtar yerine OAuth kullanın: tokenlar (sv_at_…) aynı başlıkla gönderilir.

Yanıtlar, hatalar, sınırlar

Başarılı yanıtlar {"data": …}, hatalar {"error": "Türkçe açıklama", "field"?: "alan"} döner; error metnini kullanıcınıza olduğu gibi gösterebilirsiniz.

400Eksik ya da geçersiz alan (field hangisi olduğunu söyler)
401Anahtar yok, geçersiz ya da iptal edilmiş
403Plan ya da anahtar yetkisi yetmiyor
404Kayıt ya da uç nokta yok
422Bir kurala takıldı: kota, üyenin izni, moderasyon…
429Hız sınırı: anahtar başına dakikada 120, anahtarsız uçlarda IP başına 60

Listeler page ve per (en fazla 50) alır, total ve pages döner; deneyim ve konuşma listeleri since (ISO 8601) ile artımlı eşitlenir. Zamanlar ISO 8601 (UTC).

Yanıtlarda X-RateLimit-Limit ve X-RateLimit-Remaining başlıkları vardır. POST isteklerine Idempotency-Key ekleyin: ağ hatasında güvenle tekrar deneyebilirsiniz; aynı anahtar ve gövdeyle 24 saat içinde gelen istek yeniden işlenmez, ilk yanıt döner.

Kod örnekleri

JavaScript (Node.js 18+)
// Node.js 18+ — yanıtsız deneyimleri al, ilkine yanıt yaz
const BASE = "https://seviyorum.com/api/company/v1";
const headers = { Authorization: `Bearer ${process.env.SEVIYORUM_API_KEY}`, "Content-Type": "application/json" };

const res = await fetch(`${BASE}/company/reviews?filter=unreplied&per=5`, { headers });
const { data, error } = await res.json();
if (!res.ok) throw new Error(error);

const first = data.items[0];
if (first) {
  await fetch(`${BASE}/company/reviews/${first.id}/reply`, {
    method: "PUT", headers,
    body: JSON.stringify({ body: "Güzel sözleriniz için teşekkür ederiz!" }),
  });
}
Python
# Python 3 — son 24 saatin deneyimlerini eşitle
import os, datetime, requests

BASE = "https://seviyorum.com/api/company/v1"
H = {"Authorization": f"Bearer {os.environ['SEVIYORUM_API_KEY']}"}
since = (datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=1)).isoformat()

page = 1
while True:
    r = requests.get(f"{BASE}/company/reviews", headers=H, params={"since": since, "page": page, "per": 50})
    r.raise_for_status()
    data = r.json()["data"]
    for review in data["items"]:
        print(review["rating"], review["title"])
    if page >= data["pages"]:
        break
    page += 1

İlkeler

  • Seviyorum Skoru, sıralamalar, rozetler ve hangi deneyimlerin göründüğü satın alınamaz; API de bunları değiştiremez.
  • Deneyim yazılamaz, düzenlenemez, silinemez; markalar yalnızca herkese açık yanıt yazar.
  • Üyelere yeni mesaj, toplu kampanya, anlık bildirim, hediye ve arama başlatmak API'de yoktur: üyelerin izniyle çalışan bu araçlar panelde, bir insanın onayıyla kalır. API, üyenin başlattığı konuşmaları ve soruları yanıtlar.
  • Üyelerin e-posta adresi ve telefonu hiçbir uçta yoktur.
  • Kişisel hesapla (OAuth) bağlanan uygulamalar üye adına deneyim yazamaz; soru sorma, mesaj ve takip gibi işlemleri yalnızca üyenin onayıyla yapar.
  • Hediye ve fırsatlar deneyim yazmaya ya da puana bağlanamaz.
  • Yapay zekâ ile yazılan yanıtlar da markanın kendi yanıtıdır: göndermeden önce bir kişi okumalıdır.

Markalar (herkese açık)

GET/brands

Marka ara

Seviyorum'daki markaları adına göre arar. Sonuçlar sıralamadakiler ve Seviyorum Skoru yüksek olanlar önde gelecek şekilde sıralanır. Bir markanın ayrıntısı için get_brand'i slug ile çağırın.

Herkese açık (anahtarsız)MCP: search_brands
AlanYerTürAçıklama
q*querystringAranan marka adı (en az 2 harf).
limitqueryintegerEn fazla kaç sonuç (1–20). Varsayılan: 8.
curl
curl "https://seviyorum.com/api/company/v1/brands?q=kahve"
GET/brands/{slug}

Marka profili

Bir markanın herkese açık profili: Seviyorum Skoru (0–100), sıralaması, kalp ortalaması ve dağılımı, deneyim ve seven sayısı, yanıt oranı, rozetleri, canlı fırsatları, ürün vitrini ve markaya soru sorulabilip sorulamadığı. Skor satın alınamaz; ücretli planlar skoru, sıralamayı ve rozetleri etkilemez.

Herkese açık (anahtarsız)MCP: get_brand
AlanYerTürAçıklama
slug*pathstringMarkanın adresi: seviyorum.com/<slug>.
curl
curl "https://seviyorum.com/api/company/v1/brands/ornek-marka"
GET/brands/{slug}/reviews

Markanın deneyimleri

Bir markaya üyelerin yazdığı yayındaki deneyimler (1–5 kalp, başlık, metin, sevilen yönler, markanın yanıtı). Deneyimler üyelerin kişisel görüşleridir; alıntılarken bunu belirtin ve deneyim uydurmayın.

Herkese açık (anahtarsız)MCP: list_brand_reviews
AlanYerTürAçıklama
slug*pathstringMarkanın adresi: seviyorum.com/<slug>.
pagequeryintegerSayfa (1'den başlar). Varsayılan: 1.
perqueryintegerSayfa başına kayıt (en fazla 50). Varsayılan: 10.
ratingqueryintegerYalnızca bu kalp sayısı (1–5).
sortqueryyeni | faydali | yuksek | dusukSıralama: yeni, faydali, yuksek, dusuk. Varsayılan: "yeni".
curl
curl "https://seviyorum.com/api/company/v1/brands/ornek-marka/reviews?sort=yeni"
GET/rankings

En sevilen markalar

Seviyorum Skoru'na göre en sevilen markalar; isterseniz bir kategoride. Sıralamaya yalnızca yeterli deneyime ulaşmış markalar girer (eşik get_scoring'de).

Herkese açık (anahtarsız)MCP: top_brands
AlanYerTürAçıklama
categoryquerystringKategori slug'ı (list_categories).
limitqueryintegerKaç marka (1–50). Varsayılan: 10.
curl
curl "https://seviyorum.com/api/company/v1/rankings?category=kafe-restoran&limit=10"
GET/categories

Kategoriler

Seviyorum'daki marka kategorileri ve her birindeki marka sayısı.

Herkese açık (anahtarsız)MCP: list_categories
curl
curl "https://seviyorum.com/api/company/v1/categories"
GET/offers

Canlı fırsatlar

Markaların Fırsatlar'da yayınladığı canlı kuponlar. Kodlar burada görünmez: üyeler Seviyorum'a giriş yapıp tek dokunuşla alır (seviyorum.com/firsatlar). Fırsatlar hiçbir zaman deneyim yazmaya bağlı değildir.

Herkese açık (anahtarsız)MCP: list_offers
AlanYerTürAçıklama
categoryquerystringKategori slug'ı.
brandquerystringYalnızca bu markanın fırsatları.
curl
curl "https://seviyorum.com/api/company/v1/offers?category=kafe-restoran"
GET/scoring

Seviyorum Skoru nasıl hesaplanır?

Seviyorum Skoru'nun formülü, sıralama eşiği ve değiştirilemeyen kurallar. Bir markanın skorunu yorumlarken bunu kullanın.

Herkese açık (anahtarsız)MCP: get_scoring
curl
curl "https://seviyorum.com/api/company/v1/scoring"

Şirket

GET/company

Şirketiniz, planınız ve kotalarınız

Anahtarın bağlı olduğu şirket: profil bilgileri, plan, açık özellikler, bu ayki kotalar (mesaj, anlık bildirim, arama dakikası, asistan yanıtı, AI tasarım, ürün) ve yanıt bekleyen işler (yanıtsız deneyim, okunmamış öneri ve mesaj, yeni asistan talebi).

Şirket · okumaMCP: get_company
curl
curl "https://seviyorum.com/api/company/v1/company" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/company/stats

İstatistikler

Seviyorum Skoru ve sıralama, kalp dağılımı, alt puanlar (kalite, ilgi, hız, fiyat/değer), en çok sevilen yönler, yanıt oranı ve süresi, kategori ortalamaları ve günlük seri (profil görüntülenme, yeni seven, yeni deneyim).

Şirket · okumaMCP: get_stats
AlanYerTürAçıklama
daysqueryintegerGünlük serinin kaç gün geriye gideceği (7–90). Varsayılan: 30.
curl
curl "https://seviyorum.com/api/company/v1/company/stats?days=30" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/company/badges

Rozetleriniz

Şirketinizin kazandığı rozetler. Rozetler yalnızca deneyimlere, sevenlere, doğrulamaya ve ödüllere bakar; satın alınamaz.

Şirket · okumaMCP: list_badges
curl
curl "https://seviyorum.com/api/company/v1/company/badges" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
PATCH/company

Profili güncelle

Şirket profilini günceller; göndermediğiniz alanlar olduğu gibi kalır. Marka rengi kurumsal planlarda geçerlidir. Ad, kategori ve doğrulama Seviyorum ekibindedir.

Şirket · okuma ve yazmaMCP: update_company_profile
AlanYerTürAçıklama
taglinebodystring | nullKısa tanıtım (120).
descriptionbodystring | nullHakkında (2000).
websitebodystring | nullWeb sitesi (https).
support_emailbodystring | nullDestek e-postası.
support_phonebodystring | nullDestek telefonu.
citybodystring | nullŞehir.
founded_yearbodyinteger | nullKuruluş yılı.
socialsbodyobjectSosyal hesaplar: {instagram, x, facebook, linkedin, youtube, tiktok} adresleri.
brand_colorbodystring | nullMarka rengi (#RRGGBB).
curl
curl -X PATCH "https://seviyorum.com/api/company/v1/company" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tagline":"Mahallenin kahvecisi","support_email":"[email protected]"}'
GET/company/team

Ekibiniz

Şirket ekibiniz: görünen ad, rol (owner, admin, agent) ve unvan. E-posta adresleri yer almaz; ekibe davet panelden yapılır ve kişinin onayını bekler.

Şirket · okumaMCP: list_team
curl
curl "https://seviyorum.com/api/company/v1/company/team" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"

Deneyimler

GET/company/reviews

Deneyimleriniz

Şirketinize yazılan yayındaki deneyimler, yeniden eskiye; yanıtınız ve (planınızda varsa) üyenin yalnızca size yazdığı gizli öneri ile. Yanıtsızları bulmak için filter=unreplied.

Şirket · okumaMCP: list_reviews
AlanYerTürAçıklama
filterqueryall | unreplied | repliedall, unreplied (yanıtsız) ya da replied. Varsayılan: "all".
ratingqueryintegerYalnızca bu kalp sayısı.
sincequerystringYalnızca bu zamandan sonrakiler (ISO 8601) — artımlı eşitleme için.
pagequeryintegerSayfa (1'den başlar). Varsayılan: 1.
perqueryintegerSayfa başına kayıt (en fazla 50). Varsayılan: 20.
curl
curl "https://seviyorum.com/api/company/v1/company/reviews?filter=unreplied" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/company/reviews/{id}

Bir deneyim

Şirketinize yazılmış tek bir deneyim, yanıtınız ve varsa gizli öneri ile.

Şirket · okumaMCP: get_review
AlanYerTürAçıklama
id*pathstring (uuid)deneyim kimliği (UUID).
curl
curl "https://seviyorum.com/api/company/v1/company/reviews/3f1c…" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/company/suggestions

Gizli öneriler

Üyelerin deneyimle birlikte yalnızca size yazdığı öneriler (herkese açık görünmez, skoru etkilemez).

Şirket · okumaPlan: Pro+MCP: list_suggestions
AlanYerTürAçıklama
unreadquerybooleantrue: yalnızca okunmamışlar.
pagequeryintegerSayfa (1'den başlar). Varsayılan: 1.
perqueryintegerSayfa başına kayıt (en fazla 50). Varsayılan: 20.
curl
curl "https://seviyorum.com/api/company/v1/company/suggestions?unread=true" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
PUT/company/reviews/{id}/reply

Deneyime yanıt yaz

Bir deneyime şirket adına herkese açık yanıt yazar ya da mevcut yanıtı günceller. Yanıt marka sayfasında deneyimin altında görünür ve ilk yanıtta üyeye bildirim gider. Teşekkür edin, somut olun; üyeden deneyimini değiştirmesini istemeyin ve hediye/indirim karşılığı teklif etmeyin. Yanıtlar moderasyondan geçer.

Şirket · okuma ve yazmaPlan: Pro+MCP: reply_to_review
AlanYerTürAçıklama
id*pathstring (uuid)deneyim kimliği (UUID).
body*bodystringYanıt metni (2–2000 karakter, Türkçe).
curl
curl -X PUT "https://seviyorum.com/api/company/v1/company/reviews/3f1c…/reply" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"body":"Güzel sözleriniz için çok teşekkür ederiz! Ekibimize ilettik; yine bekleriz."}'
DELETE/company/reviews/{id}/reply

Yanıtı kaldır

Şirketinizin bir deneyime yazdığı yanıtı kaldırır. Deneyim olduğu gibi kalır.

Şirket · okuma ve yazmaMCP: delete_review_replyGeri alınamaz
AlanYerTürAçıklama
id*pathstring (uuid)deneyim kimliği (UUID).
curl
curl -X DELETE "https://seviyorum.com/api/company/v1/company/reviews/3f1c…/reply" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
POST/company/suggestions/{review_id}/read

Öneriyi okundu işaretle

Bir gizli öneriyi okundu (ya da read=false ile okunmadı) olarak işaretler.

Şirket · okuma ve yazmaPlan: Pro+MCP: mark_suggestion_read
AlanYerTürAçıklama
review_id*pathstring (uuid)deneyim kimliği (UUID).
readbodybooleantrue: okundu, false: okunmadı. Varsayılan: true.
curl
curl -X POST "https://seviyorum.com/api/company/v1/company/suggestions/3f1c…/read" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"read":true}'
POST/company/reviews/{id}/report

Deneyimi moderasyona bildir

Kurallara aykırı olduğunu düşündüğünüz bir deneyimi Seviyorum moderasyonuna bildirir (sahte, hakaret, kişisel veri, çıkar çatışması …). Deneyimi siz kaldıramazsınız; ekibimiz inceler. Olumsuz ama dürüst bir deneyim bildirim nedeni değildir.

Şirket · okuma ve yazmaMCP: report_review
AlanYerTürAçıklama
id*pathstring (uuid)deneyim kimliği (UUID).
reason*bodyspam | fake | offensive | personal_data | conflict | off_topic | otherspam: Spam veya reklam, fake: Gerçek bir deneyim değil, offensive: Hakaret veya nefret söylemi, personal_data: Kişisel veri içeriyor, conflict: Çıkar çatışması (çalışan / rakip), off_topic: Konu dışı, other: Diğer
notebodystring | nullEk açıklama.
curl
curl -X POST "https://seviyorum.com/api/company/v1/company/reviews/<id>/report" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Mesajlar ve sorular

GET/company/conversations

Konuşmalar

Üyelerle yazışmalarınız; asked=true olanlar üyenin size sorduğu sorulardır (yanıtlarınız aylık mesaj hakkından düşmez). Üyenin e-posta ve telefonu hiçbir zaman paylaşılmaz.

Şirket · okumaMCP: list_conversations
AlanYerTürAçıklama
unreadquerybooleantrue: yalnızca okunmamışlar.
askedquerybooleantrue: yalnızca üyelerin soruları.
sincequerystringYalnızca bu zamandan sonrakiler (ISO 8601) — artımlı eşitleme için.
curl
curl "https://seviyorum.com/api/company/v1/company/conversations?asked=true&unread=true" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/company/conversations/{id}

Bir konuşma

Bir konuşmanın tüm mesajları (eskiden yeniye). Okundu olarak işaretlemez.

Şirket · okumaMCP: get_conversation
AlanYerTürAçıklama
id*pathstring (uuid)konuşma kimliği (UUID).
curl
curl "https://seviyorum.com/api/company/v1/company/conversations/9a2b…" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
POST/company/conversations/{id}/messages

Konuşmada yanıt yaz

Mevcut bir konuşmaya şirketiniz adına yazar (üyenin sorusuna yanıt ya da süren yazışma). Üye engellediyse ya da artık mesaj almak istemiyorsa gönderilmez. Üyenin sorusuna verilen yanıtlar aylık mesaj hakkından düşmez; diğerleri düşer. Yeni konuşma başlatmak API'de yoktur (panelde, üyenin izniyle).

Şirket · okuma ve yazmaPlan: Pro+MCP: send_message
AlanYerTürAçıklama
id*pathstring (uuid)konuşma kimliği (UUID).
body*bodystringMesaj (1–4000 karakter).
curl
curl -X POST "https://seviyorum.com/api/company/v1/company/conversations/9a2b…/messages" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"body":"Merhaba, evet glütensiz seçeneklerimiz her gün var. Hafta sonu sizi bekliyoruz!"}'
GET/company/calls

Uygulama içi aramalarınız

Üyelerle uygulama içi sesli/görüntülü görüşmeleriniz: konu, süre, durum ve üyenin özel değerlendirmesi (skoru etkilemez). Arama başlatmak panelden yapılır.

Şirket · okumaPlan: Pro+MCP: list_calls
AlanYerTürAçıklama
pagequeryintegerSayfa (1'den başlar). Varsayılan: 1.
perqueryintegerSayfa başına kayıt (en fazla 50). Varsayılan: 20.
curl
curl "https://seviyorum.com/api/company/v1/company/calls" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"

Ürün vitrini

GET/company/products

Ürünleriniz

Ürün vitrininiz (sırasıyla), her ürünün mağaza bağlantıları ve son 30 günün mağaza tıklamaları.

Şirket · okumaPlan: Pro+MCP: list_products
curl
curl "https://seviyorum.com/api/company/v1/company/products" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
POST/company/products

Ürün ekle

Ürün vitrininize bir ürün ekler (Pro 12, Business 60, Kurumsal 300 ürün). Düğmeler ziyaretçiyi verdiğiniz satış sayfalarına götürür; tıklamalar sayılır.

Şirket · okuma ve yazmaPlan: Pro+MCP: create_product
AlanYerTürAçıklama
name*bodystringÜrün adı (2–80 karakter).
descriptionbodystring | nullKısa açıklama (en fazla 300 karakter).
image_urlbodystring | nullÜrün görseli: https adresi. Görsel indirilir, WebP'ye çevrilir ve Seviyorum'da saklanır.
links*bodystring[]1–6 satış sayfası (kendi siteniz, Trendyol, Hepsiburada, Amazon …). Mağaza adı adresten anlaşılır.
curl
curl -X POST "https://seviyorum.com/api/company/v1/company/products" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Filtre Kahve 250 g","description":"Taze kavrulmuş, orta gövdeli.","image_url":"https://ornek.com/img/filtre-kahve.jpg","links":["https://ornek.com/filtre-kahve","https://www.trendyol.com/ornek/filtre-kahve-p-123"]}'
PATCH/company/products/{id}

Ürünü güncelle

Bir ürünün adını, açıklamasını, görselini ya da satış bağlantılarını değiştirir; göndermediğiniz alanlar olduğu gibi kalır.

Şirket · okuma ve yazmaPlan: Pro+MCP: update_product
AlanYerTürAçıklama
id*pathstring (uuid)ürün kimliği (UUID).
namebodystringÜrün adı (2–80 karakter).
descriptionbodystring | nullKısa açıklama (en fazla 300 karakter).
image_urlbodystring | nullÜrün görseli: https adresi. Görsel indirilir, WebP'ye çevrilir ve Seviyorum'da saklanır.
linksbodystring[]1–6 satış sayfası (kendi siteniz, Trendyol, Hepsiburada, Amazon …). Mağaza adı adresten anlaşılır.
curl
curl -X PATCH "https://seviyorum.com/api/company/v1/company/products/5d7e…" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"links":["https://ornek.com/filtre-kahve"]}'
POST/company/products/{id}/active

Ürünü göster / gizle

Bir ürünü vitrinde gösterir (active=true) ya da silmeden gizler (active=false).

Şirket · okuma ve yazmaPlan: Pro+MCP: set_product_active
AlanYerTürAçıklama
id*pathstring (uuid)ürün kimliği (UUID).
active*bodybooleantrue: göster, false: gizle.
curl
curl -X POST "https://seviyorum.com/api/company/v1/company/products/5d7e…/active" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"active":false}'
DELETE/company/products/{id}

Ürünü sil

Bir ürünü vitrinden kalıcı olarak siler.

Şirket · okuma ve yazmaMCP: delete_productGeri alınamaz
AlanYerTürAçıklama
id*pathstring (uuid)ürün kimliği (UUID).
curl
curl -X DELETE "https://seviyorum.com/api/company/v1/company/products/5d7e…" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
POST/company/products/{id}/move

Ürünün sırasını değiştir

Bir ürünü vitrinde bir sıra yukarı (up) ya da aşağı (down) taşır.

Şirket · okuma ve yazmaPlan: Pro+MCP: move_product
AlanYerTürAçıklama
id*pathstring (uuid)ürün kimliği (UUID).
direction*bodyup | downup ya da down.
curl
curl -X POST "https://seviyorum.com/api/company/v1/company/products/<id>/move" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Hediye ve fırsatlar

GET/company/offers

Kuponlarınız

Hediye kuponlarınız ve Fırsatlar'da yayınladıklarınız; her birinde gönderilen, alınan, görülen, kodu açılan ve kullanılan sayıları.

Şirket · okumaPlan: Pro+MCP: list_company_offers
curl
curl "https://seviyorum.com/api/company/v1/company/offers" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
POST/company/offers

Kupon oluştur

Bir hediye kuponu oluşturur; is_public=true ile Fırsatlar'da ve marka sayfanızda yayınlanır (ilk yayında, teklif almayı kabul eden sevenlerinize bildirim gider). Kuponu deneyim yazmaya ya da puana bağlamayın. Üyelere tek tek ya da toplu gönderim panelden yapılır.

Şirket · okuma ve yazmaPlan: Pro+MCP: create_offer
AlanYerTürAçıklama
title*bodystringBaşlık (ör. “Üyelere özel %15 indirim”).
descriptionbodystring | nullKısa açıklama.
kind*bodypercent | amount | free_shipping | gift | otherpercent (yüzde), amount (TL), free_shipping, gift, other.
valuebodynumberpercent için 1–100, amount için TL.
min_spendbodynumberEn az alışveriş tutarı (TL).
code_mode*bodysingle | unique | nonesingle: herkese aynı kod, unique: her üyeye ayrı kod (codes), none: kodsuz.
codebodystring | nullsingle için kod.
codesbodystring | nullunique için kodlar: her satıra bir kod (en fazla 20.000).
urlbodystring | nullKuponun kullanılacağı sayfa (https).
termsbodystring | nullKoşullar.
expires_onbodystring | nullSon gün (YYYY-AA-GG).
is_publicbodybooleantrue: Fırsatlar'da yayınla.
claim_limitbodyinteger | nullFırsatlar'da en fazla kaç üye alabilir.
curl
curl -X POST "https://seviyorum.com/api/company/v1/company/offers" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Üyelere özel %15 indirim","kind":"percent","value":15,"code_mode":"single","code":"SEVIYORUM15","url":"https://ornek.com","expires_on":"2026-12-31","is_public":true}'
PATCH/company/offers/{id}

Kuponu yönet

Kuponun durumunu değiştirir (active, paused, ended) ve/veya Fırsatlar'da yayından kaldırır ya da yayınlar (public).

Şirket · okuma ve yazmaPlan: Pro+MCP: update_offer
AlanYerTürAçıklama
id*pathstring (uuid)kupon kimliği (UUID).
statusbodyactive | paused | endedactive, paused ya da ended.
publicbodybooleantrue: Fırsatlar'da yayınla, false: kaldır.
claim_limitbodyinteger | nullFırsatlar'da üye sınırı.
curl
curl -X PATCH "https://seviyorum.com/api/company/v1/company/offers/c41a…" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"paused"}'
GET/company/push

Anlık bildirimleriniz

Gönderdiğiniz ve planladığınız anlık bildirimler (başlık, metin, kitle, ulaşan kişi, durum). Yeni bildirim panelden gönderilir.

Şirket · okumaPlan: Pro+MCP: list_push_campaigns
curl
curl "https://seviyorum.com/api/company/v1/company/push" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/company/campaigns

Toplu mesaj kampanyalarınız

Sevenlerinize ve deneyim paylaşanlara gönderdiğiniz toplu mesaj kampanyaları ve ulaşan kişi sayıları. Yeni kampanya panelden gönderilir.

Şirket · okumaPlan: Business+MCP: list_campaigns
curl
curl "https://seviyorum.com/api/company/v1/company/campaigns" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/company/gifts

Gönderdiğiniz ve alınan hediyeler

Son gönderilen ya da Fırsatlar'dan alınan hediyeler: kupon, üyenin görünen adı, görülme, kodun açılması ve kullanım durumu.

Şirket · okumaPlan: Pro+MCP: list_sent_gifts
AlanYerTürAçıklama
limitqueryintegerKaç kayıt (1–100). Varsayılan: 30.
curl
curl "https://seviyorum.com/api/company/v1/company/gifts" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"

Yapay zekâ asistanı

GET/company/assistant/requests

Asistanın size ilettikleri

Marka asistanının yanıtlayamayıp ziyaretçinin açık izniyle size ilettiği sorular ve sohbet dökümü. İletişim bilgisi yalnızca ziyaretçinin seçtiği kanal için ve onun izniyle vardır.

Şirket · okumaPlan: Business+MCP: list_assistant_requests
AlanYerTürAçıklama
statusqueryopen | doneopen (yeni ve açık) ya da done. Varsayılan: "open".
pagequeryintegerSayfa (1'den başlar). Varsayılan: 1.
perqueryintegerSayfa başına kayıt (en fazla 50). Varsayılan: 20.
curl
curl "https://seviyorum.com/api/company/v1/company/assistant/requests?status=open" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
PATCH/company/assistant/requests/{id}

Asistan talebini güncelle

Asistanın ilettiği bir talebi açık (open) ya da tamamlandı (done) yapar; isterseniz ekip içi not ekler.

Şirket · okuma ve yazmaPlan: Business+MCP: update_assistant_request
AlanYerTürAçıklama
id*pathstring (uuid)talep kimliği (UUID).
status*bodyopen | doneopen ya da done.
notebodystring | nullEkip içi not (üye görmez).
curl
curl -X PATCH "https://seviyorum.com/api/company/v1/company/assistant/requests/e8f0…" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"done","note":"Telefonla arandı, sorun çözüldü."}'
POST/company/assistant/requests/{id}/answer

Talebi Seviyorum mesajıyla yanıtla

Ziyaretçi yanıtın Seviyorum mesajıyla gelmesini istediyse, talebi bir konuşma açarak yanıtlar ve tamamlandı yapar.

Şirket · okuma ve yazmaPlan: Business+MCP: answer_assistant_request
AlanYerTürAçıklama
id*pathstring (uuid)talep kimliği (UUID).
body*bodystringYanıt metni.
curl
curl -X POST "https://seviyorum.com/api/company/v1/company/assistant/requests/e8f0…/answer" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"body":"Merhaba, sorunuz için teşekkürler; kargonuz yarın teslim edilecek."}'
GET/company/assistant

Asistan ayarları

Marka asistanınızın adı, karşılaması, üslubu ve bildiği bilgiler (hakkımızda, saatler ve iletişim, politikalar, soru-yanıtlar, değinmemesi gerekenler) ve bu ayki kullanım.

Şirket · okumaPlan: Business+MCP: get_assistant
curl
curl "https://seviyorum.com/api/company/v1/company/assistant" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/company/assistant/chats

Asistan sohbetleri

Ziyaretçilerin marka asistanıyla yaptığı sohbetler (anonim). handoff=true yalnızca size iletilenler. Sık sorulanları görüp asistanın bilgilerini güncellemek için kullanın.

Şirket · okumaPlan: Business+MCP: list_assistant_chats
AlanYerTürAçıklama
handoffquerybooleantrue: yalnızca size iletilenler.
pagequeryintegerSayfa (1'den başlar). Varsayılan: 1.
perqueryintegerSayfa başına kayıt (en fazla 50). Varsayılan: 20.
curl
curl "https://seviyorum.com/api/company/v1/company/assistant/chats" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
PATCH/company/assistant

Asistanı güncelle

Marka asistanının bilgilerini günceller; göndermediğiniz alanlar olduğu gibi kalır. Asistan yalnızca bu bilgiler ve herkese açık profilinizden yanıt verir; fiyat, stok ve kampanya gibi sık değişen bilgileri yazmayın. faq gönderirseniz listenin tamamının yerine geçer.

Şirket · okuma ve yazmaPlan: Business+MCP: update_assistant
AlanYerTürAçıklama
enabledbodybooleanYayında mı.
namebodystringAsistanın adı.
greetingbodystringKarşılama cümlesi.
tonebodysamimi | resmisamimi (sen) ya da resmi (siz).
aboutbodystringHakkımızda, ürün ve hizmetler.
hoursbodystringÇalışma saatleri, şubeler, iletişim kanalları.
policiesbodystringTeslimat, iade, garanti, ödeme.
faqbodyobject[]Soru-yanıtlar (en fazla 30).
avoidbodystringAsistanın değinmemesi gerekenler.
curl
curl -X PATCH "https://seviyorum.com/api/company/v1/company/assistant" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Webhook

GET/company/webhook

Webhook ayarı

Kayıtlı webhook adresiniz, seçili olaylar, durum ve son teslim. İmza anahtarı burada dönmez (yalnızca ilk kayıtta ve panelde).

Şirket · okumaPlan: Business+MCP: get_webhook
curl
curl "https://seviyorum.com/api/company/v1/company/webhook" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/company/webhook/deliveries

Webhook teslimleri

Son webhook teslimleri: olay, durum (pending, sent, failed), deneme sayısı, son HTTP kodu ve hata.

Şirket · okumaPlan: Business+MCP: list_webhook_deliveries
AlanYerTürAçıklama
limitqueryintegerKaç kayıt (1–100). Varsayılan: 30.
curl
curl "https://seviyorum.com/api/company/v1/company/webhook/deliveries" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
PUT/company/webhook

Webhook kaydet

Webhook adresinizi (https), olayları ve durumunu kaydeder. İlk kayıtta imza anahtarı (whsec_…) yanıtta bir kez döner; saklayın.

Şirket · okuma ve yazmaPlan: Business+MCP: update_webhook
AlanYerTürAçıklama
url*bodystringhttps adresi.
events*bodystring[]Olaylar: review.published, question.created, message.received, assistant.request, badge.earned, plan.changed.
enabledbodybooleanEtkin mi. Varsayılan: true.
curl
curl -X PUT "https://seviyorum.com/api/company/v1/company/webhook" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
DELETE/company/webhook

Webhook'u kaldır

Webhook adresini siler; bekleyen teslimler iptal edilir.

Şirket · okuma ve yazmaPlan: Business+MCP: delete_webhookGeri alınamaz
curl
curl -X DELETE "https://seviyorum.com/api/company/v1/company/webhook" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
POST/company/webhook/deliveries/{id}/redeliver

Teslimi yeniden gönder

Başarısız (ya da istediğiniz) bir webhook teslimini hemen yeniden kuyruğa alır.

Şirket · okuma ve yazmaPlan: Business+MCP: redeliver_webhook
AlanYerTürAçıklama
id*pathstring (uuid)teslim kimliği (UUID).
curl
curl -X POST "https://seviyorum.com/api/company/v1/company/webhook/deliveries/<id>/redeliver" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Üye hesabı (OAuth)

GET/me

Hesabım

Bağlanan üyenin profili: görünen ad, kullanıcı adı, şehir, seviye ve puanı, deneyim ve sevdiği marka sayısı, fırsat izni, okunmamış bildirim ve mesajlar. E-posta adresi yer almaz.

Üye hesabı (OAuth)MCP: get_my_account
curl
curl "https://seviyorum.com/api/company/v1/me" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/me/reviews

Deneyimlerim

Üyenin yazdığı deneyimler (yayında, incelemede ya da gizli), markanın yanıtı ve moderasyon notu. Deneyim yazmak ve düzenlemek yalnızca Seviyorum sitesinde ve uygulamasında, üyenin kendi kaleminden olur.

Üye hesabı (OAuth)MCP: list_my_reviews
curl
curl "https://seviyorum.com/api/company/v1/me/reviews" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/me/loves

Sevdiğim markalar

Üyenin “Seviyorum” ile takip ettiği markalar.

Üye hesabı (OAuth)MCP: list_my_loved_brands
curl
curl "https://seviyorum.com/api/company/v1/me/loves" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
PUT/me/loves/{slug}

Markayı takip et / bırak

Bir markayı “Seviyorum” ile takip eder (loved=true) ya da bırakır (loved=false). Bu, markanın seven sayısına ve Seviyorum Skoru'na katkı verir; yalnızca üyenin gerçekten istediği markalar için kullanın.

Üye hesabı (OAuth)MCP: set_love
AlanYerTürAçıklama
slug*pathstringMarkanın adresi: seviyorum.com/<slug>.
loved*bodybooleantrue: takip et, false: bırak.
curl
curl -X PUT "https://seviyorum.com/api/company/v1/me/loves/<slug>" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
GET/me/gifts

Hediyelerim

Markaların gönderdiği ve Fırsatlar'dan alınan hediyeler. Kod, üye açmadan görünmez (reveal_gift).

Üye hesabı (OAuth)MCP: list_my_gifts
curl
curl "https://seviyorum.com/api/company/v1/me/gifts" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
POST/me/gifts/{id}/reveal

Hediye kodunu aç

Bir hediyenin kodunu açar (marka kodun açıldığını görür).

Üye hesabı (OAuth)MCP: reveal_gift
AlanYerTürAçıklama
id*pathstring (uuid)hediye kimliği (UUID).
curl
curl -X POST "https://seviyorum.com/api/company/v1/me/gifts/<id>/reveal" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
POST/me/offers/{id}/claim

Fırsatı al

Fırsatlar'daki bir kuponu üyenin Hediyelerim cüzdanına alır ve kodu döner (list_offers ile bulunur).

Üye hesabı (OAuth)MCP: claim_offer
AlanYerTürAçıklama
id*pathstring (uuid)fırsat kimliği (UUID).
curl
curl -X POST "https://seviyorum.com/api/company/v1/me/offers/<id>/claim" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
GET/me/notifications

Bildirimlerim

Üyenin son bildirimleri (yanıtlar, rozetler, mesajlar, hediyeler). Okundu olarak işaretlemez.

Üye hesabı (OAuth)MCP: list_my_notifications
AlanYerTürAçıklama
limitqueryintegerKaç bildirim (1–100). Varsayılan: 30.
curl
curl "https://seviyorum.com/api/company/v1/me/notifications" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/me/conversations

Mesajlarım

Üyenin markalarla konuşmaları (sorduğu sorular ve markaların yazdıkları).

Üye hesabı (OAuth)MCP: list_my_conversations
curl
curl "https://seviyorum.com/api/company/v1/me/conversations" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
GET/me/conversations/{id}

Bir konuşmam

Bir konuşmanın mesajları (eskiden yeniye). Okundu olarak işaretlemez.

Üye hesabı (OAuth)MCP: get_my_conversation
AlanYerTürAçıklama
id*pathstring (uuid)konuşma kimliği (UUID).
curl
curl "https://seviyorum.com/api/company/v1/me/conversations/<id>" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY"
POST/me/conversations/{id}/messages

Markaya yanıt yaz

Üyenin bir markayla süren konuşmasına yazar. Göndermeden önce metni üyeye gösterip onay alın.

Üye hesabı (OAuth)MCP: reply_in_my_conversation
AlanYerTürAçıklama
id*pathstring (uuid)konuşma kimliği (UUID).
body*bodystringMesaj (1–4000 karakter).
curl
curl -X POST "https://seviyorum.com/api/company/v1/me/conversations/<id>/messages" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
POST/me/questions

Markaya soru sor

Üyenin sevdiği ya da deneyim yazdığı bir markanın ekibine soru sorar (marka soru yanıtlıyorsa: get_brand → takes_questions). Yanıt üyenin Mesajlar'ına gelir. Göndermeden önce metni üyeye gösterip onay alın.

Üye hesabı (OAuth)MCP: ask_brand
AlanYerTürAçıklama
slug*bodystringMarkanın adresi: seviyorum.com/<slug>.
body*bodystringSoru (5–2000 karakter). İlk satır konunun başlığı olur.
curl
curl -X POST "https://seviyorum.com/api/company/v1/me/questions" \
  -H "Authorization: Bearer $SEVIYORUM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

MCP: yapay zekâ asistanları

Model Context Protocol sunucumuzun iki adresi var (Streamable HTTP, durumsuz). Araçlar yukarıdaki API işlemleriyle birebir aynıdır.

  • https://seviyorum.com/mcp/hesap — hesabınızla: claude.ai, ChatGPT ve Claude Desktop “Bağlan” deyince Seviyorum girişine yönlendirir (OAuth); kişisel hesabınızı ya da yönettiğiniz şirketi seçersiniz. Anahtar gerekmez.
  • https://seviyorum.com/mcp — anahtarsız: herkese açık 7 araç (marka arama, profil, deneyimler, sıralama, fırsatlar, skor kuralları); Authorization: Bearer sv_live_… ile şirket araçları da gelir.
https://seviyorum.com/mcp
claude.ai ve Claude Desktop
Ayarlar › Bağlayıcılar › Özel bağlayıcı ekle
URL: https://seviyorum.com/mcp/hesap
“Bağlan”a basın, Seviyorum'a giriş yapıp kişisel hesabınızı ya da şirketinizi seçin (OAuth; anahtar gerekmez).
Hazır istemler
  • yanitsiz_deneyimlere_taslak — yanıtsız deneyimlere kısa, içten yanıt taslakları; yalnızca onayladıklarınızı gönderir.
  • haftalik_ozet — skor, yeni deneyimler, sevilen yönler ve bekleyen işlerle yönetici özeti.
  • marka_karsilastir — markaları herkese açık veriyle karşılaştırır (anahtarsız).

Asistanlar herkese açık bir yanıt yazmadan önce taslağı size göstermek üzere yönlendirilir; yine de son okumayı bir kişinin yapması gerekir.

OAuth 2.1

Kendi uygulamanızı ya da asistanınızı Seviyorum kullanıcılarının hesabına bağlamak için. MCP istemcileri bunların hepsini kendiliğinden yapar; elle uygulamanız gerekmez.

Korunan kaynak (RFC 9728)https://seviyorum.com/.well-known/oauth-protected-resource/mcp/hesap
Yetkilendirme sunucusu (RFC 8414)https://seviyorum.com/.well-known/oauth-authorization-server
İstemci kaydı (RFC 7591)POST https://seviyorum.com/oauth/register
Yetkilendirmehttps://seviyorum.com/oauth/authorize — response_type=code, PKCE S256 zorunlu
TokenPOST https://seviyorum.com/oauth/token — authorization_code, refresh_token
İptal (RFC 7009)POST https://seviyorum.com/oauth/revoke
  • Kullanıcı Seviyorum’a giriş yapar ve paylaşacağını seçer: kişisel hesabı (member) ya da yönettiği bir şirket (company:read / company:write, Business ve Kurumsal).
  • Erişim tokenı (sv_at_…) 1 saat geçerlidir; yenileme tokenı 30 gün ve her kullanımda yenilenir. Eski bir yenileme tokenı tekrar kullanılırsa bağlantı güvenlik için kapanır.
  • Şirket tokenları REST API’de API anahtarı gibi kullanılabilir; kişisel hesap tokenları “Üye hesabı” işlemlerini açar.
  • Kişisel hesapla bağlanan uygulama deneyim yazamaz: deneyimler üyenin kendi kaleminden, sitede ya da uygulamada yazılır.
  • Bağlantılar Hesabım › Ayarlar › Bağlı uygulamalar’dan ve şirket panelinden tek tıkla kesilir.

Webhook’lar

Şirket paneli › API ve MCP › Webhook’ta bir https adresi ve olaylar seçin. Her olay JSON olarak POST edilir. 2xx dışındaki yanıtlarda 1 dk, 5 dk, 30 dk, 2 sa ve 6 sa sonra yeniden denenir; art arda 50 başarısız teslimde adres kapatılır. Aynı olay birden fazla gelebilir: Seviyorum-Delivery ile tekrarları ayıklayın.

OlayNe zaman
review.publishedŞirketinize yazılan bir deneyim yayına girdi.
question.createdSizi seven bir üye marka sayfanızdan soru sordu.
message.receivedBir üye süren bir konuşmada size yazdı.
assistant.requestMarka asistanı yanıtlayamadığı bir soruyu ziyaretçinin izniyle iletti.
badge.earnedŞirketiniz bir rozet kazandı.
plan.changedPlanınız etkinleşti ya da sona erdi.
pingPaneldeki “Test gönder”.

Başlıklar: Seviyorum-Event, Seviyorum-Delivery ve Seviyorum-Signature: t=<unix>,v1=<hex>. v1, imza anahtarınızla <t>.<ham gövde> metninin HMAC-SHA256 özetidir. 5 dakikadan eski imzaları reddedin.

Örnek gövde
{
  "id": "b5e1c0de-…",
  "event": "review.published",
  "created_at": "2026-11-04T09:12:44.512Z",
  "company": {
    "id": "a8a4…",
    "slug": "ornek-marka",
    "name": "Örnek Marka"
  },
  "data": {
    "review_id": "3f1c…",
    "title": "Ornek Marka için yeni bir deneyim",
    "summary": "Harika bir hafta sonu kahvaltısı",
    "url": "https://seviyorum.com/panel/ornek-marka/deneyimler#d-3f1c…"
  }
}
Doğrulama — Node.js
import crypto from "node:crypto";

// Express örneği: gövdeyi ham haliyle alın (express.raw({ type: "application/json" })).
export function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300; // 5 dakika
  return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 ?? ""));
}
Doğrulama — Python
import hmac, hashlib, time

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return abs(time.time() - int(parts["t"])) < 300 and hmac.compare_digest(expected, parts.get("v1", ""))

Kaynaklar