# empuno Company API > Firmaların izin (leaves) ve masraf (expenses) verilerini kendi sistemlerine çekmesi için SALT-OKUMA REST API. Hiçbir yazma/işlem yoktur. - Temel URL: `https://empuno.com/api/company/v1` - Kimlik doğrulama: `Authorization: Bearer ` - Erişim: read-only - Hız sınırı: 120 istek/dakika, 3000 istek/saat (anahtar başına) - Sayfalama: Liste uçları sayfalıdır: ?page=1&per_page=25 (per_page max 100). Yanıt `meta` içinde total/last_page döner. - Anahtar yönetimi: Anahtarlar firma panelinde: Firma Ayarları → API sekmesi. Ham anahtar yalnızca oluşturmada bir kez gösterilir. ## Hızlı başlangıç ```bash curl -H "Authorization: Bearer emp_live_XXXX" \ https://empuno.com/api/company/v1/leaves ``` ## Genel Anahtar doğrulama ve keşif. ### GET /me Anahtarın geçerliliğini test etmek, bağlı firmayı ve mevcut uçları görmek için ilk çağrı. Örnek yanıt: ```json { "company": { "id": 12, "name": "Örnek A.Ş.", "timezone": "Europe/Istanbul" }, "api_key": { "id": 3, "name": "Muhasebe entegrasyonu", "scopes": [ "leaves.read", "expenses.read" ], "last_used_at": "2026-07-15T09:12:00+00:00" }, "access": "read-only", "rate_limit": { "per_minute": 120, "per_hour": 3000 } } ``` ## Çalışanlar İzin/masraf kayıtlarındaki employee_id'yi isim ve departmana çözmek için minimal roster. Hassas alanlar (kimlik no, maaş, banka, adres) dönmez. ### GET /employees Firmanın çalışanları (sayfalı). Parametreler: - `status` (query): active | inactive | terminated (virgülle çoklu) - `search` (query): Ad/soyad/personel no araması - `page` (query): Sayfa (varsayılan 1) - `per_page` (query): Sayfa boyutu (varsayılan 25, max 100) Örnek yanıt: ```json { "data": [ { "id": 45, "employee_number": "ABCD-001", "full_name": "Ahmet Yılmaz", "email": "ahmet@ornek.com", "department": "Yazılım", "position": "Kıdemli Geliştirici", "status": "active", "hire_date": "2022-03-01" } ], "meta": { "current_page": 1, "per_page": 25, "total": 42, "last_page": 2, "from": 1, "to": 25 } } ``` ### GET /employees/{id} Kimlik ile tek çalışan. Parametreler: - `id` (path): Çalışan ID Örnek yanıt: ```json { "data": { "id": 45, "employee_number": "ABCD-001", "full_name": "Ahmet Yılmaz", "email": "ahmet@ornek.com", "department": "Yazılım", "position": "Kıdemli Geliştirici", "status": "active", "hire_date": "2022-03-01" } } ``` ## İzinler İzin talepleri ve izin türleri (salt-okuma). ### GET /leaves Firmanın izin talepleri (sayfalı, tarih aralığına göre filtrelenebilir). Parametreler: - `status` (query): pending | approved | rejected | cancelled (virgülle çoklu) - `employee_id` (query): Çalışana göre filtre - `leave_type_id` (query): İzin türüne göre filtre - `from` (query): YYYY-MM-DD — bu tarihle kesişen izinler - `to` (query): YYYY-MM-DD — bu tarihle kesişen izinler - `search` (query): Çalışan adı/no araması - `page` (query): Sayfa - `per_page` (query): Sayfa boyutu (max 100) Örnek yanıt: ```json { "data": [ { "id": 123, "status": "approved", "employee": { "id": 45, "employee_number": "ABCD-001", "full_name": "Ahmet Yılmaz", "department": "Yazılım" }, "leave_type": { "id": 2, "name": "Yıllık İzin", "type_key": "annual" }, "start_date": "2026-08-01", "end_date": "2026-08-05", "days": 5, "duration_type": "full_day", "start_time": null, "end_time": null, "hours": null, "reason": "Yıllık izin", "rejection_reason": null, "substitute_employee": null, "approved_at": "2026-07-15T14:30:00+00:00", "created_at": "2026-07-10T09:00:00+00:00", "updated_at": "2026-07-15T14:30:00+00:00" } ], "meta": { "current_page": 1, "per_page": 25, "total": 8, "last_page": 1, "from": 1, "to": 8 } } ``` ### GET /leaves/{id} Tek izin detayı (belge yükümlülüğü bilgisi dahil; tıbbi belge dosyaları KVKK gereği paylaşılmaz). Parametreler: - `id` (path): İzin ID Örnek yanıt: ```json { "data": { "id": 123, "status": "approved", "employee": { "id": 45, "employee_number": "ABCD-001", "full_name": "Ahmet Yılmaz", "department": "Yazılım" }, "leave_type": { "id": 2, "name": "Yıllık İzin", "type_key": "annual" }, "start_date": "2026-08-01", "end_date": "2026-08-05", "days": 5, "duration_type": "full_day", "document": { "deadline": null, "obligation_status": null, "has_attachments": false } } } ``` ### GET /leave-types Firmanın aktif izin türleri (referans veri). Örnek yanıt: ```json { "data": [ { "id": 2, "name": "Yıllık İzin", "type_key": "annual", "description": null, "max_days_per_year": 14, "quota_type": "accumulated", "requires_document": false, "affects_annual_balance": true } ] } ``` ## Masraflar Masraf kayıtları, kategoriler ve fiş görselleri (salt-okuma). ### GET /expenses Firmanın masrafları (sayfalı). Fiş görseli olanlarda `receipt_url` dolu döner. Parametreler: - `status` (query): pending | approved | rejected | paid | cancelled (virgülle çoklu) - `employee_id` (query): Çalışana göre filtre - `category_id` (query): Kategoriye göre filtre - `from` (query): YYYY-MM-DD — masraf tarihi >= - `to` (query): YYYY-MM-DD — masraf tarihi <= - `search` (query): Başlık/işyeri araması - `page` (query): Sayfa - `per_page` (query): Sayfa boyutu (max 100) Örnek yanıt: ```json { "data": [ { "id": 987, "status": "approved", "title": "Ofis malzemesi", "description": null, "amount": 250.5, "currency": "TRY", "tax_amount": 37.58, "expense_date": "2026-07-10", "merchant_name": "Kırtasiye A.Ş.", "payment_method": "kredi_karti", "category": { "id": 8, "name": "Ofis Malzemeleri" }, "employee": { "id": 45, "employee_number": "ABCD-001", "full_name": "Ahmet Yılmaz", "department": "Yazılım" }, "has_receipt": true, "receipt_url": "https://empuno.com/api/company/v1/expenses/987/receipt", "approved_at": "2026-07-11T10:30:00+00:00", "paid_at": null, "rejected_reason": null, "submitted_at": "2026-07-11T09:00:00+00:00", "created_at": "2026-07-11T08:45:00+00:00", "updated_at": "2026-07-11T10:30:00+00:00" } ], "meta": { "current_page": 1, "per_page": 25, "total": 30, "last_page": 2, "from": 1, "to": 25 } } ``` ### GET /expenses/{id} Tek masraf detayı — kalem (items) listesi ve fiş görseli varyant URL'leri dahil. Parametreler: - `id` (path): Masraf ID Örnek yanıt: ```json { "data": { "id": 987, "status": "approved", "title": "Ofis malzemesi", "amount": 250.5, "currency": "TRY", "expense_date": "2026-07-10", "merchant_name": "Kırtasiye A.Ş.", "has_receipt": true, "receipt_url": "https://empuno.com/api/company/v1/expenses/987/receipt", "items": [ { "name": "Defter (5'li)", "quantity": 1, "price": 150 } ], "receipt": { "url": "https://empuno.com/api/company/v1/expenses/987/receipt", "processed_url": "https://empuno.com/api/company/v1/expenses/987/receipt?variant=processed", "original_url": "https://empuno.com/api/company/v1/expenses/987/receipt?variant=original" } } } ``` ### GET /expenses/{id}/receipt Fiş görseline erişim. Anahtar + firma sahipliği doğrulanır, taze imzalı görsel URL'ine 302 yönlendirir. HTTP istemcinizi yönlendirmeyi takip edecek şekilde ayarlayın. Parametreler: - `id` (path): Masraf ID - `variant` (query): processed (varsayılan) | original Yanıt: 302 Found → Location: imzalı görsel URL'i (image/jpeg). Fiş yoksa 404 JSON. ### GET /expense-categories Firmanın aktif masraf kategorileri (referans veri). Örnek yanıt: ```json { "data": [ { "id": 8, "name": "Ofis Malzemeleri", "description": null, "requires_receipt": true, "max_amount": null } ] } ``` ## Hatalar - 401: Anahtar eksik veya geçersiz/iptal edilmiş. - 403: Anahtara bağlı firma pasif. - 404: Kayıt bulunamadı (veya başka firmaya ait). - 429: Hız sınırı aşıldı. HTML dokümantasyon: https://empuno.com/api-docs OpenAPI: https://empuno.com/api-docs/openapi.json