Fatura tarafını Paraşüt API ile otomatikleştirdikten sonra sıra genellikle sevkiyata gelir: depodan çıkan malın irsaliyesini kesmek, alıcı e-İrsaliye kullanıyorsa resmileştirmek, size gelen e-İrsaliyeleri kabul ya da reddetmek ve irsaliyeyi doğru faturayla eşleştirmek. Paraşüt API v4'te bunların hepsi shipment_documents kaynağı ve onun etrafındaki birkaç uç üzerinden yapılır.

Bu yazıda irsaliye oluşturma, listeleme ve düzenleme; e_despatch_inboxes ile alıcı posta kutusunu bulma; legalize ile e-İrsaliye gönderme ve trackable job takibi; gelen e-İrsaliyeleri (inbound_e_despatches) yanıtlama ve içe aktarma; son olarak fatura ile irsaliye eşleştirme konularını tek tek ele alıyoruz. Hangi belgeyi kesmeniz gerektiği mevzuatla ve mali müşavirinizle belirlenir; burada yalnızca API tarafını anlatıyoruz. Genel kurulum için Paraşüt entegrasyonu genel rehberine bakabilirsiniz.

Paraşüt API'de irsaliye ile ilgili kaynaklar

Kaynak / UçNe işe yarar
shipment_documentsİrsaliye kaydı (giden ya da gelen); kalemleri stock_movements
e_despatch_inboxesAlıcının aktif e-İrsaliye posta kutularını VKN/TCKN ile listeler
shipment_documents/{id}/legalizeGiden irsaliyeyi e-İrsaliye olarak resmileştirir (202 + trackable job)
shipment_documents/{id}/e_despatchResmileşmiş irsaliyenin e-İrsaliye ve zarf bilgileri
inbound_e_despatchesFirmanıza gelen e-İrsaliyeler; kabul, kısmi kabul, ret, içe aktarma
trackable_jobs/{id}Arka planda çalışan işin durumu: running, done, error

Bu uçlar müşteri ve ürün kayıtlarına dayanır. Cari ve ürün hazırlığını cari hesap oluşturma ve ürün, stok ve depo yönetimi yazılarında anlattık.

İrsaliye oluşturma (POST /shipment_documents)

İrsaliye oluşturma (POST /shipment_documents): Liste ucunda page[size] en fazla 25'tir. Belgelenen filtreler..., include değerleri, Arşivlemede zaten arşivlenmiş, arşivden...

İrsaliye yapısal olarak satış faturasına benzer, ama fatura kalemleri (details) yerine relationships.stock_movements dizisi kullanılır. Yönü inflow alanı belirler: false sevk (giden) irsaliyesi, true giriş (gelen) irsaliyesidir.

bash
curl -X POST "https://api.parasut.com/v4/{company_id}/shipment_documents" \
  -H "Authorization: Bearer $PARASUT_ACCESS_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "type": "shipment_documents",
      "attributes": {
        "issue_date": "2026-11-03",
        "shipment_date": "2026-11-03T10:00:00Z",
        "inflow": false,
        "description": "Kasım sevkiyatı",
        "address": "Örnek Mah. Deneme Sk. No: 1",
        "district": "Kadıköy",
        "city": "İstanbul"
      },
      "relationships": {
        "contact": { "data": { "type": "contacts", "id": "{contact_id}" } },
        "stock_movements": {
          "data": [
            {
              "type": "stock_movements",
              "attributes": { "quantity": 5 },
              "relationships": {
                "product": { "data": { "type": "products", "id": "{product_id}" } },
                "warehouse": { "data": { "type": "warehouses", "id": "{warehouse_id}" } }
              }
            }
          ]
        }
      }
    }
  }'
AlanAçıklama
attributes.issue_dateZorunlu. Düzenleme tarihi, YYYY-AA-GG
attributes.shipment_dateFiili sevk tarihi (tarih-saat)
attributes.inflowfalse: sevk irsaliyesi, true: giriş irsaliyesi
attributes.descriptionİrsaliye açıklaması
attributes.address, district, citySevkiyat adresi, ilçe, il
attributes.procurement_numberİrsaliye numarası; rehbere göre boş bırakılırsa sistem üretir
relationships.contactMüşteri ya da tedarikçi (contacts)
relationships.stock_movementsKalemler; her biri quantity (zorunlu), product ve isteğe bağlı warehouse taşır
relationships.tagsEtiketler (tags)

