# Stok girmek, saymak ve taşımak

> **Ne yaparsınız:** Depoya mal girişi yapar, stok sayar, fire/kayıp yazar, depolar arasında taşır ve yanlış belgeyi tersine çevirirsiniz.
> **Hangi uçlar:** [Stok girişi yap](https://developer.siparis.app/uc/stok-girisi-yap), [Stok sayımı yap](https://developer.siparis.app/uc/stok-sayimi-yap), [Fire ve kayıp yaz](https://developer.siparis.app/uc/fire-ve-kayip-yaz), [Depolar arası taşı](https://developer.siparis.app/uc/depolar-arasi-tasi), [Stok belgesini geri al](https://developer.siparis.app/uc/stok-belgesini-geri-al)
> **Gereken izin:** `inventory:write`; alış fiyatı, KDV seçimi ve tedarikçi için ayrıca `costs:write`, iç not için `internal_notes:write`.

API adresi `https://api.siparis.app/v1`. Depoları ve güncel miktarı okumak için ayrıca `inventory:read` kapsamı (okuma izni) gerekir; maliyetleri görmek `costs:read`, iç notları görmek `internal_notes:read` ister.

Anahtarınızı sunucuda `SIPARIS_API_KEY` ortam değişkeninde tutun; sohbete veya URL'ye yazmayın. [Stoku eşitlemek](https://developer.siparis.app/stoku-esitlemek) rehberiyle `var_` seçenek ve `loc_` depo kimliklerini bulun. Miktarlar ondalık metindir; adetle tutulan stokta tam sayı, kg/metre/litre gibi birimlerde en çok üç ondalık hane kabul edilir.

## Mal girişi

Aşağıdaki değerleri kendi deponuz ve stok kodunuzla değiştirin. Çok markalı işletmede gövdeye satış markanızın kimliğini `"store":"sto_…"` olarak ekleyin; tek markada ve marka sınırlı anahtarda atlanabilir. `location` her zaman açıkça seçilir; marka sınırlı anahtar yalnız `/locations` listesindeki depolara yazar.

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

| Alan | Tür | Açıklama | Örnek |
| --- | --- | --- | --- |
| `lines` | liste: nesne (en çok 500 öğe) | Gelen seçenekler, miktarları ve isteğe bağlı alış fiyatları. |  |
| `lines[].quantity` | sayı (en az 0; en çok 100000000) veya metin | İşlenecek miktar; en çok üç ondalık hane, adet biriminde tam sayı. | `"2"` |
| `location` | metin | İşlemin loc_ depo kimliği; /locations listesinden seçin. | `"loc_1234567890abcdef1234567890abcdef"` |

Bütün alanlar: [Stok girişi yap](https://developer.siparis.app/uc/stok-girisi-yap).

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/inventory/receipts" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: mal-girisi-20261016-001' \
  --data '{"location":"loc_1234567890abcdef1234567890abcdef","lines":[{"sku":"KUPA-MAVI","quantity":"10","unit_price":"120.00"}],"vat_included":true,"external_reference":{"id":"MAL-2026-001"}}'
```

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

```json
{
  "created_at": "2026-10-16T09:00:00Z",
  "id": "doc_1234567890abcdef1234567890abcdef",
  "kind": "receipt",
  "location": "loc_1234567890abcdef1234567890abcdef",
  "movements": {
    "data": [
      {
        "count_reason": null,
        "created_at": "2026-10-16T09:00:00Z",
        "currency": "TRY",
        "document": "doc_1234567890abcdef1234567890abcdef",
        "id": "mov_1234567890abcdef1234567890abcdef",
        "location": "loc_1234567890abcdef1234567890abcdef",
        "order": "ord_1234567890abcdef1234567890abcdef",
        "product": "prd_1234567890abcdef1234567890abcdef",
        "quantity_change": "-1.000",
        "reason": "sale",
        "variant": "var_1234567890abcdef1234567890abcdef",
        "variant_balance_after": "12.000"
      }
    ],
    "has_more": false,
    "next_cursor": null
  },
  "reversed_by": null,
  "reverses": null,
  "revision": 1,
  "to_location": "loc_1234567890abcdef1234567890abcdef"
}
```



Başarıda `201`, belgenin güncel modeli ve `Location: /v1/inventory/documents/doc_…` gelir. `ETag` belgenin sürüm etiketidir. Hareketler sayfalanır; `has_more=true` ise `next_cursor` (sonraki sayfanın yer imi) ile belgeyi okumaya devam edin.

Alış fiyatı isteğe bağlıdır; yazılmazsa maliyet değiştirilmez. KDV ayrımı ürünün kayıtlı oranıyla yapılır, yeni maliyet paneldeki ağırlıklı ortalama kuralından gelir. Tedarikçi, fatura numarası ve tarihi gibi isteğe bağlı alanlar [Stok girişi yap](https://developer.siparis.app/uc/stok-girisi-yap) sayfasındadır.

`external_reference.id` kendi sisteminizdeki belge numarasıdır; API bağlantınızda (paneldeki erişim kaydı; anahtar döndürmek bunu değiştirmez) bir kez kullanılabilir. Aynı numarayla yeni işlem `409 external_reference_conflict` verir. Bu alan tekrar anahtarının yerine geçmez.

## Aynı isteği güvenle tekrarlayın

Her POST için `Idempotency-Key` (tekrar anahtarı: aynı isteği güvenle yeniden göndermek için sizin ürettiğiniz benzersiz metin) zorunludur. Yanıt kaybolduğunda aynı gövde ve varsa aynı `If-Match` başlığıyla (belge siz okuduktan sonra değiştiyse işlemi durduran sürüm denetimi) aynı anahtarı gönderin: iş ikinci kez uygulanmaz, belgenin güncel hali `Idempotent-Replayed: true` ile döner. Örneğin sonradan tersine çevrilmiş girişin tekrar yanıtında `reversed_by` doludur. Yeni iş veya düzeltilmiş istek için yeni anahtar kullanın.

## Sayımda expected neden zorunlu?

`quantity` rafta saydığınız yeni miktardır. `expected`, saymaya başlamadan önce `/inventory/levels?variant=var_…&location=loc_…` yanıtında okuduğunuz **aynı deponun** miktarıdır; arada satış yapılırsa eski miktarın üzerine yazılmasını önler. Stok seviyesindeki `revision` (sürüm numarası) yalnız o seviyeye aittir; stok hareketi ürünün sürümünü değiştirmez.

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

| Alan | Tür | Açıklama | Örnek |
| --- | --- | --- | --- |
| `lines` | liste: nesne (en çok 500 öğe) | Sayımın miktarı ve her satır için zorunlu expected değeri. |  |
| `lines[].expected` | sayı (en az -100000000; en çok 100000000) veya metin · null olabilir | Zorunlu: okuduğunuz depo miktarı. Stok sayılmıyorsa açıkça null gönderin; değişmişse 409 stock_changed. | `"10"` |
| `lines[].quantity` | sayı (en az 0; en çok 100000000) veya metin | Saydığınız depo miktarı; sıfır olabilir. | `"12"` |
| `location` | metin | İşlemin loc_ depo kimliği; /locations listesinden seçin. | `"loc_1234567890abcdef1234567890abcdef"` |

Bütün alanlar: [Stok sayımı yap](https://developer.siparis.app/uc/stok-sayimi-yap).

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/inventory/counts" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: stok-sayimi-20261016-001' \
  --data '{"location":"loc_1234567890abcdef1234567890abcdef","lines":[{"sku":"KUPA-MAVI","quantity":"12","expected":"10"}],"reason":"count_diff"}'
```

`expected` uyuşmazsa hiçbir satır yazılmaz: `409 stock_changed`, ilk hata yanıtında `current_quantity` güncel miktarı verir. Stoğu tekrar okuyun, sayımı değerlendirin ve yeni anahtarla gönderin. Stok sayılmıyorsa `expected` yine zorunludur: açıkça `null` gönderin. Gizli geçmiş bakiye gösterilmez; ilk sayım panelle aynı şekilde sayımı başlatır. Sipariş üzerine hazırlanan ürünün stoğu sayılmaz.

Miktar zaten aynıysa ortak sayım servisi belge açmaz; `200 {"changed":false}` döner. Sayılmayan stokta “0 var” sayımı da sayımı başlatır. Bu belgesiz başarı tekrarlandığında işlem yeniden uygulanmaz.

## Fire veya kayıp

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/inventory/write_offs" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: stok-kaybi-20261016-001' \
  --data '{"location":"loc_1234567890abcdef1234567890abcdef","lines":[{"sku":"KUPA-MAVI","quantity":"1"}],"reason":"broken"}'
```

Miktar pozitif yazılır; servis stoktan düşer. `broken` hasarlı/kırık, `lost` kayıp, `other` diğer nedendir; `other` için `note` zorunludur. Giyim ve aksesuarda `defective`, `fitting`, `sample`; gıda ve kozmetikte `expired` de kullanılabilir. Panelin sektör listesi geçerlidir. Sayılmayan stoktan fire düşülmez; önce sayım yapılır.

## Depolar arasında taşıma

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/inventory/transfers" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: stok-tasima-20261016-001' \
  --data '{"location":"loc_1234567890abcdef1234567890abcdef","to_location":"loc_abcdef1234567890abcdef1234567890","lines":[{"sku":"KUPA-MAVI","quantity":"3"}]}'
```

Kaynak ve hedef farklı, açık ve anahtarın erişebildiği depolar olmalıdır. Kaynakta yeterli miktar yoksa `insufficient_stock` döner; kısmi taşıma yapılmaz. Toplam stok ve ortalama maliyet değişmez.

## Yanlış belgeyi tersine çevirin

Önce belgeyi okuyup `ETag` değerini alın. Aşağıdaki belge kimliğini ve `If-Match` değerini kendi yanıtınızla değiştirin.

```bash
curl --fail-with-body --silent --show-error \
  "${SIPARIS_API_URL:-https://api.siparis.app/v1}/inventory/documents/doc_1234567890abcdef1234567890abcdef/reverse" \
  -H "Authorization: Bearer $SIPARIS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: stok-ters-kayit-20261016-001' \
  -H 'If-Match: "1"' \
  --data '{}'
```

Mal girişi ve fire bir kez tersine çevrilebilir. Eski belge ve hareketler korunur; yeni belge `201` ve `Location` ile gelir. Ters belge `reverses`, özgün belge `reversed_by` alanıyla bağlanır. Mal satılmışsa ve ters kayıt yeni stok açığı yaratacaksa işlem reddedilir. Ortalama maliyet geçmişe döndürülmez. Sayım yeni sayımla, taşıma ters yönde yeni taşımayla düzeltilir.

`inventory.document_created` ve `inventory.document_reversed` belgeyi, `inventory.level_changed` depo bakiyesini bildirir. Olayları okumak `events:read` ve `inventory:read` ister. Not, tedarikçi ve maliyet olay yüküne girmez.

## Sık hatalar

| Kod | Yapılacak işlem |
| --- | --- |
| `insufficient_scope` | `inventory:write`, fiyat/tedarikçide `costs:write`, notta `internal_notes:write` kapsamını kontrol edin. |
| `not_found` | Kimlik türünü, işletmeyi ve anahtarın marka/depo sınırını kontrol edin. |
| `stock_changed` | Güncel depo miktarını okuyun; sayımı yeni anahtarla gönderin. |
| `insufficient_stock` | Kaynak miktarı aşılmıştır; fire veya taşıma miktarını düzeltin. |
| `invalid_stock_operation` | Kesirli birimi, sayılmayan stoğu, kapalı depoyu veya ters kayıt türünü kontrol edin. |
| `reserved_note` | Açıklama sistem işlemlerine ayrılmış bir ifadeyle eşleşiyor; kendi açıklamanızı yazın. Harf ve boşluk farkları eşleşmeyi değiştirmez. |
| `document_already_reversed` | Belgedeki `reversed_by` kaydını okuyun. |
| `revision_mismatch` | `If-Match` eski; güncel belgeyi okuyun. |
| `external_reference_conflict` | Önceki işlemde kullandığınız tekrar anahtarını bulun. |

Bütün alanlar ve yanıt örnekleri her ucun sayfasında: [Stok girişi yap](https://developer.siparis.app/uc/stok-girisi-yap), [Stok sayımı yap](https://developer.siparis.app/uc/stok-sayimi-yap), [Fire ve kayıp yaz](https://developer.siparis.app/uc/fire-ve-kayip-yaz), [Depolar arası taşı](https://developer.siparis.app/uc/depolar-arasi-tasi), [Stok belgesini geri al](https://developer.siparis.app/uc/stok-belgesini-geri-al). Okuma ve sürekli takip [stok eşitleme rehberinde](https://developer.siparis.app/stoku-esitlemek).
