# Ürün eklemek ve güncellemek

> **Ne yaparsınız:** Ürün ve seçenek ekler, fiyatı ve bilgileri günceller, markaya özel fiyat yazar, ürünü arşive alıp geri getirirsiniz.
> **Hangi uçlar:** [Ürün oluştur](https://developer.siparis.app/uc/urun-olustur), [Ürüne seçenek ekle](https://developer.siparis.app/uc/urune-secenek-ekle), [Seçenekleri listele](https://developer.siparis.app/uc/secenekleri-listele), [Ürünü güncelle](https://developer.siparis.app/uc/urunu-guncelle), [Seçeneği güncelle](https://developer.siparis.app/uc/secenegi-guncelle), [Marka fiyatını yaz](https://developer.siparis.app/uc/marka-fiyatini-yaz), [Ürünü arşivle](https://developer.siparis.app/uc/urunu-arsivle), [Ürünü geri getir](https://developer.siparis.app/uc/urunu-geri-getir), [Seçeneği arşivle](https://developer.siparis.app/uc/secenegi-arsivle)
> **Gereken izin:** `products:write`; maliyet için ayrıca `costs:write`, açılış stoğu için `inventory:write`, arşiv ve geri getirme için `archive:write`.

API adresi `https://api.siparis.app/v1`. Okuma için `products:read`, maliyeti yanıtta görmek için ayrıca `costs:read` gerekir; yazma kapsamı (izni) okuma izni vermez.

Anahtarı sunucunuzdaki `SIPARIS_API_KEY` ortam değişkeninde tutun. Örnekler bash ve curl ile çalışır. Her yeni işte yeni `Idempotency-Key` (tekrar anahtarı: aynı isteği güvenle yeniden göndermek için sizin ürettiğiniz benzersiz metin) kullanın. Yanıt kaybolursa aynı gövde ve aynı anahtarla tekrarlayın: iş ikinci kez uygulanmaz, `Idempotent-Replayed: true` ile kaydın **güncel** hali döner.

## Basit ürün ekleyin

Tek markada ve marka sınırlı anahtarda hedef marka atlanabilir. Çok markalı işletmede `store: "sto_…"` veya `stores: ["sto_…", "sto_…"]` gönderin; kimlikleri `GET /stores` ile bulun. Marka sınırlı anahtar başka markaya yazamaz. İki marka kavramını karıştırmayın: `store` (`sto_`) sizin satış markanızdır, `brand` (`brd_`) ürünün üretici markasıdır.

İlk örnek için zorunlu alanlar (POST /v1/products):

| Alan | Tür | Açıklama | Örnek |
| --- | --- | --- | --- |
| `name` | metin (en çok 500 karakter) | Ürün adı. | `"Seramik Kupa"` |

Bütün alanlar: [Ürün oluştur](https://developer.siparis.app/uc/urun-olustur).

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/products" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: urun-20261016-001' \
  --data '{"name":"Seramik Kupa","description":"300 ml seramik kupa","unit":"adet","tax_rate":"20","price":"120.00","sku":"KUPA-001","opening_stock":"10","external_reference":{"id":"ERP-KUPA-001"}}'
```

Örnek HTTP 201 yanıtı (uydurma veri):

```json
{
  "archived": false,
  "brand": "brd_1234567890abcdef1234567890abcdef",
  "code": "KUPA-001",
  "compare_price": "150.00",
  "created_at": "2026-10-16T09:00:00Z",
  "currency": "TRY",
  "description": "Seramik kupa, 300 ml.",
  "id": "prd_1234567890abcdef1234567890abcdef",
  "images": [
    "https://example.com/kupa.jpg"
  ],
  "kind": "standard",
  "made_to_order": false,
  "maximum_quantity": "100.000",
  "minimum_quantity": "1.000",
  "name": "Seramik Kupa",
  "pool_unit": "adet",
  "preparation": "3 iş günü",
  "price": "120.00",
  "quantity_step": "1.000",
  "short_description": "Seramik kupa",
  "slug": "ornek-kupa",
  "status": "active",
  "tax_rate": "20.00",
  "tax_status": "standard",
  "unit": "adet",
  "updated_at": "2026-10-16T09:00:00Z"
}
```



Yanıtta `201`, `prd_` ürün kimliği, varsayılan `var_` seçeneği, `Location` ve `ETag` (sürüm etiketi) gelir. Para TRY cinsinden ondalık metindir. `categories` ve `brand` yalnız mevcut kayıtları bağlar; kategori ve ürün markası oluşturmak için [Kategori, ürün markası ve kupon yazmak](https://developer.siparis.app/kupon-ve-kategori) rehberine bakın.

`external_reference.id` kendi sisteminizdeki ürün kimliğidir; API bağlantınızda (paneldeki erişim kaydı, `grt_`; anahtar döndürmek bunu değiştirmez) ve kaynak türünde bir kez kullanılabilir. Aynı dış kimlikle ikinci ürün `409 external_reference_conflict` verir.

Görseller URL ile verilir; dosya yükleme bu uçta henüz yoktur. Birim, KDV, satış durumu ve fiyat doğrulamaları panelle aynıdır; fiyatsız ürün için `status: "draft"` kullanın. Bütün alanlar [Ürün oluştur](https://developer.siparis.app/uc/urun-olustur) sayfasındadır.

## Seçenekli ürün ekleyin

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/products" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: urun-20261016-002' \
  --data '{"name":"Renkli Kupa","price":"120.00","variants":[{"name":"Mavi","sku":"KUPA-MAVI","options":[{"name":"Renk","value":"Mavi"}],"price_rule":{"kind":"tl","value":"20.00"},"opening_stock":"5"},{"name":"Beyaz","sku":"KUPA-BEYAZ","options":[{"name":"Renk","value":"Beyaz"}],"price_rule":null,"opening_stock":"5"}]}'
```

Mavi seçeneğin satış fiyatı 140 TL, beyazınki 120 TL olur. `price_rule` ürün fiyatından farktır: `kind` değeri `tl` veya `percent`, `value` negatif olabilir; `price_rule: null` ürün fiyatını izler. Kural ile mutlak `price`/`compare_price` aynı istekte gönderilmez. Açılış stoğunu seçenekli üründe her seçeneğe yazın. Her seçenek ayrıca kendi `external_reference` alanını alabilir.

Var olan ürüne [Ürüne seçenek ekle](https://developer.siparis.app/uc/urune-secenek-ekle) ile aynı seçenek gövdesini gönderin. Açık sipariş varken de seçenek eklenebilir: ilk seçenek varsayılan seçeneğin kimliğini ve stoğunu korur. Mevcut stoğu değiştirecekseniz `opening_stock` yanında gördüğünüz `expected_stock` gerekir; normal stok işlemleri için [stok yazma rehberini](https://developer.siparis.app/stok-yazmak) kullanın. Setin parçası olan varsayılan seçeneğin dönüşümü paneldeki gibi engellenir.

## SKU ile seçeneği bulun

```bash
curl --fail-with-body --silent --show-error --get \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/variants" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  --data-urlencode 'sku=KUPA-MAVI'
```

`GET /v1/variants?sku=KUPA-MAVI` sonucundaki `var_` kimliğiyle `PATCH /variants/{id}` çağırabilirsiniz. SKU ve barkod, işletmede canlı seçenekler arasında baştaki/sondaki boşluk ve harf büyüklüğü dikkate alınmadan tekildir.

## Fiyatı güncelleyin

`prd_…` yerine ürününüzün kimliğini, `If-Match` yerine en son GET veya yazma yanıtının ETag değerini tırnaklarıyla yazın. Başlığı okumak için curl’e `--include` ekleyebilirsiniz.

```bash
curl --fail-with-body --silent --show-error -X PATCH \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/products/prd_1234567890abcdef1234567890abcdef" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: urun-fiyat-20261016-001' \
  -H 'If-Match: "0123456789abcdef"' \
  --data '{"price":"140.00"}'
```

`If-Match` isteğe bağlıdır; ürün siz okuduktan sonra değiştiyse yazmayı durdurur. ETag, anahtarınızın görebildiği ürün, seçenek, kategori ve marka fiyatı alanlarının içerik özetidir; yanıtta `revision` alanı bulunmaz. Stok miktarı, stok sayım durumu ve `updated_at` değişiklikleri özete katılmaz. `include` (yanıta alt kayıt ekleme) ve `archived` parametreleri etiketi değiştirmez; aynı anahtarla okuduğunuz ETag’i kullanın. `412 revision_mismatch` alırsanız ürünü yeniden okuyup yeni tekrar anahtarıyla deneyin. PATCH’te atlanan alan korunur; `categories: []` kategori bağlarını, `brand: null` ürün markasını kaldırır.

Seçenek ayrıntıları [Seçeneği güncelle](https://developer.siparis.app/uc/secenegi-guncelle) ile güncellenir; seçeneğin ETag’i bağlı ürünün ETag’idir. `is_default: true` olan varsayılan satırı paneldeki gibi `PATCH /products/{id}` ile düzenleyin; seçenek PATCH/arşiv ucunda yalnız ürünün eklenmiş seçenekleri kullanılır. Marka fiyatında da varsayılan satır için `variant` göndermeyin.

## Markaya özel fiyat yazın

Aşağıdaki `sto_` ve `prd_` kimliklerini değiştirin. Gövdeye eklenen isteğe bağlı `variant: "var_…"` yalnız o seçeneğin marka fiyatını yazar. Diğer markaların fiyatları ve ürün bağları korunur.

```bash
curl --fail-with-body --silent --show-error -X PUT \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/store-prices/sto_1234567890abcdef1234567890abcdef/prd_1234567890abcdef1234567890abcdef" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: marka-fiyat-20261016-001' \
  --data '{"price":"110.00","compare_price":"140.00"}'
```

Alanlar [Marka fiyatını getir](https://developer.siparis.app/uc/marka-fiyatini-getir) okumasıyla aynıdır. `price` ve `compare_price` ikisi de zorunludur; ikisi `null` ise özel fiyat satırı kalkar ve katalog fiyatı devralınır. Yanıt, güncel `store_prices` listesini içeren üründür; ETag de ürüne aittir. Panelle aynı vitrin önbelleği geçersizleştirilir. Katalog fiyatı değişiklikleri panelin fiyat geçmişine girer; markaya özel fiyatlar paneldeki gibi bu geçmişin dışında kalır.

## Arşivleyin ve geri getirin

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/products/prd_1234567890abcdef1234567890abcdef/archive" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: urun-arsiv-20261016-001' \
  --data '{}'
```

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/products/prd_1234567890abcdef1234567890abcdef/restore" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: urun-geri-20261016-001' \
  --data '{}'
```

Arşiv kayıt silmez; ürün vitrinden ve varsayılan listelerden kalkar, yeni siparişe eklenemez. Açık sipariş/iade varsa panelin koruması işlemi engeller. Önceden satışta olan ürün `draft` döner; diğer satış durumları korunur; arşivde sıfırlanan stok ortak stok defteriyle geri gelir. Ürünle birlikte arşivlenen seçenekler geri gelir; önceden ayrı arşivlenenler gelmez. Seçenek arşivi [Seçeneği arşivle](https://developer.siparis.app/uc/secenegi-arsivle); bağımsız seçenek geri getirme ucu henüz yoktur. Arşivdeki kaydı okumak için `archived=true` kullanın.

## Sık hatalar ve olaylar

| Yanıt | Yapılacak işlem |
| --- | --- |
| `403 insufficient_scope` | Anahtardaki ürün, maliyet, stok veya arşiv iznini kontrol edin. |
| `409 code_taken` | İlk yanıttaki `existing_product` / `existing_variant` görünür kod sahibini gösterir; mevcut kaydı güncelleyin veya farklı kod seçin. |
| `409 external_reference_conflict` | Dış kimliğin mevcut ürün/seçeneğini kullanın. |
| `409 conflict` | Panelin açık sipariş/iade koruması gibi ticari engelin ayrıntısını okuyun. |
| `409 product_restore_conflict` | Ürünün arşiv durumunu ve geri getirme engelini kontrol edin. |
| `412 revision_mismatch` | Güncel ETag’i okuyup değişikliği yeniden değerlendirin. |

`product.created/updated/archived/restored`, `variant.created/updated/archived/restored` ve `store_price.updated` olayları panelle aynı kalıcı olay kanıtlarından üretilir. Seçenek olayında `data.object.id` seçeneği, `data.object.product` ürünü gösterir. `events:read` ve `products:read` ile izleyin; ayrıntılar [olay akışında](https://developer.siparis.app/olaylar).
