Ne işe yarar
GM, Opel ve Chevrolet parça kataloğunu (epc.vin) kendi yazılımınızdan sorgulamak için. Asıl iş: müşterinizin aracının VIN'inden o araca uyan parça numaralarını bulmak ve stoğunuzdakilerle karşılaştırmak.
İki yol var, sonuçları aynıdır:
POST /parts/check: Elinizdeki numaraları (en çok 500) gönderirsiniz, her biri için "uyar / uymaz" ve kataloğun neresinde olduğu döner. Az sayıda aday parça için en kolayı budur.GET /vehicles/{vin}/parts: Araca uyan bütün numaraları alırsınız, karşılaştırmayı kendi sisteminizde yaparsınız. Tüm stoğu taramak için uygundur.
Araç, epc.vin arayüzündeki varsayılan süzgeçlerle değerlendirilir (VIN Süzgeci, UltraVIN ve Yıl Süzgeci açık, parça geçmişi gizli). Arayüzde o aracın sayfalarında görünen her parça API'de de uyar.
Alan adları İngilizce, değerler (açıklamalar, hata ve eşleşme kodları) Türkçedir. Yanıtlar UTF-8 JSON'dur ve Accept-Encoding: gzip ya da br gönderirseniz sıkıştırılır.
Hızlı başlangıç
export EPC_API_KEY=epc_... # yönetimden aldığınız anahtar
# Araç
curl -s https://api.epc.vin/v1/vehicles/KL1SF48W9BB261734 \
-H "Authorization: Bearer $EPC_API_KEY"
# Bu numaralar bu araca uyar mı?
curl -s https://api.epc.vin/v1/parts/check \
-H "Authorization: Bearer $EPC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"vin": "KL1SF48W9BB261734", "part_numbers": ["96829637", "95955933", "13300900"]}'
Makine okunur tanım (OpenAPI 3.1): /v1/openapi.json. Postman, Insomnia ya da kod üreticilerine doğrudan verilebilir.
Anahtar ve güvenlik
Her istekte Authorization: Bearer <anahtar> başlığı gönderilir. Anahtarlar epc_ ile başlar ve 53 karakterdir. Bunları epc.vin yönetimi verir. Anahtar yalnız verildiği anda bir kez gösterilir; biz yalnız özetini saklarız, kaybolursa yenisi verilir.
- Anahtarı yalnız sunucunuzda tutun: bir ortam değişkeninde ya da sır deposunda. Tarayıcıda, mobil uygulamada ya da kaynak kodunda tutmayın. API tarayıcıdan çağrılmaya kapalıdır (CORS izni yoktur).
- Her sistem için ayrı anahtar isteyin (ör. "stok sunucusu", "test"). Biri sızarsa yalnız o iptal edilir.
- Değiştirirken önce yenisini alın, sisteminize koyun, sonra eskisini iptal ettirin. Böylece kesinti olmaz.
- Yalnız HTTPS. Yanıtlar önbelleğe alınmaz (
Cache-Control: no-store). - Her yanıtta bir
X-Request-Idbaşlığı döner. Bir sorun bildirirken bu kimliği de iletin.
Bir adresten 15 dakikada 30 hatalı anahtar denenirse o adres bir süre bekletilir (cok_fazla_hatali_anahtar).
Sınırlar
| Sınır | Varsayılan | Aşılınca |
|---|---|---|
| Hesap başına dakikada istek | 60 | 429 istek_siniri |
| Günde farklı VIN (İstanbul saatiyle; aynı gün aynı VIN yeniden sayılmaz) | 500 | 429 gunluk_vin_kotasi |
| Bir kontrolde parça numarası | 500 | 400 cok_fazla_numara |
| İstek gövdesi | 64 KB | 413 govde_cok_buyuk |
Sınırlar hesaba özeldir; ihtiyacınız farklıysa yönetimle konuşun. Her yanıtta dakika sınırının durumu IETF taslağındaki başlıklarla gelir:
RateLimit-Policy: "dakika";q=60;w=60
RateLimit: "dakika";r=57;t=41 # bu dakikadan 57 istek kaldı, 41 sn sonra yenilenir
429 yanıtlarında Retry-After kaç saniye bekleneceğini söyler. Lütfen o kadar bekleyip yeniden deneyin, art arda denemeyin.
Hatalar
Hatalar her uçta aynı biçimdedir. code programlar için sabittir, message insanlar için açıklamadır ve değişebilir.
{ "error": { "code": "gecersiz_vin", "message": "VIN 17 karakter olmalı; harf ve rakam, I, O ve Q yok." } }
| Durum | Kod | Anlamı |
|---|---|---|
| 400 | gecersiz_vin | VIN 17 karakter değil ya da I, O, Q içeriyor |
| 400 | gecersiz_numara | Parça numarası harf ve rakam dışında karakter içeriyor ya da 32 karakterden uzun |
| 400 | gecersiz_istek | Gövde ya da sorgu okunamadı, tanınmayan bir alan var |
| 400 | numara_yok | part_numbers boş |
| 400 | cok_fazla_numara | 500'den fazla numara |
| 401 | anahtar_yok | Authorization başlığı yok |
| 401 | gecersiz_anahtar | Anahtar tanınmıyor |
| 401 | anahtar_iptal | Anahtar iptal edilmiş |
| 403 | hesap_kapali | API hesabı kapalı ya da süresi doldu |
| 404 | arac_bulunamadi | VIN geçerli ama katalogda aracı yok |
| 404 | donanim_bulunamadi | Verilen equipment_id bu VIN'in araçlarından değil |
| 404 | parca_bulunamadi | Parça numarası katalogda yok |
| 404 | bulunamadi | Böyle bir adres yok |
| 405 | yontem_desteklenmiyor | Adres bu yöntemle çağrılmaz (ör. GET yerine POST) |
| 413 | govde_cok_buyuk | Gövde 64 KB'tan büyük |
| 415 | json_bekleniyor | Content-Type: application/json değil |
| 429 | istek_siniri | Dakika sınırı doldu |
| 429 | gunluk_vin_kotasi | Günlük VIN kotası doldu (bugün sorulan VIN'ler yine sorulabilir) |
| 429 | cok_fazla_hatali_anahtar | Bu adresten çok fazla hatalı anahtar denendi |
| 500 | sunucu_hatasi | Bizim tarafta bir hata; X-Request-Id ile bildirin |
VIN'in aracı
GET/vehicles/{vin}
VIN'i çözer. Bir VIN bazen birden çok donanıma denk gelir. O durumda diğer uçlara equipment_id verilir; verilmezse ilk araç kullanılır. Bu uç günlük VIN kotasına sayılır.
{
"vin": "KL1SF48W9BB261734",
"vehicles": [
{
"equipment_id": 2986,
"make": "Chevrolet",
"model": "AVEO (T250 / T255) [EUR] (2006 - 2011)",
"catalog_code": "T06",
"catalog_name": "T06",
"equipment_name": "AVEO (T250/T255) [EUR]",
"production_date": null,
"source": "arac_kaydi"
}
]
}
source aracın nereden bulunduğunu söyler. arac_kaydi: VIN katalogun araç kayıtlarında var, donanımı (motor, şanzıman, seçenekler) biliniyor. vin_cozumleme: VIN kayıtlarda yok, VIN'in kendisinden çözüldü. Donanımı daha az bilindiği için bu araçlara uyan parça listesi daha geniştir; bir parçayı satmadan önce kullanım bilgisine (usage) bakın.
Parça kontrolü
POST/parts/check
Gönderdiğiniz parça numaralarının araca uyup uymadığını söyler. Her numara, gönderildiği sırayla ve gönderildiği yazımla yanıtlanır. Bu uç günlük VIN kotasına sayılır.
İstek
| Alan | Tür | |
|---|---|---|
vin | metin | Zorunlu. Küçük harf de olur. |
part_numbers | metin dizisi | Zorunlu, 1 ile 500 arası. GM parça numarası ya da Opel KAT numarası. |
equipment_id | sayı | İsteğe bağlı. VIN birden çok donanıma denk geliyorsa hangisi. |
Numaralar karşılaştırılırken boşluk, tire, nokta ve eğik çizgi atılır, harfler büyütülür: 13 300 900, 13-300-900 ve 13300900 aynıdır. Opel KAT numarası (6 50 104) da tanınır.
{ "vin": "KL1SF48W9BB261734", "part_numbers": ["96829637", "95955933", "13300900", "abc;"] }
Yanıt
{
"vin": "KL1SF48W9BB261734",
"vehicle": { "equipment_id": 2986, "make": "Chevrolet", "model": "AVEO (T250 / T255) [EUR] (2006 - 2011)", ... },
"summary": { "asked": 4, "fits": 2 },
"results": [
{
"part_number": "96829637",
"fits": true,
"match": "birebir",
"catalog_part_numbers": ["96829637"],
"places": [
{
"catalog_part_number": "96829637",
"group": ["YAKIT & MOTOR KONTROL", "YAKIT"],
"page_code": "2111",
"page_title": "YAKIT DEPOSU II (2111)",
"callout": "1",
"description": "DEPO A-YAKIT 45L",
"usage": "(BASE,LS,LT,E) (69,08,48) (&LDT/LMU)",
"quantity": "1",
"notes": [],
"not_serviced": false
}
]
},
{ "part_number": "95955933", "fits": true, "match": "yeni_numara", "catalog_part_numbers": ["96829637"], "places": [ ... ] },
{ "part_number": "13300900", "fits": false, "reason": "araca_uymuyor" },
{ "part_number": "abc;", "fits": false, "reason": "gecersiz_numara" }
]
}
Eşleşme türleri (match)
birebir | Numara (ya da KAT numarası), aracın kataloğunda araca uyan bir satırda geçiyor. |
yeni_numara | Katalog eski bir numarayı listeliyor; gönderdiğiniz numara onun yerine geçen yenisi. Genellikle stokta tutulması gereken budur. |
eski_numara | Katalog yeni numarayı listeliyor; gönderdiğiniz numara onun yerini aldığı eskisi. Stoktaki eski parça çoğu zaman kullanılabilir, ama satmadan önce kontrol edin. |
Uymayanlarda reason: araca_uymuyor (numara katalogda var ama bu araca değil), katalogda_yok (numara hiçbir katalogda yok), gecersiz_numara (biçim hatalı). Bir numaranın en çok 20 yeri döner. Yerine geçen numaralar GM Avrupa ve GM Daewoo fiyat kitaplarından okunur.
Araca uyan tüm parçalar
GET/vehicles/{vin}/parts ?equipment_id=
Araca uyan her parça numarası bir kez, katalog sırasıyla (grup grup, sayfa sayfa) döner; her biri yerleri ve yerine geçen yeni numaralarıyla gelir. Kayıtlı bir araç için tipik olarak 1.500–3.000 numara, sıkıştırılmış hâliyle yaklaşık 50 KB tutar; VIN çözümlemesiyle bulunan bir araçta (source: vin_cozumleme) 10.000'i geçebilir, sıkıştırılmış hâliyle 500 KB, sıkıştırmasız 8 MB. Bu yüzden Accept-Encoding: gzip göndermeyi unutmayın (çoğu HTTP kütüphanesi kendiliğinden gönderir). Bir aracın ilk listesi 2–3 saniye sürebilir; aynı aracın sonraki istekleri 30 dakika boyunca hızlıdır. Bu uç günlük VIN kotasına sayılır.
{
"vin": "KL1SF48W9BB261734",
"vehicle": { ... },
"count": 1776,
"parts": [
{
"part_number": "96829637",
"description": "DEPO A-YAKIT 45L",
"replaced_by": ["95955933"],
"places": [ { "group": ["YAKIT & MOTOR KONTROL", "YAKIT"], "page_code": "2111", "callout": "1", "quantity": "1", ... } ]
}
]
}
replaced_by, numaranın yerine geçen numaralardır; zincir sırasıyla gelir, en yenisi sondadır. Stoğunuzda yeni numara varsa o da bu araca uyar.
Parça geçmişi
GET/parts/{part_number}
Parçanın yerine geçen numaraları (zincir sırasıyla) ve yerini aldığı eski numaraları döner. Stok kartlarınızı güncel numarayla eşlemek için kullanabilirsiniz. VIN kotasına sayılmaz.
{ "part_number": "13300900", "replaced_by": ["13363092", "13403607", "13473421"], "replaces": [] }
Kullanım
GET/usage
{
"account": "yedekparca",
"limits": { "requests_per_minute": 60, "vins_per_day": 500, "part_numbers_per_check": 500 },
"today": { "vins": 12, "requests": 40 }
}
Stokla karşılaştırma
Müşteri tezgâhta, VIN elinizde. Stokta olan ve araca uyan parçaları göstermek için iki örnek:
Az sayıda aday: kontrol
import os, requests
API = "https://api.epc.vin/v1"
KEY = os.environ["EPC_API_KEY"]
s = requests.Session()
s.headers["Authorization"] = f"Bearer {KEY}"
def uyanlar(vin, stok_numaralari):
"""Stoktaki numaralardan araca uyanlar, eşleşme türüyle."""
uyan = []
for i in range(0, len(stok_numaralari), 500):
r = s.post(f"{API}/parts/check", json={"vin": vin, "part_numbers": stok_numaralari[i:i + 500]}, timeout=30)
if r.status_code == 429:
raise RuntimeError(f"sınır: {r.json()['error']['message']} ({r.headers.get('Retry-After')} sn)")
r.raise_for_status()
uyan += [x for x in r.json()["results"] if x["fits"]]
return uyan
for p in uyanlar("KL1SF48W9BB261734", ["96829637", "95955933", "13300900"]):
yer = p["places"][0]
print(p["part_number"], p["match"], " › ".join(yer["group"]), yer["description"])
Bütün stok: liste
def stokta_uyanlar(vin, stok): # stok: {"96829637": 3, ...} (numara → adet)
r = s.get(f"{API}/vehicles/{vin}/parts", timeout=60)
r.raise_for_status()
sade = lambda n: "".join(ch for ch in n if ch.isalnum()).upper()
stok = {sade(n): adet for n, adet in stok.items()}
for p in r.json()["parts"]:
# Katalogdaki numara ya da onun yerine geçen yenilerinden biri stokta mı?
for n in [p["part_number"], *p["replaced_by"]]:
if stok.get(sade(n)):
yield n, p["description"], stok[sade(n)]
break
Aynı müşteri için tekrar tekrar sorgu atmayın; aracın listesini kendi tarafınızda bir süre saklayabilirsiniz. Katalog verisi değişmez.
Notlar ve sürümler
- Sürüm yolu
/v1. Geriye uyumlu eklemeler (yeni alan, yeni uç) bu sürümde yapılır, bu yüzden tanımadığınız alanları görmezden gelin. Uyumu bozan bir değişiklik olursa/v2açılır ve/v1bir süre çalışmaya devam eder. - Değerlerin Türkçe olması şimdilik böyle; kodlar (
birebir,araca_uymuyor…) sabittir. - Bu belge sunucuyla birlikte yayımlanır: gördüğünüz belge her zaman çalışan API'nin belgesidir.
2026-10 · v1.0 ilk sürüm.