Kalemde warehouse verilmezse firmanın varsayılan deposu kullanılır; mevcut bir kalemi güncellerken verilmezse depo değişmez. uuid, despatch_no, status, status_message, legalized_at, archived gibi alanlar salt okunurdur; istek gövdesine koymayın.

Listeleme, güncelleme, silme ve arşiv

İşlemUç nokta
ListeleGET /{company_id}/shipment_documents
GörüntüleGET /{company_id}/shipment_documents/{id}
GüncellePUT /{company_id}/shipment_documents/{id}
SilDELETE /{company_id}/shipment_documents/{id} (204)
Arşivle / geri alPATCH .../{id}/archive ve PATCH .../{id}/unarchive
  • Liste ucunda page[size] en fazla 25'tir. Belgelenen filtreler filter[flow_type], filter[invoice_status] ve filter[archived]; sıralama id, issue_date, description, inflow ile yapılabilir.
  • include değerleri: contact, stock_movements, stock_movements.product, tags, invoices.
  • Arşivlemede zaten arşivlenmiş, arşivden çıkarmada arşivde olmayan irsaliyeler ve her iki durumda e-İrsaliye gönderimi süren giden irsaliyeler için 422 döner.

Liste parametrelerinin ortak kuralları filtreleme, sayfalama ve include yazısında.

Giden irsaliyeyi e-İrsaliye olarak gönderme

Sevk irsaliyesini (inflow: false) resmileştirme akışı dört adımdır: alıcının posta kutusunu bulun, irsaliyeyi resmileştirin, işi ve sonucu takip edin, PDF ya da UBL dosyasını alın.

1. Alıcının e-İrsaliye posta kutusunu bulun

bash
curl -X GET "https://api.parasut.com/v4/{company_id}/e_despatch_inboxes?tax_number=1234567890" \
  -H "Authorization: Bearer $PARASUT_ACCESS_TOKEN"

Buradaki tuzak: tax_number (VKN ya da TCKN) zorunlu düz bir sorgu parametresidir, filter[tax_number] biçiminde gönderilmez. Uç sayfalama yapmaz ve alıcının aktif posta kutularını döner. Her kaydın özellikleri:

AlanAçıklama
aliasPosta kutusu etiketi; legalize isteğinde to alanına yazılır
legal_nameAlıcının unvanı
tax_numberVKN/TCKN
activePosta kutusunun aktif olup olmadığı
public_institutionKamu kurumu bilgisi
alias_registered_at, registered_atEtiketin ve kaydın tarihi

2. İrsaliyeyi resmileştirin (legalize)

bash
curl -X POST "https://api.parasut.com/v4/{company_id}/shipment_documents/{shipment_document_id}/legalize" \
  -H "Authorization: Bearer $PARASUT_ACCESS_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": {
      "attributes": { "to": "urn:mail:irsaliyepk@ornek-alici.com" }
    }
  }'

Gövde isteğe bağlıdır; data.attributes.to alanına 1. adımdaki alias değerini yazarsınız. Yanıt belgenin kendisi değil, 202 Accepted ile bir trackable job'dır. Trackable job, Paraşüt'ün arka planda yürüttüğü bir işin kaydıdır; işin kimliği data.id alanındadır.

DurumSonuç
Aktif e-İrsaliye entegrasyonu yok422
Aynı irsaliye için gönderim zaten sürüyor422
İrsaliye arşivlenmiş202 kabul edilir, iş error ile biter
İrsaliye daha önce resmileşmiş (status dolu)202 kabul edilir, iş error ile biter
Firmanın e-belge kontörü bitmiş202 kabul edilir, iş error ile biter

3. İşi takip edin, sonucu kontrol edin

bash
curl -X GET "https://api.parasut.com/v4/{company_id}/trackable_jobs/{trackable_job_id}" \
  -H "Authorization: Bearer $PARASUT_ACCESS_TOKEN"

