İçeriğe geç
Euphona

Geliştiriciler

API olarak Euphona motoru

api.euphonaai.com/v1 üzerinde tek bir REST sözleşmesi. Canlı SSE ilerleme bildirimli asenkron işler, imzalı dosya aktarımı, önekli anahtarlar ve ücretsiz bir test modu: on iki aylık kendi destek süresi olan, birinci taraf bir ürün.

Anahtarlar Studio ayarlarında oluşturulur: eu_test_… anında ve ücretsiz; eu_live_… ise kayıtlı bir kart eklendikten sonra aynı ekrandan, ilk işinden itibaren ücretlendirilerek. Test modu sözleşmenin tamamını çalıştırır.

Her şey bir iş

curl -X POST https://api.euphonaai.com/v1/masters \
  -H "Authorization: Bearer $EUPHONA_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"file_id": "file_8Kd2mQTz3XaV7pLw"}'

HTTP/2 202
{
  "id": "job_7Vd2mHs5Yq8Tz3Xa",
  "object": "job",
  "type": "mastering",
  "status": "queued",
  "stage": null,
  "metering": {
    "pool": "payg",
    "charged_minutes": 0,
    "test_mode": false
  }
}

Tasarım

Nasıl tasarlandı

Pazarlığa açık olmayan dört karar; çünkü her biri, ilk kesintisini atlatan bir entegrasyonla atlatamayan bir entegrasyon arasındaki fark.

Her şey bir iş

İşlev uç noktaları 202 ve bir iş kaynağı döndürür. Senkron işleme uç noktası yok ve hiçbir zaman olmayacak: mastering kalitesinde üç dakikalık bir şarkı bir istek/yanıt döngüsü değildir ve aksini iddia eden bir API, her entegrasyona yanlış yazılmayı öğretir.

Ses API’den geçmez, etrafından dolaşır

POST /v1/files, files.euphonaai.com üzerinde imzalı, devam ettirilebilir bir yükleme hedefi döndürür. Sonuçlar imzalı ve süresi dolan indirme URL’leri olarak gelir. API’nin kendisi bir JSON kontrol düzlemidir ve asla tek bir bayt ses taşımaz.

Bu API bir yan ürün değil, ürünün kendisi

Euphona Studio farklı, birinci taraf bir API konuşur. Bu bilinçli bir tercih: ikisi tek bir motoru paylaşan ayrı ürünlerdir; bu yüzden uygulamanın istediği bir değişiklik bu sözleşmeye ulaşamaz ve bu sözleşmenin on iki aylık destek süresi, uygulamanın ödemek zorunda olduğu bir vergi değildir. Dürüst sonucu şu: uygulama, bu API’nin yapmadığı şeyler yapabilir, bu senin için önemliyse sor; bir sürpriz yerine yol haritasında bir madde olur.

Belge, sözleşmenin kendisidir

OpenAPI 3.1 belgesi tek doğruluk kaynağıdır. Sunucu rotaları ve tipler ondan üretilir; dağıtım kapısındaki bir test, sunulan rotaları bildirilen işlemlerle eşit tutar: böylece belgelenenle sunulan arasındaki sapma, izlemeye söz verdiğimiz bir şey olmak yerine derlemeyi başarısız kılar. Aynı belgeden üretilen SDK’lar, geliştirici önizlemesiyle birlikte gelir.

Adım adım

Bir entegrasyonun yapısı

Bir dosya oluştur, baytları imzalı hedefe gönder, bir iş gönder ve SSE üzerinden bitişini izle. Dört adım; işleve göre değişen tek kısım üçüncüsü.

1. Dosyayı oluştur ve bir yükleme hedefi al

curl -X POST https://api.euphonaai.com/v1/files \
  -H "Authorization: Bearer $EUPHONA_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"filename":"take-07.wav","bytes":58210044,"content_type":"audio/wav"}'

{
  "id": "file_8Kd2mQ...",
  "object": "file",
  "status": "awaiting_upload",
  "upload": { "protocol": "...", "url": "https://files.euphonaai.com/...", "expires_at": "..." }
}

2. Baytları bize değil, files. adresine gönder

