Metadata-Version: 2.4
Name: kita
Version: 2.1.1
Summary: Official Python SDK for Kita Document Processing API
Author-email: Kita Team <support@usekita.com>
Maintainer-email: Kita Team <support@usekita.com>
License: MIT
Project-URL: Homepage, https://usekita.com
Project-URL: Documentation, https://docs.usekita.com
Project-URL: Repository, https://github.com/usekita/kita-python-sdk
Project-URL: Issues, https://github.com/usekita/kita-python-sdk/issues
Project-URL: Changelog, https://github.com/usekita/kita-python-sdk/blob/main/CHANGELOG.md
Keywords: kita,document-processing,ocr,bank-statement,payslip,pdf,api,sdk
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.25.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: types-requests>=2.28.0; extra == "dev"
Dynamic: requires-python

# Kita API Documentation

Extract structured data from documents — bank statements, payslips, invoices, government IDs, and 30+ other types. Upload a file, get back clean JSON with transactions, metadata, fraud signals, and more.

---

## Authentication

Every request requires an API key in the `Authorization` header. Get your key from the [Kita dashboard](https://portal.usekita.com).

```
Authorization: Bearer kita_prod_your_key_here
```

**Base URL:** `https://portal.usekita.com`

---

## Quick Start

Upload a document, poll for the result, and use the extracted data.

<!-- cURL -->
```bash
# 1. Upload a document
curl -X POST https://portal.usekita.com/api/process-async \
  -H "Authorization: Bearer kita_prod_..." \
  -F "file=@statement.pdf" \
  -F "document_type=bank_statement"
# Returns: { "documentId": 12345, "status": "pending" }

# 2. Poll for the result
curl https://portal.usekita.com/api/results/12345 \
  -H "Authorization: Bearer kita_prod_..."
# Returns full extracted data once status is "completed"
```

<!-- Python -->
```python
from kita import KitaClient

client = KitaClient(api_key="kita_prod_...")

# Process and wait for result (handles polling automatically)
result = client.process("statement.pdf", "bank_statement")

print(result.metadata)        # Account holder, bank, dates, balances
print(result.transactions)    # Categorized transaction list
print(result.metrics)         # Inflow, outflow, averages, breakdowns

result.save_json("output.json")
```

<!-- JavaScript -->
```javascript
const res = await fetch("https://portal.usekita.com/api/process-async", {
  method: "POST",
  headers: { Authorization: "Bearer kita_prod_..." },
  body: form, // FormData with file + document_type
});
const { documentId } = await res.json();

// Poll GET /api/results/{documentId} until status is "completed"
```

---

## Endpoints

### Process a Document

Upload a file for processing. Returns a `documentId` to poll for results.

This endpoint accepts **two upload modes** on the same URL:

#### Option A: Multipart file upload

```
POST /api/process-async
Content-Type: multipart/form-data
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `file` | file | Yes | PDF, PNG, JPG, TIFF, or BMP |
| `document_type` | string | Yes | See [Document Types](#document-types) |
| `password` | string | No | PDF password if encrypted |

**cURL:**
```bash
curl -X POST https://portal.usekita.com/api/process-async \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@invoice.pdf" \
  -F "document_type=sales_invoice"
```

#### Option B: Base64 JSON upload

Send the file contents as a base64-encoded string in a JSON body. Useful when you already have the file in memory (e.g. from a database, another API, or a browser `FileReader`).

```
POST /api/process-async
Content-Type: application/json
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `file_base64` | string | Yes | Base64-encoded file contents. Data URI prefix (`data:application/pdf;base64,...`) is accepted and stripped automatically. |
| `filename` | string | Yes | Filename with extension (e.g. `"statement.pdf"`). The extension determines file type validation. |
| `document_type` | string | Yes | See [Document Types](#document-types) |
| `password` | string | No | PDF password if encrypted |

**cURL:**
```bash
curl -X POST https://portal.usekita.com/api/process-async \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file_base64": "JVBERi0xLjQg...",
    "filename": "statement.pdf",
    "document_type": "bank_statement"
  }'
```

**JavaScript:**
```javascript
// From a browser File input
const file = inputElement.files[0];
const reader = new FileReader();
reader.onload = async () => {
  const res = await fetch("https://portal.usekita.com/api/process-async", {
    method: "POST",
    headers: {
      Authorization: "Bearer kita_prod_...",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      file_base64: reader.result, // data URI is accepted
      filename: file.name,
      document_type: "bank_statement",
    }),
  });
  const { documentId } = await res.json();
};
reader.readAsDataURL(file);
```

**Python (file upload):**
```python
result = client.process("invoice.pdf", "sales_invoice")
# wait=True by default — returns completed DocumentResult
# Set wait=False to get the pending response immediately
```

**Python (base64):**
```python
import base64

with open("invoice.pdf", "rb") as f:
    b64 = base64.b64encode(f.read()).decode()

result = client.process_base64(b64, "invoice.pdf", "sales_invoice")
```

**Response (both modes):**
```json
{
  "documentId": 12345,
  "status": "pending",
  "message": "Document queued for processing"
}
```

---

### Get Result

Retrieve the full processed result for a document. Poll this endpoint until `status` is `"completed"`.

```
GET /api/results/{documentId}
```

**cURL:**
```bash
curl https://portal.usekita.com/api/results/12345 \
  -H "Authorization: Bearer $API_KEY"
```

**Python:**
```python
result = client.get_result(12345)
print(result.status)         # "completed"
print(result.document_type)  # "bank_statement"
print(result.metadata)       # Account info
print(result.transactions)   # Transaction list
```

**Response** (see [Response Format](#response-format) for full structure):
```json
{
  "status": "completed",
  "document_type": "bank_statement",
  "document_id": 12345,
  "filename": "statement.pdf",
  "processing_time_seconds": 12.5,
  "metadata": { ... },
  "extracted_data": { ... },
  "fraud_detection": { ... }
}
```

---

### Get Summary

Get key metrics for a bank statement or passbook — account info, flows, balances, category breakdowns. No transaction-level data.

```
GET /api/documents/{id}/summary
GET /api/documents/{id}/summary?format=csv
```

**cURL:**
```bash
# JSON
curl https://portal.usekita.com/api/documents/12345/summary \
  -H "Authorization: Bearer $API_KEY"

# CSV
curl https://portal.usekita.com/api/documents/12345/summary?format=csv \
  -H "Authorization: Bearer $API_KEY" -o summary.csv
```

**Python:**
```python
summary = client.get_summary(result.document_id)
print(summary['total_inflow'])
print(summary['average_daily_balance'])

# Or as CSV
csv_data = client.get_summary(result.document_id, format='csv')
```

---

### Download Export

Download an Excel (.xlsx) export of a processed document.

```
GET /api/documents/{id}/custom-export
GET /api/documents/{id}/credit-report-export
```

| Endpoint | Use case |
|----------|----------|
| `/custom-export` | Org-configured Excel format (works for all document types) |
| `/credit-report-export` | Multi-sheet credit report Excel (credit reports only) |

For schema-based document types (AFS, credit reports, SLIK, etc.), use the V1 schema export endpoint:

```
GET /api/v1/documents/{id}/export
```

This generates a multi-sheet Excel workbook with type-specific sheets. For AFS documents, this produces a 17-sheet workbook covering company info, balance sheet, income statement, cash flow, notes, shareholders, equity, tax, risk, and more.

**cURL:**
```bash
# Org-configured export
curl https://portal.usekita.com/api/documents/12345/custom-export \
  -H "Authorization: Bearer $API_KEY" -o report.xlsx

# Schema-based export (AFS, credit report, etc.)
curl https://portal.usekita.com/api/v1/documents/12345/export \
  -H "Authorization: Bearer $API_KEY" -o afs_report.xlsx
```

**Python:**
```python
client.custom_export(result.document_id, "report.xlsx")
client.custom_export(result.document_id, "credit.xlsx", export_type="credit_report")
client.custom_export(result.document_id, "afs_report.xlsx", export_type="schema")
```

---

### Edit Transactions

Update transactions for a bank statement document. The original transactions are preserved as an immutable backup on first edit.

```
PUT /api/documents/{id}/transactions
Content-Type: application/json
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `transactions` | array | Yes | Updated transactions array |
| `revalidate` | boolean | No | Re-run balance validation after edit (default: `true`) |

**cURL:**
```bash
curl -X PUT https://portal.usekita.com/api/documents/12345/transactions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transactions": [
      {
        "transaction_id": "txn_001",
        "date": "01-02-2024",
        "description": "SALARY CREDIT",
        "amount": -30000,
        "debit": 0,
        "credit": 30000,
        "balance": 80000,
        "category": "income"
      }
    ],
    "revalidate": true
  }'
```

**Python:**
```python
result = client.get_result(12345)
txns = result.transactions

# Fix a miscategorized transaction
txns[3]['category'] = 'income'

updated = client.edit_transactions(12345, txns)
print(f"Version: {updated['edit_history']['version']}")
```

**Response:**
```json
{
  "success": true,
  "transactions": [ ... ],
  "metrics": { ... },
  "balance_checks": { ... },
  "edit_history": {
    "last_edited_at": "2024-01-15T10:30:00Z",
    "edited_by_user_id": "...",
    "version": 1
  }
}
```

### Revert Transactions

Restore the original extracted transactions (before any edits).

```
POST /api/documents/{id}/transactions/revert
```

**cURL:**
```bash
curl -X POST https://portal.usekita.com/api/documents/12345/transactions/revert \
  -H "Authorization: Bearer $API_KEY"
```

**Python:**
```python
reverted = client.revert_transactions(12345)
print(reverted['message'])  # "Transactions reverted to original"
```

### Re-validate Transactions

Re-run balance validation on current transactions without making changes.

```
POST /api/documents/{id}/transactions/revalidate
```

**cURL:**
```bash
curl -X POST https://portal.usekita.com/api/documents/12345/transactions/revalidate \
  -H "Authorization: Bearer $API_KEY"
```

**Python:**
```python
result = client.revalidate_transactions(12345)
print(f"Balance checks: {result['balance_checks']}")
```

---

### List Documents

List all processed documents for your organization with pagination and filtering.

```
GET /api/documents?limit=100&offset=0
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `limit` | int | 100 | Max results |
| `offset` | int | 0 | Pagination offset |
| `status` | string | — | Filter: `pending`, `processing`, `completed`, `failed` |
| `document_type` | string | — | Filter by document type |

**cURL:**
```bash
curl "https://portal.usekita.com/api/documents?limit=50&status=completed&document_type=bank_statement" \
  -H "Authorization: Bearer $API_KEY"
```

**Python:**
```python
docs = client.list_documents(limit=50, status='completed', document_type='bank_statement')
for doc in docs['documents']:
    print(f"{doc['id']}: {doc.get('document_type')}")
```

---

### Process from URL

Process a document from a public URL without uploading a file. Uses the batch endpoint.

```
POST /api/v1/batch
Content-Type: application/json
```

**cURL:**
```bash
curl -X POST https://portal.usekita.com/api/v1/documents \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file_url": "https://my-bucket.s3.amazonaws.com/statement.pdf?X-Amz-Algorithm=...",
    "document_type": "bank_statement"
  }'
```

**Python:**
```python
result = client.process_url(
    "https://my-bucket.s3.amazonaws.com/statement.pdf?X-Amz-Algorithm=...",
    "bank_statement"
)
# Handles polling automatically, returns DocumentResult
```

**With webhook (fire-and-forget):**
```python
result = client.process_url(
    "https://my-bucket.s3.amazonaws.com/statement.pdf?X-Amz-Algorithm=...",
    "bank_statement",
    wait=False,
    webhook_url="https://your-server.com/kita-webhook"
)
# Your webhook receives a POST when processing completes
```

**Response:**
```json
{
  "success": true,
  "document_id": 42,
  "job_id": "a1b2c3d4-...",
  "status": "pending",
  "status_url": "/api/v1/documents/jobs/42"
}
```

---

### Batch Processing

Process up to 100 documents from URLs in a single request.

**Create a batch:**
```
POST /api/v1/batch
```

```bash
curl -X POST https://portal.usekita.com/api/v1/batch \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "documents": [
      { "file_url": "https://example.com/stmt1.pdf", "document_type": "bank_statement" },
      { "file_url": "https://example.com/stmt2.pdf", "document_type": "bank_statement" },
      { "file_url": "https://example.com/payslip.pdf", "document_type": "payslip" }
    ]
  }'
```

Each document requires `file_url` and `document_type`. Optional `filename` overrides auto-detection.

**Check status:**
```
GET /api/v1/batch/{batch_id}
```

```json
{
  "batch_id": "batch_abc123",
  "status": "processing",
  "total_documents": 3,
  "completed": 2,
  "failed": 0,
  "progress_percent": 66.67,
  "documents": [
    { "document_id": 100, "filename": "stmt1.pdf", "status": "completed" },
    { "document_id": 101, "filename": "stmt2.pdf", "status": "completed" },
    { "document_id": 102, "filename": "payslip.pdf", "status": "processing" }
  ]
}
```

**Get results:**
```
GET /api/v1/batch/{batch_id}/results
```

Returns full extracted data for every document in the batch.

**Python (batch from folder):**
```python
batch = client.batch_process("/path/to/statements", "bank_statement")
results = batch.results()  # {filepath: DocumentResult}

for filepath, result in results.items():
    print(f"{filepath}: {result.status}")
    result.save_json(f"{filepath}_output.json")
```

**Python (batch from URLs):**
```python
results = client.batch_process_urls([
    {"file_url": "https://example.com/stmt1.pdf", "document_type": "bank_statement"},
    {"file_url": "https://example.com/stmt2.pdf", "document_type": "bank_statement"},
])
for doc in results['documents']:
    if doc['status'] == 'completed':
        print(doc['result']['metadata'])
```

**Python (batch from base64):**
```python
results = client.batch_process_base64([
    {"file_base64": "JVBERi0xLjQ...", "filename": "stmt1.pdf", "document_type": "bank_statement"},
    {"file_base64": "JVBERi0xLjQ...", "filename": "stmt2.pdf", "document_type": "bank_statement"},
])
for doc in results['documents']:
    if doc['status'] == 'completed':
        print(doc['result']['metadata'])
```

### Merge Documents

Combine multiple images or PDFs into a single document for processing. Useful for multi-page documents scanned as separate images.

```python
# Merge from URLs
result = client.merge_documents(
    files=[
        {"file_url": "https://example.com/page1.png"},
        {"file_url": "https://example.com/page2.png"},
    ],
    document_type="bank_statement",
    output_filename="merged_statement.pdf",
)
print(result['document_id'], result['pages'])

# Merge from local files (auto-converted to base64)
result = client.merge_documents(
    files=[
        {"file_path": "/path/to/page1.jpg"},
        {"file_path": "/path/to/page2.jpg"},
    ],
    document_type="bank_statement",
)

# Mix URLs, base64, and local files
result = client.merge_documents(
    files=[
        {"file_url": "https://example.com/cover.pdf"},
        {"file_path": "/path/to/scan.png"},
        {"file_base64": "iVBORw0KGgo...", "filename": "page3.png"},
    ],
    document_type="bank_statement",
)
```

---

## Document Types

Type names are case-insensitive. `"bank_statement"`, `"BANK_STATEMENT"`, and `"Bank Statement"` all work.

### Financial Documents

| Type | What it extracts |
|------|-----------------|
| `bank_statement` | Transactions, balances, flow metrics, category breakdowns, fraud signals |
| `passbook` | Same as bank statement |
| `credit_card_statement` | Transactions, balances, payment info |
| `payslip` | Earnings, deductions, net pay, employer info, statutory IDs, fraud score |
| `bill` | Provider, amounts, due dates, verification signals |
| `credit_report` | Accounts, KYC data, bureau score, payment history, credit metrics |
| `sales_invoice` | Seller/buyer, line items, totals, VAT, invoice signals |
| `afs` | Financial statements, balance sheet, income statement, cash flow, notes/schedules, qualitative data (business info, shareholders, equity, tax, risk management, capital management), profitability/liquidity/leverage ratios, completeness scoring, risk flags |
| `loan_statement` | Loan details, payment schedule |

### Government & Legal Documents

| Type | What it extracts |
|------|-----------------|
| `government_id` | Name, ID number, dates, photo (passport, driver's license, etc.) |
| `income_tax_return` | Tax return fields, income, deductions |
| `bir_2303` | TIN, registered name, business address, tax types |
| `bir_2307` | Tax withheld, payee/payor info |
| `certificate_of_employment` | Employer, employee, position, dates, salary |
| `secretarys_certificate` | Corporate resolution details |
| `tin_id` | TIN, name, address |

### Business Documents

| Type | What it extracts |
|------|-----------------|
| `business_registration_dti` | Business name, registration details |
| `business_registration_sec` | SEC registration number, incorporators |
| `certificate_of_incorporation` | Company details, incorporators |
| `general_information_sheet` | Corporate governance, capital structure, stockholders, directors, officers, beneficial owners, compliance |
| `business_permit` | Permit details, business activities |
| `mayors_permit` | Permit number, validity, business type |
| `purchase_order` | PO details, line items |
| `bill_of_lading` | Shipping details, consignee, cargo |

### Other

| Type | What it extracts |
|------|-----------------|
| `proof_of_billing` | Address verification, billing details |
| `remittance_slip` | Remittance details, amounts |
| `land_title` | Title number, owner, lot details |
| `vehicle_registration` | Vehicle info, owner, registration |
| `insurance_policy` | Policy details, coverage, beneficiaries |
| `loan_agreement` | Loan terms, parties, schedules |
| `barangay_clearance` | Clearance details |
| `general_document` | Auto-classifies and extracts relevant fields |
| `other_document` | Generic extraction with AI-generated signals |

---

## Response Format

All document types share this structure:

```json
{
  "status": "completed",
  "document_type": "bank_statement",
  "document_id": 12345,
  "filename": "statement.pdf",
  "processing_time_seconds": 12.5,
  "uploaded_at": "2024-01-15T10:30:00Z",
  "metadata": { ... },
  "extracted_data": { ... },
  "fraud_detection": { ... }
}
```

| Field | Type | Description |
|-------|------|-------------|
| `status` | string | `"completed"`, `"failed"`, `"pending"`, or `"processing"` |
| `document_type` | string | The document type that was processed |
| `document_id` | number | Unique document identifier |
| `filename` | string | Original filename |
| `processing_time_seconds` | number | Time taken to process |
| `metadata` | object | Document-level info (account holder, dates, institution, etc.) |
| `extracted_data` | object | All type-specific extracted content (see examples below) |
| `fraud_detection` | object | Fraud/authenticity signals. Only present when data exists. |

---

## Response Examples

### Bank Statement

```json
{
  "status": "completed",
  "document_type": "bank_statement",
  "document_id": 123,
  "metadata": {
    "account_holder_name": "Juan Dela Cruz",
    "account_number": "1234567890",
    "financial_institution": "BDO",
    "statement_start_date": "01-01-2024",
    "statement_end_date": "01-31-2024",
    "currency": "PHP",
    "opening_balance": 50000.00,
    "closing_balance": 62000.00
  },
  "extracted_data": {
    "transactions": [
      {
        "date": "01-02-2024",
        "description": "SALARY CREDIT",
        "credit": 30000.00,
        "debit": 0,
        "balance": 80000.00,
        "category": "income",
        "tampered": false,
        "is_outlier": false,
        "outlier_reason": null,
        "transaction_type": "credit"
      }
    ],
    "metrics": {
      "total_inflow": 45000.00,
      "total_outflow": 33000.00,
      "net_cash_flow": 12000.00,
      "average_balance": 58000.00,
      "total_transactions": 25,
      "by_category": { "...": "..." },
      "by_month": { "...": "..." }
    }
  },
  "fraud_detection": {
    "risk_level": "low",
    "authenticity_score": 92,
    "signals": [
      { "severity": "info", "category": "document_integrity", "message": "Document appears authentic" }
    ]
  },
  "suspicious_accounts": {
    "outlier_transactions": [
      {
        "description": "WIRE TRANSFER",
        "amount": 500000.00,
        "type": "debit",
        "date": "01-15-2024",
        "category": "transfers",
        "avg_amount": 5882.35,
        "multiplier": 85.0,
        "flag": "outlier"
      }
    ],
    "frequent_descriptions": [],
    "circular_transfers": [],
    "outlier_count": 1,
    "frequent_count": 0,
    "circular_count": 0,
    "total_suspicious": 1
  }
}
```

### Payslip

```json
{
  "status": "completed",
  "document_type": "payslip",
  "document_id": 456,
  "metadata": {
    "employee_name": "Juan Dela Cruz",
    "employer_name": "Acme Corp",
    "pay_date": "01-15-2024"
  },
  "extracted_data": {
    "payslip_count": 1,
    "payslips": [
      {
        "earnings": [
          { "label": "Basic Pay", "amount": 25000, "taxable": true },
          { "label": "Rice Allowance", "amount": 2000, "taxable": false }
        ],
        "deductions": [
          { "label": "SSS", "amount": 900, "category": "sss" },
          { "label": "PhilHealth", "amount": 450, "category": "philhealth" },
          { "label": "Withholding Tax", "amount": 2500, "category": "tax" }
        ],
        "totals": {
          "gross_pay": 30000,
          "total_deductions": 4950,
          "net_pay": 25050
        },
        "pay_period": {
          "start_date": "01-01-2024",
          "end_date": "01-15-2024",
          "pay_date": "01-15-2024"
        }
      }
    ],
    "employment_info": {
      "employer_name": "Acme Corp",
      "employee_name": "Juan Dela Cruz",
      "employee_id": "EMP-001",
      "department": "Engineering",
      "statutory_ids": { "tin": "...", "sss": "...", "philhealth": "...", "pagibig": "..." }
    },
    "signals": [
      { "key": "mandatory_coverage", "label": "Mandatory Deductions Coverage", "score": 95, "status": "good" },
      { "key": "arithmetic_integrity", "label": "Payslip Arithmetic Integrity", "score": 98, "status": "good" },
      { "key": "fraud_confidence", "label": "Document Trust Score", "score": 80, "status": "good" }
    ],
    "fraud_score": {
      "overall_score": 95.93,
      "risk_level": "low",
      "categories": {
        "duplicates": { "score": 100 },
        "round_numbers": { "score": 72.86 },
        "data_consistency": { "score": 100 }
      }
    }
  }
}
```

### Bill

```json
{
  "status": "completed",
  "document_type": "bill",
  "document_id": 789,
  "metadata": {
    "account_holder_name": "Juan Dela Cruz",
    "service_address": "123 Main St, Makati"
  },
  "extracted_data": {
    "bill_fields": {
      "provider": "Meralco",
      "account_number": "1234567890",
      "billing_period_start": "12-01-2023",
      "billing_period_end": "12-31-2023",
      "due_date": "01-15-2024",
      "total_amount_due": 3500.00
    },
    "signals": [
      { "signal_id": "address_match", "label": "Address Verification", "value": true, "status": "pass" }
    ],
    "signal_summary": {
      "overall_score": 85,
      "total_signals": 6,
      "passed": 5,
      "warnings": 1,
      "failed": 0,
      "risk_level": "low"
    }
  }
}
```

### Credit Report

```json
{
  "status": "completed",
  "document_type": "credit_report",
  "document_id": 321,
  "metadata": {
    "subject_name": "Dela Cruz, Juan",
    "bureau_score": 650,
    "source_bureau": "CIBI"
  },
  "extracted_data": {
    "credit_report_data": {
      "report_metadata": {
        "source_bureau": "CIBI",
        "bureau_score_value": 650,
        "bureau_score_band": "Fair"
      },
      "subject_person": {
        "last_name": "Dela Cruz",
        "first_name": "Juan",
        "date_of_birth": "1990-05-15"
      },
      "accounts": [
        {
          "product_type": "Installment",
          "product_category": "Housing Loan",
          "provider_name": "BDO",
          "outstanding_balance": 1800000,
          "monthly_payment": 15000
        }
      ]
    },
    "metrics": {
      "credit_report_metrics": {
        "loan_activity_24m": { "...": "..." },
        "repayment_performance_60m": { "...": "..." },
        "dpd_analysis_60m": { "...": "..." }
      }
    }
  }
}
```

### Sales Invoice

```json
{
  "status": "completed",
  "document_type": "sales_invoice",
  "document_id": 987,
  "extracted_data": {
    "invoices": [
      {
        "seller": { "name": "ABC Trading Corp", "tin": "123-456-789-000" },
        "buyer": { "name": "XYZ Industries", "tin": "987-654-321-000" },
        "invoice_number": "INV-2024-001",
        "invoice_date": "2024-01-15",
        "line_items": [
          { "description": "Product A", "quantity": 100, "unit_price": 500, "amount": 50000 }
        ],
        "subtotal": 50000,
        "vat": 6000,
        "total": 56000
      }
    ]
  },
  "invoice_signals": {
    "signals": ["..."],
    "per_invoice": ["..."]
  }
}
```

### Audited Financial Statement (AFS)

```json
{
  "status": "completed",
  "document_type": "afs",
  "document_id": 555,
  "metadata": {
    "company_name": "ABC Industries Inc.",
    "fiscal_year_end": "2023-12-31"
  },
  "extracted_data": {
    "company": {
      "name": "ABC Industries Inc.",
      "tin": "123-456-789-000",
      "sec_registration": "SEC-2020-001",
      "address": "123 Business Ave, Makati City",
      "industry": "Manufacturing"
    },
    "audit_info": {
      "auditor_name": "Santos & Associates CPAs",
      "audit_opinion": "Unqualified",
      "audit_date": "2024-03-15",
      "fiscal_year_end": "2023-12-31"
    },
    "officers": {
      "directors": ["Juan Dela Cruz", "Maria Santos"],
      "president": "Juan Dela Cruz",
      "treasurer": "Maria Santos"
    },
    "balance_sheet": {
      "years": {
        "2023": {
          "year_label": "2023",
          "total_assets": 50000000,
          "total_liabilities": 30000000,
          "total_equity": 20000000,
          "current_assets": 15000000,
          "current_liabilities": 10000000
        },
        "2022": { "...": "..." }
      }
    },
    "income_statement": {
      "years": {
        "2023": {
          "year_label": "2023",
          "revenue": 80000000,
          "cost_of_sales": 55000000,
          "gross_profit": 25000000,
          "operating_expenses": 15000000,
          "net_income": 8000000
        },
        "2022": { "...": "..." }
      }
    },
    "cash_flow": {
      "operating": 12000000,
      "investing": -5000000,
      "financing": -3000000,
      "net_change": 4000000
    },
    "notes": {
      "trade_receivables": { "current": 5000000, "past_due": 500000 },
      "property_and_equipment": { "land": 10000000, "buildings": 8000000 },
      "related_party_transactions": [
        { "party": "XYZ Holdings", "nature": "Advances", "amount": 2000000 }
      ]
    },
    "qualitative": {
      "business_description": {
        "nature_of_business": "Manufacturing of industrial components",
        "year_established": "2005",
        "principal_office": "123 Business Ave, Makati City"
      },
      "shareholders": [
        { "name": "Juan Dela Cruz", "shares": 500000, "percentage": 50.0 },
        { "name": "Maria Santos", "shares": 300000, "percentage": 30.0 }
      ],
      "equity_structure": {
        "authorized_capital": 10000000,
        "subscribed_capital": 8000000,
        "paid_up_capital": 8000000,
        "par_value_per_share": 10
      },
      "income_tax_details": {
        "tax_rate": 25,
        "income_tax_expense": 2500000,
        "deferred_tax_asset": 100000
      },
      "risk_management": {
        "credit_risk": "The company maintains diversified receivables...",
        "liquidity_risk": "The company maintains sufficient cash reserves...",
        "market_risk": "Exposure to foreign currency fluctuations is minimal..."
      },
      "capital_management": {
        "policy": "The company manages capital to maintain a debt-to-equity ratio below 2.0",
        "compliance": true
      },
      "subsequent_events": [
        { "date": "2024-02-15", "description": "Board approved dividend distribution of PHP 2M" }
      ],
      "supplementary_information": {
        "revenue_regulations": "RR No. 15-2010",
        "tax_type": "VAT Registered"
      },
      "accounting_policies": {
        "revenue_recognition": "Revenue is recognized at the point of transfer of control...",
        "inventory_method": "First-in, first-out (FIFO)"
      }
    },
    "signals": {
      "profitability": { "gross_margin": 31.25, "net_margin": 10.0, "roe": 40.0 },
      "liquidity": { "current_ratio": 1.5, "quick_ratio": 1.2 },
      "leverage": { "debt_to_equity": 1.5, "debt_ratio": 60.0 }
    },
    "risk_flags": [
      { "flag": "high_related_party", "severity": "warning", "message": "Related party transactions exceed 10% of revenue" }
    ],
    "data_validation": { "...": "..." }
  },
  "metrics": {
    "profitability": { "gross_margin": 31.25, "net_margin": 10.0, "roe": 40.0, "roa": 16.0 },
    "liquidity": { "current_ratio": 1.5, "quick_ratio": 1.2 },
    "leverage": { "debt_to_equity": 1.5, "debt_ratio": 60.0 },
    "efficiency": { "asset_turnover": 1.6, "receivables_turnover": 16.0 }
  },
  "completeness": {
    "overall_score": 87,
    "sections": {
      "company_info": { "score": 100, "weight": 10 },
      "balance_sheet": { "score": 95, "weight": 25 },
      "income_statement": { "score": 90, "weight": 20 },
      "cash_flow": { "score": 80, "weight": 10 },
      "notes": { "score": 75, "weight": 10 },
      "prior_year_data": { "score": 85, "weight": 10 },
      "qualitative": { "score": 90, "weight": 10 },
      "audit_info": { "score": 100, "weight": 5 }
    }
  },
  "statements_found": ["balance_sheet", "income_statement", "cash_flow"],
  "fraud_detection": {
    "risk_level": "low",
    "signals": []
  }
}
```

### General Information Sheet (GIS)

```json
{
  "status": "completed",
  "document_type": "general_information_sheet",
  "document_id": 777,
  "metadata": {
    "company_name": "ABC Industries Inc.",
    "sec_registration": "CS201912345",
    "fiscal_year": "2023",
    "document_type": "general_information_sheet"
  },
  "extracted_data": {
    "company": {
      "company_name": "ABC Industries Inc.",
      "sec_registration_number": "CS201912345",
      "date_registered": "January 15, 2010",
      "tin": "123-456-789-000",
      "fiscal_year_end": "December 31",
      "industry_classification": "Manufacturing",
      "primary_purpose": "To engage in the manufacture and sale of industrial components",
      "principal_office_address": "123 Business Ave, Makati City",
      "website": "www.abcindustries.com.ph",
      "telephone": "(02) 8123-4567"
    },
    "filing_info": {
      "fiscal_year": "2023",
      "date_of_annual_meeting": "June 15, 2024",
      "date_of_submission": "July 1, 2024",
      "is_amended": false,
      "type_of_annual_meeting": "Regular"
    },
    "capital_structure": {
      "authorized_capital_stock": 10000000,
      "authorized_shares": 1000000,
      "par_value_per_share": 10,
      "subscribed_capital": 5000000,
      "subscribed_shares": 500000,
      "paid_up_capital": 5000000,
      "paid_up_shares": 500000,
      "share_classes": [
        {
          "class_name": "Common",
          "authorized_shares": 1000000,
          "par_value": 10,
          "subscribed_shares": 500000,
          "paid_up_shares": 500000
        }
      ]
    },
    "stockholders": [
      {
        "name": "Juan Dela Cruz",
        "nationality": "Filipino",
        "number_of_shares": 250000,
        "ownership_percentage": 50.0,
        "amount_paid": 2500000,
        "tin": "123-456-789-000",
        "share_type": "Common"
      },
      {
        "name": "Maria Santos",
        "nationality": "Filipino",
        "number_of_shares": 150000,
        "ownership_percentage": 30.0,
        "amount_paid": 1500000,
        "tin": "987-654-321-000",
        "share_type": "Common"
      }
    ],
    "directors": [
      {
        "name": "Juan Dela Cruz",
        "nationality": "Filipino",
        "board": "Executive Director",
        "gender": "Male",
        "incorporator": true,
        "stockholder": true,
        "officer": true,
        "tin": "123-456-789-000",
        "meetings_attended": 10,
        "total_meetings": 12
      },
      {
        "name": "Pedro Reyes",
        "nationality": "Filipino",
        "board": "Independent Director",
        "gender": "Male",
        "incorporator": false,
        "stockholder": false,
        "officer": false,
        "meetings_attended": 11,
        "total_meetings": 12
      }
    ],
    "officers": [
      { "name": "Juan Dela Cruz", "position": "President & CEO", "tin": "123-456-789-000" },
      { "name": "Maria Santos", "position": "Treasurer & CFO", "tin": "987-654-321-000" },
      { "name": "Ana Reyes", "position": "Corporate Secretary", "tin": "111-222-333-000" }
    ],
    "beneficial_owners": [
      {
        "name": "Juan Dela Cruz",
        "nationality": "Filipino",
        "percentage_of_capital": 50.0,
        "category": "Direct ownership"
      }
    ],
    "intercompany_relationships": [
      {
        "company_name": "XYZ Holdings Corp",
        "relationship": "Parent",
        "sec_registration": "CS200812345",
        "ownership_percentage": 70
      }
    ],
    "external_auditor": {
      "auditing_firm": "Santos & Associates CPAs",
      "accreditation_number": "SEC-A-2020-001",
      "contact_person": "Carlos Santos",
      "date_engaged": "March 2020"
    },
    "compliance_info": {
      "compliance_officer": "Ana Reyes",
      "annual_report_submitted": true,
      "financial_statements_submitted": true,
      "gis_submitted": true,
      "pending_cases": null,
      "sanctions_penalties": null
    },
    "amendments": [],
    "signals": { "...": "..." },
    "risk_flags": [
      { "code": "concentration_risk", "severity": "high", "message": "Single stockholder 'Juan Dela Cruz' owns 50.0%" }
    ],
    "data_validation": { "...": "..." }
  },
  "metrics": {
    "summary": {
      "company_name": "ABC Industries Inc.",
      "sec_registration": "CS201912345",
      "authorized_capital": 10000000,
      "subscribed_capital": 5000000,
      "paid_up_capital": 5000000,
      "stockholder_count": 2,
      "director_count": 5,
      "independent_director_count": 2,
      "officer_count": 3,
      "beneficial_owner_count": 1,
      "intercompany_count": 1,
      "foreign_ownership_pct": 0.0
    },
    "risk_signals": [
      {
        "code": "concentration_risk",
        "severity": "high",
        "message": "Single stockholder 'Juan Dela Cruz' owns 50.0% — high ownership concentration.",
        "details": { "stockholder": "Juan Dela Cruz", "percentage": 50.0 }
      }
    ]
  },
  "completeness": {
    "overall_score": 92,
    "sections": {
      "company": { "score": 15.0, "weight": 15, "fields_present": 6, "fields_total": 6 },
      "filing": { "score": 10.0, "weight": 10, "fields_present": 3, "fields_total": 3 },
      "capital_structure": { "score": 20.0, "weight": 20, "fields_present": 5, "fields_total": 5 },
      "stockholders": { "score": 18.0, "weight": 20, "fields_present": 2, "fields_total": 1 },
      "directors": { "score": 14.0, "weight": 15, "fields_present": 5, "fields_total": 5 },
      "officers": { "score": 10.0, "weight": 10, "fields_present": 3, "fields_total": 3 },
      "beneficial_owners": { "score": 2.5, "weight": 5, "fields_present": 1, "fields_total": 2 },
      "compliance": { "score": 5.0, "weight": 5, "fields_present": 2, "fields_total": 2 }
    }
  },
  "fraud_detection": {
    "risk_level": "low",
    "signals": []
  }
}
```

### Schema-based Documents (BIR, COE, Government ID, etc.)

All schema-based types return extracted fields directly in `extracted_data`:

```json
{
  "status": "completed",
  "document_type": "bir_2303",
  "document_id": 111,
  "metadata": {},
  "extracted_data": {
    "tin": "123-456-789-000",
    "registered_name": "ABC Corp",
    "registration_date": "2020-01-15",
    "business_address": "...",
    "lines_of_business": ["Retail Trade"],
    "tax_types": ["Income Tax", "VAT"]
  }
}
```

---

## Error Handling

### HTTP Status Codes

| Status | Meaning | What to do |
|--------|---------|------------|
| `200` | Success | Parse the JSON response |
| `202` | Accepted | Document queued — poll for results |
| `400` | Bad Request | Check your request body/parameters |
| `401` | Unauthorized | Invalid or missing API key |
| `403` | Forbidden | Upgrade required, or document type not enabled for your org |
| `404` | Not Found | Document/batch ID doesn't exist |
| `429` | Rate Limited | Wait and retry. Check `Retry-After` header. |
| `500` | Server Error | Retry after a brief delay |

### Error Response Format

```json
{
  "error": "Bad Request",
  "message": "documents array is required and must not be empty"
}
```

### Python Error Handling

```python
from kita import (
    KitaClient,
    KitaError,               # Base SDK error
    KitaAPIError,             # API returned an error (has .status_code, .message)
    KitaAuthenticationError,  # 401 — invalid API key
    KitaRateLimitError        # 429 — rate limited (has .retry_after)
)

try:
    result = client.process("doc.pdf", "bank_statement")
except KitaAuthenticationError:
    print("Invalid API key")
except KitaRateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s")
except KitaAPIError as e:
    print(f"API error {e.status_code}: {e.message}")
except KitaError as e:
    print(f"SDK error: {e}")
```

---

## Python SDK Reference

### Installation

```bash
pip install kita
```

### Configuration

```python
from kita import KitaClient

# Pass API key directly
client = KitaClient(api_key="kita_prod_...")

# Or use environment variables
# export KITA_API_KEY=kita_prod_...
# export KITA_API_URL=https://portal.usekita.com  (optional, this is the default)
client = KitaClient()
```

### DocumentResult Object

All processing methods return a `DocumentResult` with property accessors:

```python
# Common (all document types)
result.status              # "completed", "failed", "pending"
result.document_id         # int
result.document_type       # "bank_statement", "payslip", etc.
result.metadata            # dict — account holder, dates, institution
result.extracted_data      # dict — all type-specific content
result.fraud_detection     # dict — fraud signals (when present)
result.suspicious_accounts # dict — outlier transactions, frequent descriptions, circular transfers

# Bank statement / passbook / credit card statement
result.transactions        # list — categorized transactions (each has is_outlier, outlier_reason)
result.metrics             # dict — inflow, outflow, averages, breakdowns

# Payslip
result.payslips            # list — earnings, deductions, totals per payslip
result.employment_info     # dict — employer, employee, statutory IDs
result.signals             # list — lender verification signals
result.fraud_score         # dict — fraud scoring with category breakdown
result.payslip_count       # int — number of payslips in document

# Bill
result.bill_fields         # dict — provider, amounts, dates
result.signals             # list — verification signals
result.signal_summary      # dict — overall score, pass/warn/fail counts

# Credit report
result.credit_report_data  # dict — accounts, KYC, bureau data
result.metrics             # dict — credit metrics

# Sales invoice
result.extracted_data      # dict — invoices array with line items
result.invoice_signals     # dict — invoice verification

# AFS (Audited Financial Statement)
result.financial_statements  # dict — balance_sheet, income_statement, cash_flow
result.company_info          # dict — company name, TIN, SEC registration, address
result.audit_info            # dict — auditor, opinion, date, fiscal year
result.officers              # dict — directors, president, treasurer
result.qualitative_data      # dict — all qualitative/text-based extractions
result.shareholders          # list — shareholder name, shares, percentage
result.equity_structure      # dict — authorized/subscribed/paid-up capital
result.risk_management       # dict — credit, liquidity, market risk narratives
result.financial_ratios      # dict — profitability, liquidity, leverage, efficiency
result.risk_flags            # list — risk flag alerts with severity
result.completeness          # dict — per-section completeness scores (0-100)
result.notes                 # dict — notes/schedules (receivables, PP&E, related parties)
result.statements_found      # list — which financial statements were detected

# GIS (General Information Sheet)
result.gis_company               # dict — company name, SEC reg, TIN, address, industry
result.filing_info               # dict — fiscal year, meeting date, submission date
result.capital_structure         # dict — authorized/subscribed/paid-up capital, share classes
result.stockholders              # list — name, nationality, shares, ownership %, amount paid
result.directors                 # list — name, nationality, board type, independent flag, attendance
result.gis_officers              # list — name, position, nationality, TIN
result.beneficial_owners         # list — name, nationality, % of capital, category
result.intercompany_relationships # list — related companies (parent/subsidiary/affiliate)
result.external_auditor          # dict — auditing firm, accreditation, contact
result.compliance_info           # dict — compliance officer, report submissions, pending cases
result.gis_risk_signals          # list — risk signals (concentration, capitalization, governance)
result.gis_summary               # dict — stockholder/director counts, foreign ownership %, capital
result.completeness              # dict — per-section completeness scores (0-100)

# Serialization
result.to_dict()           # convert to dict
result.to_json()           # formatted JSON string
result.save_json("out.json")
result['key']              # dict-like access
result.get('key', default)
```

### All Methods

| Method | Description |
|--------|-------------|
| `client.process(file_path, document_type, webhook_url=None)` | Upload and process a file. Returns `DocumentResult`. |
| `client.process_base64(file_base64, filename, document_type, webhook_url=None)` | Process a base64-encoded file. Returns `DocumentResult`. |
| `client.process_url(file_url, document_type, webhook_url=None)` | Process from a URL (S3 presigned, public). Returns `DocumentResult`. |
| `client.get_result(document_id)` | Get result by ID. Returns `DocumentResult`. |
| `client.get_summary(document_id, format='json')` | Get bank statement summary. Returns dict or CSV string. |
| `client.custom_export(document_id, output_path)` | Download Excel export. Supports `export_type`: `"credit_report"` or `"schema"` (AFS, GIS, credit report, SLIK multi-sheet). |
| `client.edit_transactions(document_id, transactions, revalidate)` | Update transactions and re-validate. |
| `client.revert_transactions(document_id)` | Revert transactions to original extraction. |
| `client.revalidate_transactions(document_id)` | Re-run validation on current transactions. |
| `client.list_documents(limit, offset, status, document_type)` | List documents with filtering. |
| `client.batch_process(folder_path, document_type)` | Batch process files from a folder. Returns `Batch`. |
| `client.batch_process_urls(documents)` | Batch process from URLs. Returns dict with results. |
| `client.batch_process_base64(documents)` | Batch process from base64-encoded files. Returns dict with results. |
| `client.merge_documents(files, document_type, output_filename)` | Merge images/PDFs into one document. Returns dict with document_id. |

---

## Other Languages

Not using Python? Call the API directly with any HTTP client.

| Language | Example |
|----------|---------|
| **cURL** | [examples/curl/examples.sh](../examples/curl/examples.sh) |
| **JavaScript** | [examples/javascript/kita_example.js](../examples/javascript/kita_example.js) — Node.js 18+ |
| **PHP** | [examples/php/kita_example.php](../examples/php/kita_example.php) — PHP 7.4+ |
| **Java** | [examples/java/KitaExample.java](../examples/java/KitaExample.java) — Java 11+ |
| **C#** | [examples/csharp/KitaExample.cs](../examples/csharp/KitaExample.cs) — .NET 6+ |

### Postman Collection

Import [kita_api.postman_collection.json](../postman/kita_api.postman_collection.json) into Postman to test all endpoints interactively. Set the `api_key` collection variable to your API key.

---

## Rate Limits & Constraints

| Constraint | Value |
|------------|-------|
| Max file size | Determined by your plan |
| Max batch size | 100 documents per request |
| Batch processing | Requires paid plan |
| Rate limiting | Per-organization. `429` responses include `Retry-After` header. |

## Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `KITA_API_KEY` | API key | (required) |
| `KITA_API_URL` | API base URL override | `https://portal.usekita.com` |