# Örnek yanıt
# {"data": {"id": "JOB_ID", "type": "trackable_jobs", "attributes": {"status": "done", "errors": []}}}

status değerleri: running (sürüyor, biraz sonra tekrar sorun), done (tamamlandı), error (başarısız; errors metin dizisi nedeni açıklar). Rehbere göre işin durumu son güncellemesinden sonra 15 dakika boyunca sorgulanabilir; sonucu bu süre içinde okuyun. Önerilen bir sorgulama aralığı belgelenmemiştir; birkaç saniyelik aralık ve üst sınırlı bir deneme sayısı makul bir başlangıçtır.

javascript
const BASE = 'https://api.parasut.com/v4';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function waitForJob(companyId, jobId, token) {
  for (let i = 0; i < 30; i++) {
    const res = await fetch(`${BASE}/${companyId}/trackable_jobs/${jobId}`, {
      headers: { Authorization: `Bearer ${token}` },
    });
    if (!res.ok) throw new Error(`trackable job HTTP ${res.status}`);
    const { data } = await res.json();
    if (data.attributes.status === 'done') return;
    if (data.attributes.status === 'error') {
      throw new Error((data.attributes.errors || []).join('; '));
    }
    await sleep(3000); // running: bekle ve tekrar sor
  }
  throw new Error('İş zamanında tamamlanmadı');
}

İş bittikten sonra gönderim sonucu irsaliye kaydına yazılır. GET /{company_id}/shipment_documents/{id} yanıtında bakılacak alanlar:

AlanAçıklama
statuswaiting (bekliyor), failed (başarısız), legalized (resmileşti); resmileştirilmemişse boş
status_messageHata durumunda nedeni içerir; boş olabilir
despatch_noe-İrsaliye numarası
uuide-İrsaliye UUID değeri
legalized_atResmileştirme tarihi

Zarf bilgileri (env_uuid, gib_status_code, despatch_no) için GET /{company_id}/shipment_documents/{id}/e_despatch kullanılır. Durum failed ise PATCH /{company_id}/shipment_documents/{id}/resend ile yeniden gönderebilirsiniz; yanıt yine 202 ve trackable job'dır. Durumu failed olmayan bir irsaliyede istek 202 ile kabul edilir ama iş Sadece gönderimi başarısız olan irsaliyeler tekrar gönderilebilir hatasıyla biter.

4. PDF ve UBL dosyasını alın

DosyaUç noktaNot
e-İrsaliye PDFGET /{company_id}/shipment_documents/{id}/pdfurl ve expires_at ya da dosyanın kendisi; hazır değilse 204
e-İrsaliye UBLGET /{company_id}/shipment_documents/{id}/ublZip indirir; yalnızca giden irsaliye; hazır değilse 204

UBL ucu gelen irsaliyede 404, aktif e-İrsaliye entegrasyonu yoksa 422 döner. PDF bağlantısını süresi dolunca yeniden isteyin; bağlantıyı doğrudan müşteriyle paylaşmak yerine dosyayı indirip kendi sisteminizden iletin.

Gelen e-İrsaliyeler (inbound_e_despatches)

Gelen e-İrsaliyeler (inbound_e_despatches): GET .../inbound_e_despatches/{id}/inbound_despatch_advice, POST .../{id}/accept, POST .../{id}/respond, PATCH .../{id}/resend_response

Size gönderilen e-İrsaliyeler ayrı bir kaynakta durur. Liste ucu varsayılan olarak yalnızca henüz yanıtlanmamış irsaliyeleri döner (filter[responded]=false); yanıtlananlar için filter[responded]=true gönderin.

ParametreAçıklama
filter[issue_date]YYYY-AA-GG; [gt], [lt], [gteq], [lteq], [eq], [not_eq] operatörleriyle
filter[query]contact_name ve despatch_no üzerinde metin araması
filter[imported] / filter[not_imported]İrsaliyeye dönüştürülmüş ya da henüz dönüştürülmemiş olanlar
filter[response_status]waiting, expired, legalized, sent, rejected (yalnızca responded=true ile)
sortissue_date, contact_name
page[size]En fazla 25; büyük değer 422 döner