# upload.protocol alanını oku, tek bir mekanizma varsayma. Devam ettirilebilir
# yükleme mekanizması, sözleşme içindeki bir uygulama tercihidir ve büyük
# bir sürüm değişikliği olmadan değişebilir; belgede değil de bir alanda
# olmasının nedeni tam olarak bu.

3. İşi izle

curl -N https://api.euphonaai.com/v1/jobs/job_4Rb.../events \
  -H "Authorization: Bearer $EUPHONA_API_KEY"

event: job.progress
data: {"status":"analyzing","stage":"analyze","progress":{"fraction":0.4}}

event: job.completed
data: {"status":"succeeded","result":{...},"metering":{"pool":"payg","charged_minutes":3.4}}

4. Sonucu işin kendisiyle doğrula

curl https://api.euphonaai.com/v1/jobs/job_4Rb... \
  -H "Authorization: Bearer $EUPHONA_API_KEY"

{"id":"job_4Rb...","status":"succeeded","result":{...},
 "metering":{"pool":"payg","charged_minutes":3.4}}

# İş kaynağı, durum makinesinin güncel gerçeğidir: bir akış ne gösterdiyse
# ya da neyi kaçırdıysa, harekete geçmeden önce onu yeniden oku. Kopan bir
# SSE bağlantısı Last-Event-ID ile yeniden bağlanır ve hiçbir şey kaybetmez.

Başvuru

Yüzey

Her işlevin paylaştığı platform yüzeyi. Her işlev tek bir oluşturma uç noktası ekler; döndürdüğü iş aşağıdaki her şeyden geçer: aynı yaşam döngüsü, aynı olaylar, aynı rapor.

v1 sözleşmesindeki uç noktalar
YöntemYolNe yapar
POST/v1/filesBir dosya oluşturur ve imzalı, devam ettirilebilir bir yükleme hedefi döndürür.
GET/v1/files/{id}İçe alma durumu, ölçülen süre, örnekleme hızı, kanallar, format.
DELETE/v1/files/{id}Bir dosyayı ve ondan üretilenleri siler; bir iş onu hâlâ kullanırken reddedilir.
GET/v1/files/{id}/downloadİmzalı, süresi dolan bir indirme URL’si.
GET/v1/jobsBirleşik okuma yüzeyi, imleçle sayfalanır.
GET/v1/jobs/{id}Durum, aşama, ilerleme, ücretlendirme ve ölçülen rapor.
POST/v1/jobs/{id}/cancelİptal eder; işleme aşaması başlamadan önce ücret alınmaz.
POST/v1/jobs/{id}/inputawaiting_input durumundaki bir işin sorduğunu yanıtlar ve işi devam ettirir. Ücretlendirilmez.
GET/v1/jobs/{id}/eventsİşin yaşam süresi boyunca sunucu tarafından gönderilen olaylar.
POST/v1/projectsDosyaları ve işleri gruplar; Track Graph adını verdiğimiz ortak analiz her proje için ayrıdır.
GET/v1/projects/{id}Dosya ve iş kimlikleriyle birlikte tek bir proje.
GET/v1/usageKota durumu ve iki ücretlendirme havuzu.
GET/v1/webhook-endpointsBu anahtarın modundaki webhook uç noktaların.
POST/v1/webhook-endpointsBir https URL’si kaydet; hiçbir şey kaydedilmeden önce imzalı bir sınamayı yanıtlar.
GET/v1/webhook-endpoints/{id}Tek bir uç nokta. Sırrı bir daha asla gösterilmez.
PATCH/v1/webhook-endpoints/{id}Olaylarını, açıklamasını veya URL’sini değiştir; yeni bir URL yeniden doğrulanır.
DELETE/v1/webhook-endpoints/{id}Sil; ona teslim edilmemiş olaylar atılır.
POST/v1/webhook-endpoints/{id}/rotate-secretYeni bir imzalama sırrı; eskisi bir geçiş süresi boyunca imzalamaya devam eder.
GET/v1/eventsOtuz günlük olaylar ve her teslimatın sonucu.
GET/v1/events/{id}Teslim edildiği haliyle tek bir olay ve teslimatları.

Webhook’lar

Bir işin bittiğini öğren

Bir iş bittiğinde ya da yanıtını beklediğinde gelen imzalı bildirimler; böylece bir entegrasyonun akışı açık tutması ya da sürekli sorgulaması gerekmez.

