Toplu metaobject içe aktarma
POST /custom-data/metaobjects/{type}/entries/bulk — scope (yetki) write_metaobjects, Idempotency-Key zorunlu.
Tek kayıtlık PUT …/entries/{handle} rotasının toplu kardeşi. Bir içerik türünü tek seferde
yüklemek — bir şehir rehberinin 1.500 şehir sayfası, bir ırk rehberinin 350 ırk sayfası — ve sonra yeniden
senkronlamak için kullanın. Her satır tek kayıtlık PUT ile aynı doğrulamadan geçer.
{ "dryRun": false, "mode": "merge", "entries": [ { "handle": "abbots-langley", "fields": { "name": "Abbots Langley", "population": "10472", "hero": "https://images.example.org/towns/abbots-langley.jpg" }, "seoTitle": "Abbots Langley — yerel rehber", "publish": "published", "externalKey": "ons:E04012345" } ]}| Alan | Anlamı |
|---|---|
entries |
1 ile 500 satır. Bir handle istekte yalnızca bir kez geçebilir. |
entries[].handle |
Kaydın anahtarı ve URL parçası: küçük harf, rakam, - ve _; en fazla 128 karakter. Var olan handle güncellenir, yenisi oluşturulur. |
entries[].fields |
Alan anahtarı → değer. Aşağıdaki Alan değerleri bölümüne bakın. |
entries[].seoTitle, seoDescription |
Gönderilmezse saklı değer korunur (merge); "" temizler. En fazla 256 / 512 karakter. |
entries[].publish |
published (şimdi yayında — zaten yayında olan kayıt ilk tarihini korur), draft ya da gönderilmezse mevcut durum korunur. Yeni kayıt taslak başlar. |
entries[].publishedAt |
Açık yayın tarihi (ISO 8601); gelecekteki tarih zamanlar. publish’e göre önceliklidir. |
entries[].externalKey |
Kaynak kaydın sizin taraftaki kimliği (tür içinde benzersiz, görüntülenmez). |
dryRun |
true: her satır yazma ile aynı şekilde doğrulanır, hiçbir şey yazılmaz, görsel indirilmez. |
mode |
merge (varsayılan): göndermediğiniz alan saklı değerini korur. replace: gönderdiğiniz alanlar kaydın alan kümesinin tamamıdır. |
Alan değerleri
Bölüm başlığı “Alan değerleri”Değerler gerçek JSON ya da bir tablo hücresindeki metin olabilir; sunucu metni alanın türüne çevirir: sayılar
("12", "3.25" — virgül değil nokta), boolean (true/false, yes/no, 1/0, evet/hayır), list.* (JSON dizi ya da
dikey çizgiyle ayrılmış tek hücre, a\|b\|c), json/money/… (JSON metni), dosya alanları (medya kimliği ya da
https:// görsel URL’si). null ya da boş metin değer yok demektir; merge modunda o alanı temizler.
Çevrilemeyen değer alanın doğrulayıcısına olduğu gibi gider ve satır alanın kendi gerekçesiyle başarısız olur.
Görsel URL’leri
Bölüm başlığı “Görsel URL’leri”Dosya alanındaki https:// URL’si medya içe aktarıcı üzerinden mağazanın medya
kütüphanesine alınır ve kayıt varlık kimliğini saklar. Bunun için uygulamanın write_media yetkisine de sahip
olması gerekir. İstek başına 100 farklı görsel URL’si; satırlar arasında tekrar eden URL bir kez sayılır ve bir
kez indirilir. Başarısız görsel yalnızca kendi satırını düşürür.
Yanıt — geçerli istekte 200
Bölüm başlığı “Yanıt — geçerli istekte 200”Her satır için status: created, updated, unchanged (saklı olanla aynı — hiçbir şey yazılmadı), failed
(errorCode ve error ile). Deneme çalıştırmasında created/updated ne olacağını söyler. Aynı dosyayı yeniden
göndermek bu yüzden zararsızdır: her satır unchanged döner.
İstek düzeyinde ret — 400 ve { "code", "error" }, hiçbir şey yazılmaz: no_entries, too_many_entries,
duplicate_handles, invalid_mode, too_many_images. 404: mağazada {type} türü yok. 403: token’da
write_metaobjects yok.
curl -X POST https://www.example-store.com/custom-data/metaobjects/town/entries/bulk \ -H "Authorization: Bearer ciqra_at_..." \ -H "Idempotency-Key: towns-2026-11-01-batch-1" \ -H "Content-Type: application/json" \ -d '{"dryRun":true,"entries":[{"handle":"whitby","fields":{"name":"Whitby","population":"13213"},"publish":"published"}]}'Python — 500’lük gruplar halinde bir CSV
Bölüm başlığı “Python — 500’lük gruplar halinde bir CSV”import csv, uuid, requests
STORE = "https://www.example-store.com"TOKEN = "ciqra_at_..." # POST /apps/token (yetkiler: write_metaobjects, write_media)TYPE = "town"BATCH = 500
def rows(path): with open(path, newline="", encoding="utf-8") as f: for r in csv.DictReader(f): yield { "handle": r["slug"], "fields": {"name": r["name"], "population": r["population"], "hero": r["image_url"]}, "seoTitle": r["meta_title"], "publish": "published", }
def send(batch, dry_run): # Aynı grubun tekrarı aynı anahtarı kullanır ve ilk yanıtı geri alır. key = f"{TYPE}-{'dry' if dry_run else 'run'}-{uuid.uuid5(uuid.NAMESPACE_URL, repr(batch))}" response = requests.post( f"{STORE}/custom-data/metaobjects/{TYPE}/entries/bulk", headers={"Authorization": f"Bearer {TOKEN}", "Idempotency-Key": key}, json={"entries": batch, "dryRun": dry_run}, timeout=300, ) response.raise_for_status() return response.json()
entries = list(rows("towns.csv"))for dry_run in (True, False): # önce hepsini kontrol et, sonra yaz failed = 0 for start in range(0, len(entries), BATCH): result = send(entries[start:start + BATCH], dry_run) failed += result["failed"] for r in result["results"]: if r["status"] == "failed": print(start + r["index"], r["handle"], r["errorCode"], r["error"]) if dry_run and failed: raise SystemExit(f"{failed} satır başarısız olacak; düzeltip yeniden çalıştırın")