Media API

Bu API görseller, videolar, PDF'ler — site için yüklediğiniz her şeyle ilgili. Güzel tarafı: bir JPEG yüklediğinizde jekcms arka planda sizin için AVIF ve WebP varyantlarını üretir ve küçük resimleri hazırlar. Yani ön yüzünüz ekstra araç gerekmeden <picture> etiketleri sunabilir.

Uç noktalar /api/v1/media altında. Bearer token'ınızın media:* kapsamına sahip olması gerekiyor.

Medya listele

GET /api/v1/media

Kapsam: media:read. Filtre seçenekleri:

  • typeimage, video, document, audio
  • search — dosya adı, alt metin veya başlık içinde arar
  • uploaded_by — kullanıcı ID'si
  • page, per_page (varsayılan 50, en fazla 100)
  • order_byuploaded_at, filename, size
curl -H "Authorization: Bearer YOUR_TOKEN" \
  "https://yoursite.com/api/v1/media?type=image&per_page=20"

Cevap bildiğiniz data + pagination yapısı. Her medya öğesinde id, filename, orijinal url, mime, size_bytes, görseller için width/height, alt_text, caption, bir variants nesnesi (varyant URL'leri) ve yükleyen kişi/zaman bilgisi gelir:

{
    "data": [
        {
            "id": 45,
            "filename": "cover.jpg",
            "url": "https://yoursite.com/storage/uploads/2026/04/cover.jpg",
            "mime": "image/jpeg",
            "size_bytes": 248301,
            "width": 1600,
            "height": 900,
            "alt_text": "Plate of scrambled eggs",
            "variants": {
                "avif": "https://yoursite.com/storage/uploads/2026/04/cover.avif",
                "webp": "https://yoursite.com/storage/uploads/2026/04/cover.webp",
                "thumb_400": "https://yoursite.com/storage/uploads/2026/04/cover_400.jpg",
                "thumb_800": "https://yoursite.com/storage/uploads/2026/04/cover_800.jpg"
            },
            "uploaded_by": 1,
            "uploaded_at": "2026-04-10T08:55:00Z"
        }
    ],
    "pagination": { "page": 1, "per_page": 20, "total": 412, "total_pages": 21 }
}

Dosya yükle

POST /api/v1/media
Content-Type: multipart/form-data

Kapsam: media:write. Form alanları:

  • file (zorunlu) — binary dosya
  • alt_text (opsiyonel) — görseller için erişilebilirlik metni, SEO için de önemli
  • caption (opsiyonel)
  • folder (opsiyonel) — sanal klasör, örn. blog/2026/april
curl -X POST https://yoursite.com/api/v1/media \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@/path/to/cover.jpg" \
  -F "alt_text=Plate of scrambled eggs" \
  -F "folder=blog/breakfast"

201 Created ile tam medya nesnesi döner. Dikkat edin: AVIF/WebP varyantları ve küçük resimler asenkron üretilir. İlk cevapta variants nesnesi boş olabilir, birkaç saniye içinde dolar. Yazıya koymadan önce varyantların hazır olmasını bekliyorsanız GET /api/v1/media/{id} ile kısa aralıklarla yoklayın.

URL'den görsel çek

Bir stok kütüphaneden ya da AI üretimi bir URL'den görseli sitenize kopyalamak için elle indirmeye gerek yok:

POST /api/v1/media/fetch
Content-Type: application/json

Kapsam: media:write.

{
    "url": "https://images.example.com/food/eggs-4k.jpg",
    "alt_text": "Plate of scrambled eggs",
    "folder": "blog/breakfast"
}

Sunucu URL'yi çeker, mime tipini izin listesine karşı doğrular, yerel olarak saklar ve normal yüklemeyle aynı varyantları üretir. Cevap multipart uç noktasıyla birebir aynı.

URL ulaşılamıyorsa, dönen içerik görsel değilse veya maksimum yükleme boyutunu aşıyorsa 422 alırsınız.

Medya sil

DELETE /api/v1/media/{id}

DB satırını, orijinal dosyayı ve tüm üretilmiş varyantları tek seferde temizler. Medya bir yerde kullanılıyorsa (bir yazının öne çıkan görseli ya da içinde referans verilmişse) jekcms sizi korur ve 409 Conflict döner — cevap gövdesinde hangi yazı ID'lerinin referans verdiğini görürsünüz.

Yine de silmek istiyorsanız ?force=true ekleyin; ama bunu yaptığınızda öne çıkan görsel referansları null olur, gövde içindeki <img> etiketleri bozuk kalır. Başarıda 204 No Content.

Sınırlar

Dosya boyutu: sabit üst sınır 50 MB. Paylaşımlı hostingde PHP ayarları (upload_max_filesize / post_max_size) bunu daha da düşürebilir — host'unuzun panelinden kontrol edin.

Büyük video veya arşiv yüklemeleri için S3 uyumlu harici depolama kullanın. Settings → Storage altındaki admin arayüzü doğrudan bucket'a yükleme yapar, PHP sürecini tamamen bypass eder — yani 50 MB engeli ortadan kalkar.

İzin verilen tipler:

  • Görseller: image/jpeg, image/png, image/gif, image/webp, image/avif, image/svg+xml (SVG'ler yüklenirken temizlenir)
  • Video: video/mp4, video/webm, video/ogg
  • Ses: audio/mpeg, audio/mp4, audio/ogg, audio/wav
  • Belge: application/pdf

Listede olmayan bir tip 422 unsupported_media_type alır. Admin listeyi Settings → Media → Allowed types altından genişletebilir; ama çalıştırılabilir veya arşiv tipleri eklemeden önce iki kere düşünün — tarayıcıda satır içi çalışmasını engellemek için Content-Disposition: attachment ile sunmak şart.

Varyantlar nasıl üretilir

Bir görsel yüklediğinizde jekcms arka plan işleri kuyruklar:

  • AVIF %80 kalite (modern tarayıcılar için en iyi sıkıştırma)
  • WebP %85 kalite (fallback)
  • 400px ve 800px genişlikli JPEG'ler (kart ve thumbnail kullanımları için)

Orijinal dosyaya dokunulmaz. EXIF yönü korunur ama GPS metadata'sı gizlilik için silinir. Zaten AVIF veya WebP yüklediyseniz yalnızca thumbnail'ler üretilir.

İş media.variant_worker zamanlanmış görevinde çalışır. Varyantlar üretilmiyorsa ilk yapılacak şey cron'un canlı olduğunu kontrol etmek.

Hata kodları

  • 400file alanı yok ya da form bozuk
  • 401 — token sorunu
  • 403 — token'da media:write kapsamı yok
  • 404 — ID bulunamadı (DELETE veya tekli GET'te)
  • 409 — başka yerde kullanılıyor (force=true ile geçilebilir)
  • 413 — 50 MB sınırı aşıldı
  • 422 — desteklenmeyen mime tipi veya uzak URL bozuk
  • 429 — hız sınırı

Yeniliklerden ilk sen haberdar ol

Yeni özellikler, sürüm notları ve CMS rehberleri — ayda birkaç e-posta, spam yok.