Olaylar
job.completed, job.failed, job.canceled ve job.awaiting_input. Her biri, data alanı sorgulamanın döndürdüğü iş kaynağının tıpatıp aynısı olan bir olaydır.
Çalışma alanı olayları
Saklanan bir yüklemeye kaldırılabileceği bir tarih verildiğinde file.expiring, data olarak dosyayla; bir kullanım havuzu sınırının %80’ine veya %100’üne ulaştığında usage.threshold. İkisi de her iki moddaki uç noktalara ulaşır; dosya başına bir kez ya da eşik ve dönem başına bir kez.
Kayıt
Yeni anahtarlarda bulunmayan webhooks:manage kapsamına sahip bir anahtar gerekir. URL https kullanmalı ve yalnızca herkese açık adreslere çözümlenmelidir; ayrıca hiçbir şey kaydedilmeden önce imzalı bir sınamayı, onu geri döndüren bir 2xx yanıtıyla yanıtlamalıdır. Teslimatlar yalnızca IPv4 üzerinden gönderilir, bu yüzden ana makinenin bir IPv4 adresi olmalıdır.
Teslimat
En az bir kez; bu yüzden tekrarları Euphona-Event-Id ile ayıkla. 10 saniye içinde 2xx dışında gelen her yanıt 24 saat boyunca üstel geri çekilmeyle yeniden denenir, ardından teslim edilemeyenlere alınır ve GET /v1/events içinde tutulur. Yönlendirmeler asla izlenmez ve sıra garanti edilmez: işle karşılaştırarak uzlaştır.
İmzalar
Euphona-Signature, bir zaman damgası ile zaman damgası, nokta ve ham gövde üzerinden uç noktanın sırrıyla anahtarlanmış bir HMAC-SHA256 taşır. Ayrıştırmadan önce doğrula, sabit sürede karşılaştır ve saatinden beş dakikadan fazla sapan bir zaman damgasını reddet.
Kaynak adresler
Teslimatlar 65.21.69.162 adreslerinden gönderilir. Güvenlik duvarın gelen trafiği filtreliyorsa bunlara izin ver ve imzayı yine de doğrula: bir isteğin geldiği adres, onu kimin gönderdiğini kanıtlamaz.

Bir teslimatı doğrulamak (Node.js)

import { createHmac, timingSafeEqual } from "node:crypto";

// Gövdeyi tam geldiği gibi ilet: ayrıştırılıp yeniden serileştirilmiş JSON,
// imzalanan mesaj değildir.
export function verifyEuphonaSignature(rawBody, header, secret, now = Date.now() / 1000) {
  const parts = header.split(",").map((part) => part.trim().split("="));
  const t = Number(parts.find(([key]) => key === "t")?.[1]);
  const signatures = parts.filter(([key]) => key === "v1").map(([, value]) => value);
  if (!Number.isFinite(t) || Math.abs(now - t) > 300) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
  return signatures.some((value) => {
    const given = Buffer.from(value, "hex");
    return given.length === expected.length && timingSafeEqual(given, expected);
  });
}

İşletim

Gece üçte can yakan şeyler

Entegrasyonu yazmadan önce okumaya değer altı davranış: seni uykundan uyandırdıktan sonra değil.

