{
    "openapi": "3.1.0",
    "info": {
        "title": "empuno Company API",
        "version": "1.0.0",
        "description": "Firmaların izin ve masraf verilerini kendi sistemlerine çekmesi için salt-okuma REST API. Kimlik doğrulama: per-firma API anahtarı (Bearer). Yönetim: Firma Ayarları → API sekmesi."
    },
    "servers": [
        {
            "url": "https://empuno.com/api/company/v1"
        }
    ],
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "API Key"
            }
        }
    },
    "paths": {
        "/me": {
            "get": {
                "tags": [
                    "Genel"
                ],
                "summary": "Anahtarı doğrula & firmayı gör",
                "description": "Anahtarın geçerliliğini test etmek, bağlı firmayı ve mevcut uçları görmek için ilk çağrı.",
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Başarılı",
                        "content": {
                            "application/json": {
                                "example": {
                                    "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
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        },
        "/employees": {
            "get": {
                "tags": [
                    "Çalışanlar"
                ],
                "summary": "Çalışanları listele",
                "description": "Firmanın çalışanları (sayfalı).",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "active | inactive | terminated (virgülle çoklu)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Ad/soyad/personel no araması",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Sayfa (varsayılan 1)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Sayfa boyutu (varsayılan 25, max 100)",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Başarılı",
                        "content": {
                            "application/json": {
                                "example": {
                                    "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
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        },
        "/employees/{id}": {
            "get": {
                "tags": [
                    "Çalışanlar"
                ],
                "summary": "Tek çalışan",
                "description": "Kimlik ile tek çalışan.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Çalışan ID",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Başarılı",
                        "content": {
                            "application/json": {
                                "example": {
                                    "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"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        },
        "/leaves": {
            "get": {
                "tags": [
                    "İzinler"
                ],
                "summary": "İzinleri listele",
                "description": "Firmanın izin talepleri (sayfalı, tarih aralığına göre filtrelenebilir).",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "pending | approved | rejected | cancelled (virgülle çoklu)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "employee_id",
                        "in": "query",
                        "required": false,
                        "description": "Çalışana göre filtre",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "leave_type_id",
                        "in": "query",
                        "required": false,
                        "description": "İzin türüne göre filtre",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "YYYY-MM-DD — bu tarihle kesişen izinler",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "YYYY-MM-DD — bu tarihle kesişen izinler",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Çalışan adı/no araması",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Sayfa",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Sayfa boyutu (max 100)",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Başarılı",
                        "content": {
                            "application/json": {
                                "example": {
                                    "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
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        },
        "/leaves/{id}": {
            "get": {
                "tags": [
                    "İzinler"
                ],
                "summary": "Tek izin",
                "description": "Tek izin detayı (belge yükümlülüğü bilgisi dahil; tıbbi belge dosyaları KVKK gereği paylaşılmaz).",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "İzin ID",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Başarılı",
                        "content": {
                            "application/json": {
                                "example": {
                                    "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
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        },
        "/leave-types": {
            "get": {
                "tags": [
                    "İzinler"
                ],
                "summary": "İzin türleri",
                "description": "Firmanın aktif izin türleri (referans veri).",
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Başarılı",
                        "content": {
                            "application/json": {
                                "example": {
                                    "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
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        },
        "/expenses": {
            "get": {
                "tags": [
                    "Masraflar"
                ],
                "summary": "Masrafları listele",
                "description": "Firmanın masrafları (sayfalı). Fiş görseli olanlarda `receipt_url` dolu döner.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "pending | approved | rejected | paid | cancelled (virgülle çoklu)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "employee_id",
                        "in": "query",
                        "required": false,
                        "description": "Çalışana göre filtre",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "category_id",
                        "in": "query",
                        "required": false,
                        "description": "Kategoriye göre filtre",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "YYYY-MM-DD — masraf tarihi >=",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "YYYY-MM-DD — masraf tarihi <=",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Başlık/işyeri araması",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Sayfa",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Sayfa boyutu (max 100)",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Başarılı",
                        "content": {
                            "application/json": {
                                "example": {
                                    "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
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        },
        "/expenses/{id}": {
            "get": {
                "tags": [
                    "Masraflar"
                ],
                "summary": "Tek masraf",
                "description": "Tek masraf detayı — kalem (items) listesi ve fiş görseli varyant URL'leri dahil.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Masraf ID",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Başarılı",
                        "content": {
                            "application/json": {
                                "example": {
                                    "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"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        },
        "/expenses/{id}/receipt": {
            "get": {
                "tags": [
                    "Masraflar"
                ],
                "summary": "Fiş görseli",
                "description": "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.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Masraf ID",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "variant",
                        "in": "query",
                        "required": false,
                        "description": "processed (varsayılan) | original",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "302": {
                        "description": "302 Found → Location: imzalı görsel URL'i (image/jpeg). Fiş yoksa 404 JSON."
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        },
        "/expense-categories": {
            "get": {
                "tags": [
                    "Masraflar"
                ],
                "summary": "Masraf kategorileri",
                "description": "Firmanın aktif masraf kategorileri (referans veri).",
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Başarılı",
                        "content": {
                            "application/json": {
                                "example": {
                                    "data": [
                                        {
                                            "id": 8,
                                            "name": "Ofis Malzemeleri",
                                            "description": null,
                                            "requires_receipt": true,
                                            "max_amount": null
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Anahtar eksik/geçersiz"
                    },
                    "404": {
                        "description": "Kayıt bulunamadı"
                    },
                    "429": {
                        "description": "Hız sınırı aşıldı"
                    }
                }
            }
        }
    }
}