{"openapi":"3.1.0","info":{"title":"Parsek Public API","version":"1.0.0","description":"Parsek e-Fatura Public API. e-Invoice creation, sending, querying and cancellation. Secured with API keys (X-API-Key).","contact":{"name":"Parsek","url":"https://parsekpro.com/iletisim"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://api.parsekpro.com","description":"Production"}],"tags":[{"name":"Invoices","description":"e-Invoice operations"},{"name":"Current Accounts","description":"Current account (cari) operations"},{"name":"Inventory","description":"Products, stock levels and movements"},{"name":"Attendance / PDKS","description":"Attendance/time-tracking push from PDKS hardware"},{"name":"Webhooks","description":"Outbound event webhooks (HMAC-SHA256 signed)"},{"name":"Utilities","description":"Helper endpoints"},{"name":"API Keys","description":"API key management (app session)"}],"components":{"securitySchemes":{"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key created in Parsek app (Settings → API Keys). Prefixed with pk_"},"bearerAuth":{"type":"http","scheme":"bearer","description":"Parsek app session token (Supabase). For key management endpoints."}}},"paths":{"/api/external/v1/invoices":{"post":{"operationId":"create-invoice","summary":"Create invoice (optionally send)","description":"Creates a new e-Archive/e-Invoice draft. If `send_immediately: true` is passed, the invoice is sent immediately.","tags":["Invoices"],"security":[{"apiKeyAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"invoice":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"payable_amount":{"type":"integer"}}}}},"example":{"success":true,"invoice":{"id":"9f1c2b7e-...","status":"draft","payable_amount":1200}}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"send_immediately":{"type":"boolean"},"customer":{"type":"object","properties":{"name":{"type":"string"},"vkn":{"type":"string"},"email":{"type":"string"},"tax_office":{"type":"string"},"address":{"type":"object","properties":{"city":{"type":"string"},"country":{"type":"string"}}}}},"lines":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"integer"},"unit_price":{"type":"integer"},"tax_percent":{"type":"integer"},"unit_code":{"type":"string"}}}},"invoice_type":{"type":"string"},"currency":{"type":"string"}}},"example":{"send_immediately":false,"customer":{"name":"Örnek Müşteri A.Ş.","vkn":"1234567890","email":"muhasebe@ornekmusteri.com","tax_office":"Kadıköy","address":{"city":"İstanbul","country":"Türkiye"}},"lines":[{"name":"Danışmanlık Hizmeti","quantity":1,"unit_price":1000,"tax_percent":20,"unit_code":"C62"}],"invoice_type":"SATIS","currency":"TRY"}}}}},"get":{"operationId":"list-invoices","summary":"List invoices","description":"Lists the company invoices with pagination. Filterable by `direction` and `status`.","tags":["Invoices"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"direction","in":"query","required":false,"description":"'outbound' / 'inbound'","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Status (draft, sent, error…)","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Page (0-based, default 0)","schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"description":"Page size (default 20)","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"invoice_number":{"type":"string"},"direction":{"type":"string"},"status":{"type":"string"},"issue_date":{"type":"string"},"customer_name":{"type":"string"},"payable_amount":{"type":"integer"},"tax_amount":{"type":"integer"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"9f1c2b7e-...","invoice_number":"PSK2026000000123","direction":"outbound","status":"sent","issue_date":"2026-02-10","customer_name":"Örnek Müşteri A.Ş.","payable_amount":1200,"tax_amount":200}],"total":42,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/invoices/{id}":{"get":{"operationId":"get-invoice","summary":"Invoice detail","description":"Returns all fields of a single invoice.","tags":["Invoices"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Invoice ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"invoice_number":{"type":"string"},"status":{"type":"string"},"payable_amount":{"type":"integer"},"lines":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"integer"},"unitPrice":{"type":"integer"},"taxPercent":{"type":"integer"}}}}}},"example":{"id":"9f1c2b7e-...","invoice_number":"PSK2026000000123","status":"sent","payable_amount":1200,"lines":[{"name":"Danışmanlık Hizmeti","quantity":1,"unitPrice":1000,"taxPercent":20}]}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/invoices/{id}/status":{"get":{"operationId":"invoice-status","summary":"Query invoice status","description":"Returns the current status code and message of the invoice.","tags":["Invoices"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Invoice ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"invoice_uuid":{"type":"string"},"status":{"type":"string"},"status_code":{"type":"integer"},"status_message":{"type":"object"}}},"example":{"id":"9f1c2b7e-...","invoice_uuid":"A1B2C3-...","status":"sent","status_code":100,"status_message":null}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/invoices/{id}/pdf":{"get":{"operationId":"invoice-pdf","summary":"Download invoice PDF","description":"Returns the invoice PDF output (application/pdf).","tags":["Invoices"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Invoice ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/invoices/{id}/cancel":{"post":{"operationId":"invoice-cancel","summary":"Cancel e-Archive invoice","description":"Only invoices in the e-Archive (EARSIVFATURA) scenario can be cancelled.","tags":["Invoices"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Invoice ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"result":{"type":"object","properties":{}}}},"example":{"success":true,"result":{}}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"cancel_date":{"type":"string"}}},"example":{"cancel_date":"2026-02-11"}}}}}},"/api/external/v1/check-einvoice-user":{"post":{"operationId":"check-einvoice-user","summary":"Check e-Invoice registered user","description":"Checks whether the given VKN/TCKN is a registered e-Invoice (GİB) user.","tags":["Utilities"],"security":[{"apiKeyAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"is_einvoice_user":{"type":"boolean"}}},"example":{"is_einvoice_user":true}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"vkn":{"type":"string"}}},"example":{"vkn":"1234567890"}}}}}},"/api/external/v1/current-accounts":{"get":{"operationId":"list-current-accounts","summary":"List current accounts","description":"Lists company current accounts with pagination. Filters: `account_type` (CUSTOMER/VENDOR/SUBCONTRACTOR/EMPLOYEE), `status` (ACTIVE/PASSIVE), `q` (name/code search), `updated_since` (delta sync).","tags":["Current Accounts"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"account_type","in":"query","required":false,"description":"CUSTOMER/VENDOR/SUBCONTRACTOR/EMPLOYEE","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"ACTIVE / PASSIVE","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Name/code search","schema":{"type":"string"}},{"name":"updated_since","in":"query","required":false,"description":"Updated after this timestamp","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Page (0-based)","schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"description":"Page size (max 100)","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"account_code":{"type":"string"},"account_name":{"type":"string"},"account_type":{"type":"string"},"balance":{"type":"integer"},"base_currency":{"type":"string"},"status":{"type":"string"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"uuid","account_code":"MUS-00001","account_name":"Örnek Müşteri A.Ş.","account_type":"CUSTOMER","balance":12500,"base_currency":"TRY","status":"ACTIVE"}],"total":42,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}},"post":{"operationId":"create-current-account","summary":"Create current account","description":"Creates a new current account. If `account_code` is omitted it is auto-generated by type. Supports the `Idempotency-Key` header.","tags":["Current Accounts"],"security":[{"apiKeyAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"account_code":{"type":"string"},"account_name":{"type":"string"},"account_type":{"type":"string"},"status":{"type":"string"},"base_currency":{"type":"string"}}},"example":{"id":"uuid","account_code":"MUS-00007","account_name":"Örnek Müşteri A.Ş.","account_type":"CUSTOMER","status":"ACTIVE","base_currency":"TRY"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"account_name":{"type":"string"},"account_type":{"type":"string"},"tax_number":{"type":"string"},"email":{"type":"string"},"base_currency":{"type":"string"}}},"example":{"account_name":"Örnek Müşteri A.Ş.","account_type":"CUSTOMER","tax_number":"1234567890","email":"muhasebe@ornek.com","base_currency":"TRY"}}}}}},"/api/external/v1/current-accounts/{id}":{"get":{"operationId":"get-current-account","summary":"Current account detail","description":"Returns all fields of a single current account.","tags":["Current Accounts"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Account ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"account_code":{"type":"string"},"account_name":{"type":"string"},"account_type":{"type":"string"},"tax_number":{"type":"string"},"iban":{"type":"string"},"balance":{"type":"integer"},"base_currency":{"type":"string"},"status":{"type":"string"}}},"example":{"id":"uuid","account_code":"MUS-00001","account_name":"Örnek Müşteri A.Ş.","account_type":"CUSTOMER","tax_number":"1234567890","iban":"TR..","balance":12500,"base_currency":"TRY","status":"ACTIVE"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}},"put":{"operationId":"update-current-account","summary":"Update current account","description":"Updates the given fields (whitelisted fields only).","tags":["Current Accounts"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Account ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"account_code":{"type":"string"},"phone":{"type":"string"},"status":{"type":"string"}}},"example":{"id":"uuid","account_code":"MUS-00001","phone":"05551112233","status":"PASSIVE"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"phone":{"type":"string"},"status":{"type":"string"}}},"example":{"phone":"05551112233","status":"PASSIVE"}}}}}},"/api/external/v1/current-accounts/{id}/balance":{"get":{"operationId":"current-account-balance","summary":"Current account balance","description":"Returns debit/credit/net balance and multi-currency balances.","tags":["Current Accounts"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Account ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"account_id":{"type":"string"},"debit_balance":{"type":"integer"},"credit_balance":{"type":"integer"},"balance":{"type":"integer"},"balance_base":{"type":"integer"},"base_currency":{"type":"string"},"balances":{"type":"object","properties":{"TRY":{"type":"integer"}}}}},"example":{"account_id":"uuid","debit_balance":30000,"credit_balance":17500,"balance":12500,"balance_base":12500,"base_currency":"TRY","balances":{"TRY":12500}}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/current-accounts/{id}/transactions":{"get":{"operationId":"current-account-transactions","summary":"Current account transactions","description":"Returns account transactions with pagination. `from`/`to` date filter.","tags":["Current Accounts"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Account ID","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Start date","schema":{"type":"string"}},{"name":"to","in":"query","required":false,"description":"End date","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"transaction_date":{"type":"string"},"transaction_type":{"type":"string"},"amount":{"type":"integer"},"currency_code":{"type":"string"},"description":{"type":"string"},"document_number":{"type":"string"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"uuid","transaction_date":"2026-02-10","transaction_type":"DEBIT","amount":1200,"currency_code":"TRY","description":"Fatura","document_number":"PSK2026..."}],"total":12,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/products":{"get":{"operationId":"list-products","summary":"Product/material catalog","description":"Lists the material catalog. Filters: `q` (name search), `material_type`, `updated_since`.","tags":["Inventory"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Name search","schema":{"type":"string"}},{"name":"material_type","in":"query","required":false,"description":"CONSUMABLE / USABLE","schema":{"type":"string"}},{"name":"updated_since","in":"query","required":false,"description":"Delta sync","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Page","schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"description":"Size (max 100)","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"material_type":{"type":"string"},"minimum_stock_level":{"type":"integer"},"current_avg_cost":{"type":"integer"},"sale_price":{"type":"integer"},"default_currency":{"type":"string"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"uuid","name":"Çimento CEM I 42.5","material_type":"CONSUMABLE","minimum_stock_level":100,"current_avg_cost":250,"sale_price":300,"default_currency":"TRY"}],"total":128,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/products/{id}":{"get":{"operationId":"get-product","summary":"Product detail","description":"Returns all fields of a single material.","tags":["Inventory"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Material ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"material_type":{"type":"string"},"current_avg_cost":{"type":"integer"},"total_stock_value":{"type":"integer"}}},"example":{"id":"uuid","name":"Çimento CEM I 42.5","material_type":"CONSUMABLE","current_avg_cost":250,"total_stock_value":32000}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/inventory/levels":{"get":{"operationId":"inventory-levels","summary":"Stock levels","description":"Current stock levels per warehouse/branch. Filters: `material_id`, `branch_id`, `warehouse_location_id`.","tags":["Inventory"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"material_id","in":"query","required":false,"description":"Material filter","schema":{"type":"string"}},{"name":"branch_id","in":"query","required":false,"description":"Branch filter","schema":{"type":"string"}},{"name":"warehouse_location_id","in":"query","required":false,"description":"Warehouse filter","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"material_id":{"type":"string"},"material_name":{"type":"string"},"branch_id":{"type":"string"},"warehouse_location_id":{"type":"string"},"current_quantity":{"type":"integer"},"total_incoming":{"type":"integer"},"total_outgoing":{"type":"integer"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"material_id":"uuid","material_name":"Çimento CEM I 42.5","branch_id":"uuid","warehouse_location_id":"uuid","current_quantity":450,"total_incoming":900,"total_outgoing":450}],"total":12,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/inventory/movements":{"get":{"operationId":"inventory-movements-list","summary":"Stock movements","description":"Lists stock movements. Filters: `material_id`, `branch_id`, `transaction_type`, `from`/`to`.","tags":["Inventory"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"material_id","in":"query","required":false,"description":"Material","schema":{"type":"string"}},{"name":"transaction_type","in":"query","required":false,"description":"IN/OUT/ADJUSTMENT…","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Start","schema":{"type":"string"}},{"name":"to","in":"query","required":false,"description":"End","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"material_id":{"type":"string"},"transaction_type":{"type":"string"},"quantity":{"type":"integer"},"unit_price":{"type":"integer"},"currency_code":{"type":"string"},"created_at":{"type":"string"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"uuid","material_id":"uuid","transaction_type":"IN","quantity":100,"unit_price":250,"currency_code":"TRY","created_at":"2026-02-10T10:00:00Z"}],"total":340,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}},"post":{"operationId":"create-inventory-movement","summary":"Create stock movement","description":"Stock in/out/adjustment. `transaction_type`: IN, OUT, ADJUSTMENT, COUNT_ADJUSTMENT. Stock level and valuation (FIFO/Average) are updated automatically. 409 on insufficient stock for OUT. Supports `Idempotency-Key`.","tags":["Inventory"],"security":[{"apiKeyAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"material_id":{"type":"string"},"transaction_type":{"type":"string"},"quantity":{"type":"integer"},"unit_price":{"type":"integer"},"currency_code":{"type":"string"},"created_at":{"type":"string"}}},"example":{"id":"uuid","material_id":"uuid","transaction_type":"IN","quantity":100,"unit_price":250,"currency_code":"TRY","created_at":"2026-02-10T10:00:00Z"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"material_id":{"type":"string"},"transaction_type":{"type":"string"},"quantity":{"type":"integer"},"unit_price":{"type":"integer"},"notes":{"type":"string"}}},"example":{"material_id":"uuid","transaction_type":"IN","quantity":100,"unit_price":250,"notes":"Satın alma girişi"}}}}}},"/api/external/v1/warehouses":{"get":{"operationId":"list-warehouses","summary":"Warehouse/location list","description":"Lists warehouses and locations. Filters: `branch_id`, `is_active`.","tags":["Inventory"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"branch_id","in":"query","required":false,"description":"Branch","schema":{"type":"string"}},{"name":"is_active","in":"query","required":false,"description":"Active filter","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"},"location_path":{"type":"string"},"is_active":{"type":"boolean"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"uuid","code":"DEPO-01","name":"Merkez Depo","location_path":"Merkez Depo","is_active":true}],"total":6,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/employees":{"get":{"operationId":"list-employees","summary":"Employee directory (mapping)","description":"Returns the employee directory for PDKS card/number mapping. Filters: `q`, `status`, `branch_id`, `updated_since`.","tags":["Attendance / PDKS"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Name / number / card search","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"active / passive","schema":{"type":"string"}},{"name":"updated_since","in":"query","required":false,"description":"ISO8601 delta sync","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"employee_number":{"type":"string"},"pdks_card_no":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"full_name":{"type":"string"},"tc_identity_no":{"type":"string"},"branch_id":{"type":"string"},"status":{"type":"string"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"uuid","employee_number":"SICIL-9001","pdks_card_no":"CARD-001","first_name":"Ali","last_name":"Yılmaz","full_name":"Ali Yılmaz","tc_identity_no":"12345678901","branch_id":"uuid","status":"active"}],"total":42,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/attendance":{"get":{"operationId":"list-attendance","summary":"Daily attendance records","description":"Lists daily attendance records. Filters: `employee_id`, `branch_id`, `status_code`, `date`, `from`/`to`.","tags":["Attendance / PDKS"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"employee_id","in":"query","required":false,"description":"Employee","schema":{"type":"string"}},{"name":"status_code","in":"query","required":false,"description":"X/I/R/YG/DD/UI","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Start (YYYY-MM-DD)","schema":{"type":"string"}},{"name":"to","in":"query","required":false,"description":"End (YYYY-MM-DD)","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"employee_id":{"type":"string"},"date":{"type":"string"},"status_code":{"type":"string"},"work_hours":{"type":"number"},"overtime_hours":{"type":"number"},"check_in_time":{"type":"string"},"check_out_time":{"type":"string"},"source":{"type":"string"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"uuid","employee_id":"uuid","date":"2026-02-10","status_code":"X","work_hours":9.5,"overtime_hours":1.5,"check_in_time":"2026-02-10T05:00:00Z","check_out_time":"2026-02-10T14:30:00Z","source":"pdks_api"}],"total":120,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}},"post":{"operationId":"create-attendance","summary":"PDKS attendance push (punch or daily)","description":"Two modes for PDKS hardware/integrators: (1) `punches` — raw in/out events are pushed; daily attendance (work hours via IN→OUT pairing) is computed automatically; resends are idempotent (dedup). (2) `records` — daily attendance is written directly (`status_code`: X/I/R/YG/DD/UI). Employees are matched by `card_no`, `employee_number`, `tc_identity_no` or `employee_id`. Unmatched entries are returned in `unmatched`. `standard_daily_hours` (default 8) is the overtime baseline. Supports `Idempotency-Key`. Triggers the `attendance.recorded` webhook on success.","tags":["Attendance / PDKS"],"security":[{"apiKeyAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"mode":{"type":"string"},"punches_received":{"type":"integer"},"punches_inserted":{"type":"integer"},"punches_skipped_duplicate":{"type":"integer"},"attendance_upserted":{"type":"integer"},"unmatched":{"type":"array","items":{"type":"object"}}}},"example":{"mode":"punch","punches_received":2,"punches_inserted":2,"punches_skipped_duplicate":0,"attendance_upserted":1,"unmatched":[]}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"standard_daily_hours":{"type":"integer"},"punches":{"type":"array","items":{"type":"object","properties":{"card_no":{"type":"string"},"timestamp":{"type":"string"},"direction":{"type":"string"},"device_id":{"type":"string"}}}}}},"example":{"standard_daily_hours":8,"punches":[{"card_no":"CARD-001","timestamp":"2026-02-10T05:00:00Z","direction":"IN","device_id":"GATE-1"},{"card_no":"CARD-001","timestamp":"2026-02-10T14:30:00Z","direction":"OUT","device_id":"GATE-1"}]}}}}}},"/api/external/v1/attendance/punches":{"get":{"operationId":"list-attendance-punches","summary":"Raw PDKS punch events","description":"Returns raw device punch events (debug/audit). Filters: `employee_id`, `device_id`, `matched`, `from`/`to`.","tags":["Attendance / PDKS"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"employee_id","in":"query","required":false,"description":"Employee","schema":{"type":"string"}},{"name":"device_id","in":"query","required":false,"description":"Device ID","schema":{"type":"string"}},{"name":"matched","in":"query","required":false,"description":"Match status","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"employee_id":{"type":"string"},"card_no":{"type":"string"},"device_id":{"type":"string"},"direction":{"type":"string"},"punch_time":{"type":"string"},"attendance_date":{"type":"string"},"matched":{"type":"boolean"},"source":{"type":"string"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"uuid","employee_id":"uuid","card_no":"CARD-001","device_id":"GATE-1","direction":"IN","punch_time":"2026-02-10T05:00:00Z","attendance_date":"2026-02-10","matched":true,"source":"pdks_api"}],"total":240,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/webhooks":{"get":{"operationId":"list-webhooks","summary":"List webhook endpoints","description":"Returns the company webhook endpoints and the subscribable event catalog (`available_events`).","tags":["Webhooks"],"security":[{"apiKeyAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"is_active":{"type":"boolean"},"secret_masked":{"type":"string"}}}},"available_events":{"type":"array","items":{"type":"string"}}}},"example":{"data":[{"id":"uuid","url":"https://ornek.com/webhook","events":["invoice.status_changed","payment.received"],"is_active":true,"secret_masked":"whsec_…a1b2"}],"available_events":["current_account.created","current_account.updated","inventory.movement.created","inventory.low_stock","invoice.status_changed","payment.received","attendance.recorded","webhook.test"]}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}},"post":{"operationId":"create-webhook","summary":"Create webhook","description":"Adds a new webhook endpoint. Only public `https://` URLs are accepted (private/internal IPs are rejected by SSRF protection). The `secret` is returned in full ONLY once at creation — store it for HMAC-SHA256 signature verification.","tags":["Webhooks"],"security":[{"apiKeyAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"is_active":{"type":"boolean"},"secret":{"type":"string"}}},"example":{"id":"uuid","url":"https://ornek.com/parsek-webhook","events":["invoice.status_changed","payment.received"],"is_active":true,"secret":"whsec_9f1c2b7e...(yalnizca burada tam doner)"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"description":{"type":"string"}}},"example":{"url":"https://ornek.com/parsek-webhook","events":["invoice.status_changed","payment.received"],"description":"Muhasebe entegrasyonu"}}}}}},"/api/external/v1/webhooks/{id}":{"get":{"operationId":"get-webhook","summary":"Webhook detail","description":"Returns a single webhook endpoint detail (secret masked).","tags":["Webhooks"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"is_active":{"type":"boolean"},"secret_masked":{"type":"string"}}},"example":{"id":"uuid","url":"https://ornek.com/webhook","events":["payment.received"],"is_active":true,"secret_masked":"whsec_…a1b2"}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}},"put":{"operationId":"update-webhook","summary":"Update webhook","description":"Updates URL, event list, `is_active` (enable/disable) or description. SSRF check is re-applied if the URL changes.","tags":["Webhooks"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"is_active":{"type":"boolean"}}},"example":{"id":"uuid","url":"https://ornek.com/parsek-webhook","events":["payment.received"],"is_active":false}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"is_active":{"type":"boolean"}}},"example":{"is_active":false}}}}},"delete":{"operationId":"delete-webhook","summary":"Delete webhook","description":"Deletes the webhook endpoint and its delivery records.","tags":["Webhooks"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}},"example":{"success":true}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/webhooks/{id}/test":{"post":{"operationId":"test-webhook","summary":"Send test delivery","description":"Sends a `webhook.test` event synchronously and returns the result (HTTP code, attempts).","tags":["Webhooks"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"delivered":{"type":"boolean"},"response_code":{"type":"integer"},"error":{"type":"object"},"attempts":{"type":"integer"}}},"example":{"delivered":true,"response_code":200,"error":null,"attempts":1}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/webhooks/{id}/deliveries":{"get":{"operationId":"list-webhook-deliveries","summary":"List delivery logs","description":"Returns delivery attempts for the endpoint (status, attempts, HTTP code, error) with pagination. For debugging.","tags":["Webhooks"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Page (0-based)","schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"description":"Page size","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"event":{"type":"string"},"status":{"type":"string"},"attempts":{"type":"integer"},"response_code":{"type":"integer"},"error":{"type":"object"},"created_at":{"type":"string"}}}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"example":{"data":[{"id":"uuid","event":"payment.received","status":"success","attempts":1,"response_code":200,"error":null,"created_at":"2026-02-10T10:00:00Z"}],"total":12,"page":0,"limit":20}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver":{"post":{"operationId":"redeliver-webhook","summary":"Redeliver a delivery","description":"Manually re-sends a failed (or any) delivery, resetting the attempt counter; returns the result synchronously.","tags":["Webhooks"],"security":[{"apiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}},{"name":"deliveryId","in":"path","required":true,"description":"Delivery ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"delivered":{"type":"boolean"},"response_code":{"type":"integer"},"error":{"type":"object"},"attempts":{"type":"integer"},"will_retry":{"type":"boolean"}}},"example":{"delivered":true,"response_code":200,"error":null,"attempts":1,"will_retry":false}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}},"/api/external/keys":{"get":{"operationId":"list-keys","summary":"List API keys","description":"Lists company API keys (admin/super_admin). Keys are returned masked.","tags":["API Keys"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"key_name":{"type":"string"},"api_key_masked":{"type":"string"},"is_active":{"type":"boolean"},"rate_limit":{"type":"integer"},"request_count":{"type":"integer"}}}},"example":[{"id":"uuid","key_name":"Muhasebe Entegrasyonu","api_key_masked":"...a1b2c3d4","is_active":true,"rate_limit":60,"request_count":128}]}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}},"post":{"operationId":"create-key","summary":"Create API key","description":"Generates a new API key (pk_ prefixed). The full key is shown only once at creation.","tags":["API Keys"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"api_key":{"type":"string"},"message":{"type":"string"}}},"example":{"id":"uuid","api_key":"pk_9f...c3","message":"API anahtari olusturuldu. Bu anahtari guvenli bir yerde saklayin."}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"key_name":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"}},"rate_limit":{"type":"integer"}}},"example":{"key_name":"Muhasebe Entegrasyonu","permissions":["einvoice"],"rate_limit":60}}}}}},"/api/external/keys/{id}":{"delete":{"operationId":"delete-key","summary":"Delete API key","description":"Deletes the given API key.","tags":["API Keys"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Key ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}},"example":{"success":true}}}},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized — invalid or missing API key"},"403":{"description":"Forbidden — domain not allowed / insufficient role"},"404":{"description":"Not Found"}}}}}}