Anahtarlar
eu_live_… ve eu_test_…; bir çalışma alanına aittir, oluşturulurken bir kez gösterilir ve depolamada hash olarak tutulur. En fazla otuz günlük bir örtüşme süresiyle değiştir; böylece anahtar değişimi bir kesintiye dönüşmez. Test anahtarları kendi aylık sınırları dahilinde ücretsizdir ve kendi zamanlama sınıflarında çalışır; master yerine önizleme döndürürler, böylece bir entegrasyon hiçbir şey satın almadan baştan sona kurulabilir.
Hatalar
Her zaman RFC 9457 application/problem+json; kararlı, makine tarafından okunabilir bir code, insanlar için bir detail ve istek kimliğiyle. Dallanmayı metne göre değil, her zaman code değerine göre yap: metin yerelleştirilir, kod ise bir sözleşmedir.
Idempotency
Her POST isteğinde Idempotency-Key. Aynı anahtar aynı gövdeyle, oluşturduğu kaynak var olduğu sürece özgün yanıtı yeniden döndürür; aynı anahtar farklı bir gövdeyle reddedilir. Bu yüzden zaman aşımından sonra yapılan bir yeniden deneme, ücretlendirileceğin ikinci bir iş başlatmak yerine özgün işi döndürür.
Sınırlar
Standart RateLimit-* başlıklarıyla anahtar başına kayan pencere; kullandıkça öde modelinde dakikada 60 istek, taahhütlü kullanım sözleşmesinde daha fazlası. Sınırlayıcı yalnızca istek sıklığını yönetir: iş hacmini kotan ve kuyruk belirler.
İki sayaç, asla tek değil
API anahtarıyla gelen işler kullandıkça öde havuzundan sayılır; Studio oturumundan gelen işler plan dakikalarından düşer. Hiçbir havuz diğerini tüketemez ve GET /v1/usage ikisini de bildirir. Harcama limitleri varsayılan olarak açıktır. Depolama alanı iki değil, tek bir kotadır: anahtarla yüklenen dosyalar ve API işlerinin sonuçları, Studio’daki her şeyle birlikte çalışma alanının planındaki depolama kotasından sayılır, ücretsiz planda 2 GB, ve sığmayacak bir yükleme ya da iş storage_full ile reddedilir.
Request-Id
Başarılı ya da başarısız, her yanıtta. Bir destek talebinde belirttiğinde uçtan uca izlenebilir: işe, her aşamaya, gerçekte ne olduysa oraya kadar.
Hatalar
codetitle
unauthenticatedKimlik doğrulama gerekli
invalid_keyGeçersiz API anahtarı
key_revokedAPI anahtarı iptal edildi
insufficient_scopeYetersiz kapsam
email_verification_requiredE-posta doğrulaması gerekli
malformed_requestHatalı biçimlendirilmiş istek
validation_failedİstek doğrulanamadı
unsupported_media_typeDesteklenmeyen medya türü
idempotency_key_reuseIdempotency anahtarı farklı bir gövdeyle yeniden kullanıldı
not_foundBulunamadı
job_not_cancelableİş iptal edilemez
job_not_awaiting_inputİş girdi beklemiyor
file_not_readyDosya hazır değil
file_expiredDosyanın süresi doldu
file_in_useDosya kullanımda
file_disabledDosya yasal nedenlerle kullanılamıyor
unsupported_formatDesteklenmeyen ses formatı
unsupported_sample_rateDesteklenmeyen örnekleme hızı
unsupported_channel_countDesteklenmeyen kanal sayısı
file_too_longSes çok uzun
file_too_shortSes çok kısa
file_too_largeDosya çok büyük
corrupt_mediaSesin kodu çözülemedi
rate_limitedİstek sınırı aşıldı
too_many_active_jobsÇok fazla etkin iş
quota_exceededKota aşıldı
spend_cap_reachedHarcama limitine ulaşıldı
test_mode_cap_reachedTest modu sınırına ulaşıldı
storage_fullDepolama alanı dolu
purchase_requiredSatın alma gerekli
payment_method_requiredÖdeme yöntemi gerekli
format_not_in_planFormat bu plana dahil değil
webhook_url_not_httpsWebhook URL’si HTTPS olmalıdır
webhook_url_not_publicWebhook URL’sine herkese açık ağdan erişilebilmelidir
webhook_verification_failedWebhook sahipliği doğrulanamadı
internal_errorDahili hata
service_unavailableHizmet kullanılamıyor
processing_failedİşlem başarısız oldu
capacity_unavailableKapasite yok
capability_pausedGeçici olarak duraklatıldı
workspace_suspendedÇalışma alanı askıya alındı
uploads_blockedYüklemeler duraklatıldı
reauthentication_requiredSen olduğunu onayla

Ücretler

Ne kadar tutar

İşlenen dakika başına, işlev çarpanıyla çarpılarak aylık faturalandırılır. Abonelik gerekmez, bir API çalışma alanı ücretsiz planda olabilir. Test modu ücretsizdir.

Ayın ilk 100 dakikası
$0,35
1.000 dakikaya kadar
$0,25
10.000 dakikaya kadar
$0,15
Bunun ötesi ya da taahhütlü kullanım
Konuşalım