Bu uçta bilinmeyen bir filtre, sıralama ya da include değeri 400 döner. Kayıtta response_status (waiting, failed, legalized ya da boş), response_type (accepted, rejected, partial), expires_at ve is_expired alanları bulunur. Şema açıklamasına göre expires_at, yanıt verilebilecek son tarihtir ve sağlayıcıya geliş zamanına 8 gün eklenerek hesaplanır.

Kalemleri okuyun ve yanıtlayın

  • GET .../inbound_e_despatches/{id}/inbound_despatch_advice: UBL içeriğini (gönderen, adresler, taşıma bilgileri, kalemler) döner; kalemler inbound_despatch_advice_details olarak included içinde gelir.
  • POST .../{id}/accept: kabul yanıtı. POST .../{id}/reject: ret yanıtı (gerekçe alanı yoktur).
  • POST .../{id}/respond: kalem bazında kısmi kabul.
  • PATCH .../{id}/resend_response: response_status: failed olan yanıtı yeniden gönderir.
  • Hepsi 202 ve trackable job döner. Yalnızca henüz yanıtlanmamış irsaliyeler yanıtlanabilir; gönderim sürüyorsa 422 İrsaliye cevabı gönderilme aşamasında. döner.

Kısmi yanıtın gövdesi JSON:API kaynak nesnesi değil, data altında bir kalem dizisidir. Her kalem inbound_despatch_advice yanıtındaki line_no ile eşleşir:

bash
curl -X POST "https://api.parasut.com/v4/{company_id}/inbound_e_despatches/{id}/respond" \
  -H "Authorization: Bearer $PARASUT_ACCESS_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{
    "data": [
      { "attributes": { "line_no": 1, "accepted_quantity": 8, "missing_quantity": 2, "note": "2 adet eksik geldi" } },
      { "attributes": { "line_no": 2, "accepted_quantity": 5 } }
    ]
  }'

Kalemde kullanılabilen alanlar: line_no (zorunlu), accepted_quantity, rejected_quantity, missing_quantity, extra_quantity, note.

Gelen e-İrsaliyeyi irsaliye olarak içe aktarın

GET .../inbound_e_despatches/{id}/convert_to_shipment_document hiçbir kayıt oluşturmaz; yalnızca bir giriş irsaliyesi (inflow: true) taslağı üretir. Taslakta ürünler tam ad eşleşmesiyle firmanın aktif ürünlerinden seçilir, eşleşme yoksa yeni ürün önerilir; depo varsayılan depodur. İsteğe bağlı contact_id parametresiyle taslağa cari atayabilirsiniz (cari yoksa 404).

Taslağı kaydetmek için POST /{company_id}/shipment_documents çağrısına relationships.inbound_e_despatch ilişkisini ekleyin; irsaliye böylece içe aktarılmış (imported) sayılır:

json
{
  "data": {
    "type": "shipment_documents",
    "attributes": { "issue_date": "2026-11-03", "inflow": true },
    "relationships": {
      "contact": { "data": { "type": "contacts", "id": "{tedarikci_id}" } },
      "inbound_e_despatch": { "data": { "type": "inbound_e_despatches", "id": "{inbound_e_despatch_id}" } },
      "stock_movements": { "data": [
        { "type": "stock_movements", "attributes": { "quantity": 8 },
          "relationships": { "product": { "data": { "type": "products", "id": "{product_id}" } } } }
      ] }
    }
  }
}

Gelen e-İrsaliyenin PDF'i GET .../{id}/pdf ile alınır (url bir saat geçerlidir, hazır değilse 204); UBL ucu GET .../{id}/ubl dosyaya 302 ile yönlendirir.

Fatura ile irsaliyeyi eşleştirme

Aynı satışa ait satış faturası ile giden irsaliyeyi birbirine bağlayabilirsiniz. Bağlantı iki taraftan da kurulabilir ve stok entegrasyonunun açık olması gerekir. Bu uçların gövdesi JSON:API kaynak nesnesi değil, düz bir data nesnesidir ve kimlikler sayı olarak gönderilir; Paraşüt'ün genel "ilişki id'leri string" kuralının belgelenmiş istisnasıdır.

bash
# Fatura tarafından
curl -X POST "https://api.parasut.com/v4/{company_id}/sales_invoices/{invoice_id}/link_shipment_documents" \
  -H "Authorization: Bearer $PARASUT_ACCESS_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{ "data": { "shipment_document_ids": [4567] } }'

# İrsaliye tarafından
curl -X POST "https://api.parasut.com/v4/{company_id}/shipment_documents/{shipment_document_id}/link_invoices" \
  -H "Authorization: Bearer $PARASUT_ACCESS_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{ "data": { "invoice_type": "sales_invoices", "invoice_ids": [1234] } }'
  • invoice_type irsaliyenin yönüne uymalıdır: giden irsaliye için sales_invoices, gelen irsaliye için purchase_bills. Yanlış yön 400 döner.
  • İşlem bütünseldir: biri bağlanamazsa hiçbiri bağlanmaz. Başarılı istek 201 döner.
  • İrsaliyeli faturalar, iptal edilmiş, arşivlenmiş ve proforma faturalar, tekrarlama şablonları, depolar arası transfer irsaliyeleri ve zaten eşleşmiş çiftler 422 döner (ör. İrsaliye ile Fatura hali hazırda eşleştirilmiş.).
  • Bağlantıyı kaldırmak için aynı gövdeyle DELETE .../shipment_documents/{id}/unlink_invoices gönderin; 200 döner, bağlı olmayan faturalar sessizce atlanır ve istek güvenle tekrarlanabilir.
  • Bağlı faturaları GET .../shipment_documents/{id}?include=invoices ile görürsünüz.

Satış faturasının kendisini oluşturma adımları Paraşüt API ile fatura kesme yazısında, alış tarafı ise alış faturası ve gider kaydı yazısında.

İrsaliye değişikliklerini webhook ile izleme

shipment_document modeli create, update ve delete olaylarını destekler. Gövdede data.data irsaliyenin shipment_documents gösterimi, data.included ise stok hareketleridir; status, despatch_no gibi e-İrsaliye alanları da kaydın içinde gelir. Kurulum, doğrulama ve sıra kuralları için Paraşüt webhook kurulumu yazısına bakın. Webhook teslimatı garanti edilmediği için gönderim sonucunu yine trackable job ve irsaliye kaydı üzerinden doğrulayın.

Sık Sorulan Sorular

e_despatch_inboxes isteğim neden hata veriyor?

En sık sebep parametre biçimidir. Bu uç filter[tax_number] değil, zorunlu düz tax_number sorgu parametresi bekler: ?tax_number=1234567890.

legalize 202 döndü ama irsaliye resmileşmedi, neden?

202 yalnızca işin kuyruğa alındığını söyler. İrsaliye arşivlenmişse, daha önce resmileştirilmişse ya da e-belge kontörü bittiyse istek yine 202 alır ama iş error ile biter. GET /trackable_jobs/{id} yanıtındaki errors dizisine ve irsaliyenin status_message alanına bakın.

İrsaliye numarasını kendim verebilir miyim?

procurement_number alanı irsaliye numarasıdır ve yazılabilir; rehbere göre boş bırakılırsa sistem üretir. e-İrsaliye numarası (despatch_no) ise salt okunurdur ve resmileştirmeden sonra dolar.

Gelen e-İrsaliyeye ne kadar sürede yanıt vermeliyim?

Kayıttaki expires_at alanı yanıt verilebilecek son tarihi gösterir; şema açıklamasına göre sağlayıcıya geliş zamanı artı 8 gündür. is_expired süresi dolmuş kayıtları işaretler.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Paraşüt entegrasyonu genel rehberi · Paraşüt API ile fatura kesme · Paraşüt ürün, stok ve depo yönetimi · Paraşüt webhook kurulumu · Paraşüt e-Fatura ve e-Arşiv gönderme · E-ticaret siparişini Paraşüt'e aktarma · E-ticarette e-Arşiv ve e-Fatura zorunluluğu