Parsek API Documentation

Integrate Parsek e-Invoice operations into your own systems. A REST-based, JSON-returning public API secured with API keys.

Base URLhttps://api.parsekpro.com

Getting Started

To start using the API you first need to create an API key. In the Parsek app, go to Settings → API Keys (admin/super_admin only) to generate a new key. The key starts with the pk_ prefix and is shown in full only once, at creation.

Authentication

All /v1/* requests authenticate on every call using the X-API-Key header. Key management endpoints use the app session’s Authorization: Bearer <token> header. Each key only accesses its granted scopes; insufficient permission returns 403 insufficient_scope. Keys are stored hashed on the server and shown only once, at creation.

Rate Limit

Each API key has a per-minute request limit (default 60 req/min, configurable via rate_limit at creation). Every response includes X-RateLimit-Limit and X-RateLimit-Remaining headers; when exceeded you receive 429 + Retry-After. For browser-based calls you can define allowed_domains (origin whitelist) on the key.

Error Codes

CodeDescription
200Success
400Bad request — missing/invalid parameters
401Unauthorized — invalid or missing API key
403Forbidden — origin not allowed / insufficient role
404Resource not found
429Rate limit exceeded
500Server error

Endpoint Reference Active

Invoices

POST /api/external/v1/invoices X-API-Key scope: einvoice

Create invoice (optionally send)

Creates a new e-Archive/e-Invoice draft. If `send_immediately: true` is passed, the invoice is sent immediately.

Request Body

FieldTypeRequiredDescription
send_immediatelybooleanNoif true, invoice is sent immediately
customerobjectYesCustomer info (name required; vkn or tckn)
linesarrayYesInvoice line items (at least 1)
invoice_typestringNoInvoice type (default 'SATIS')
currencystringNoCurrency (default 'TRY')
issue_datestring (date)NoIssue date YYYY-MM-DD (default today)
notesarrayNoInvoice notes
Request Example
curl -X POST "https://api.parsekpro.com/api/external/v1/invoices" \
  -H "X-API-Key: pk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"send_immediately":false,"customer":{"name":"Örnek Müşteri A.Ş.","vkn":"1234567890","email":"[email protected]","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"}'
Response Example
{
  "success": true,
  "invoice": {
    "id": "9f1c2b7e-...",
    "status": "draft",
    "payable_amount": 1200
  }
}
GET /api/external/v1/invoices X-API-Key scope: einvoice

List invoices

Lists the company invoices with pagination. Filterable by `direction` and `status`.

Parameters

FieldTypeinRequiredDescription
directionstringqueryNo'outbound' / 'inbound'
statusstringqueryNoStatus (draft, sent, error…)
pageintegerqueryNoPage (0-based, default 0)
limitintegerqueryNoPage size (default 20)
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/invoices" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}
GET /api/external/v1/invoices/{id} X-API-Key scope: einvoice

Invoice detail

Returns all fields of a single invoice.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesInvoice ID
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/invoices/{id}" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
{
  "id": "9f1c2b7e-...",
  "invoice_number": "PSK2026000000123",
  "status": "sent",
  "payable_amount": 1200,
  "lines": [
    {
      "name": "Danışmanlık Hizmeti",
      "quantity": 1,
      "unitPrice": 1000,
      "taxPercent": 20
    }
  ]
}
GET /api/external/v1/invoices/{id}/status X-API-Key scope: einvoice

Query invoice status

Returns the current status code and message of the invoice.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesInvoice ID
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/invoices/{id}/status" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
{
  "id": "9f1c2b7e-...",
  "invoice_uuid": "A1B2C3-...",
  "status": "sent",
  "status_code": 100,
  "status_message": null
}
GET /api/external/v1/invoices/{id}/pdf X-API-Key scope: einvoice

Download invoice PDF

Returns the invoice PDF output (application/pdf).

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesInvoice ID
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/invoices/{id}/pdf" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
application/pdf (binary)
POST /api/external/v1/invoices/{id}/cancel X-API-Key scope: einvoice

Cancel e-Archive invoice

Only invoices in the e-Archive (EARSIVFATURA) scenario can be cancelled.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesInvoice ID

Request Body

FieldTypeRequiredDescription
cancel_datestring (date)NoCancel date (default today)
Request Example
curl -X POST "https://api.parsekpro.com/api/external/v1/invoices/{id}/cancel" \
  -H "X-API-Key: pk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"cancel_date":"2026-02-11"}'
Response Example
{
  "success": true,
  "result": {}
}

Utilities

POST /api/external/v1/check-einvoice-user X-API-Key scope: einvoice

Check e-Invoice registered user

Checks whether the given VKN/TCKN is a registered e-Invoice (GİB) user.

Request Body

FieldTypeRequiredDescription
vknstringNoTax ID (VKN)
tcknstringNoNational ID (TCKN)
Request Example
curl -X POST "https://api.parsekpro.com/api/external/v1/check-einvoice-user" \
  -H "X-API-Key: pk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"vkn":"1234567890"}'
Response Example
{
  "is_einvoice_user": true
}

Current Accounts

GET /api/external/v1/current-accounts X-API-Key scope: current_accounts:read

List current accounts

Lists company current accounts with pagination. Filters: `account_type` (CUSTOMER/VENDOR/SUBCONTRACTOR/EMPLOYEE), `status` (ACTIVE/PASSIVE), `q` (name/code search), `updated_since` (delta sync).

Parameters

FieldTypeinRequiredDescription
account_typestringqueryNoCUSTOMER/VENDOR/SUBCONTRACTOR/EMPLOYEE
statusstringqueryNoACTIVE / PASSIVE
qstringqueryNoName/code search
updated_sincestring (ISO8601)queryNoUpdated after this timestamp
pageintegerqueryNoPage (0-based)
limitintegerqueryNoPage size (max 100)
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/current-accounts" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}
GET /api/external/v1/current-accounts/{id} X-API-Key scope: current_accounts:read

Current account detail

Returns all fields of a single current account.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesAccount ID
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/current-accounts/{id}" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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"
}
POST /api/external/v1/current-accounts X-API-Key scope: current_accounts:write

Create current account

Creates a new current account. If `account_code` is omitted it is auto-generated by type. Supports the `Idempotency-Key` header.

Request Body

FieldTypeRequiredDescription
account_namestringYesAccount name
account_typestringYesCUSTOMER/VENDOR/SUBCONTRACTOR/EMPLOYEE
account_codestringNoAuto-generated if empty
tax_numberstringNoTax/National ID
tax_officestringNoTax office
emailstringNoEmail
phonestringNoPhone
ibanstringNoIBAN
base_currencystringNoCurrency (default TRY)
Request Example
curl -X POST "https://api.parsekpro.com/api/external/v1/current-accounts" \
  -H "X-API-Key: pk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"account_name":"Örnek Müşteri A.Ş.","account_type":"CUSTOMER","tax_number":"1234567890","email":"[email protected]","base_currency":"TRY"}'
Response Example
{
  "id": "uuid",
  "account_code": "MUS-00007",
  "account_name": "Örnek Müşteri A.Ş.",
  "account_type": "CUSTOMER",
  "status": "ACTIVE",
  "base_currency": "TRY"
}
PUT /api/external/v1/current-accounts/{id} X-API-Key scope: current_accounts:write

Update current account

Updates the given fields (whitelisted fields only).

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesAccount ID

Request Body

FieldTypeRequiredDescription
account_namestringNoAccount name
phonestringNoPhone
statusstringNoACTIVE/PASSIVE
Request Example
curl -X PUT "https://api.parsekpro.com/api/external/v1/current-accounts/{id}" \
  -H "X-API-Key: pk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"phone":"05551112233","status":"PASSIVE"}'
Response Example
{
  "id": "uuid",
  "account_code": "MUS-00001",
  "phone": "05551112233",
  "status": "PASSIVE"
}
GET /api/external/v1/current-accounts/{id}/balance X-API-Key scope: current_accounts:read

Current account balance

Returns debit/credit/net balance and multi-currency balances.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesAccount ID
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/current-accounts/{id}/balance" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
{
  "account_id": "uuid",
  "debit_balance": 30000,
  "credit_balance": 17500,
  "balance": 12500,
  "balance_base": 12500,
  "base_currency": "TRY",
  "balances": {
    "TRY": 12500
  }
}
GET /api/external/v1/current-accounts/{id}/transactions X-API-Key scope: current_accounts:read

Current account transactions

Returns account transactions with pagination. `from`/`to` date filter.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesAccount ID
fromstring (date)queryNoStart date
tostring (date)queryNoEnd date
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/current-accounts/{id}/transactions" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}

Inventory

GET /api/external/v1/products X-API-Key scope: inventory:read

Product/material catalog

Lists the material catalog. Filters: `q` (name search), `material_type`, `updated_since`.

Parameters

FieldTypeinRequiredDescription
qstringqueryNoName search
material_typestringqueryNoCONSUMABLE / USABLE
updated_sincestring (ISO8601)queryNoDelta sync
pageintegerqueryNoPage
limitintegerqueryNoSize (max 100)
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/products" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}
GET /api/external/v1/products/{id} X-API-Key scope: inventory:read

Product detail

Returns all fields of a single material.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesMaterial ID
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/products/{id}" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
{
  "id": "uuid",
  "name": "Çimento CEM I 42.5",
  "material_type": "CONSUMABLE",
  "current_avg_cost": 250,
  "total_stock_value": 32000
}
GET /api/external/v1/inventory/levels X-API-Key scope: inventory:read

Stock levels

Current stock levels per warehouse/branch. Filters: `material_id`, `branch_id`, `warehouse_location_id`.

Parameters

FieldTypeinRequiredDescription
material_idstring (uuid)queryNoMaterial filter
branch_idstring (uuid)queryNoBranch filter
warehouse_location_idstring (uuid)queryNoWarehouse filter
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/inventory/levels" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}
GET /api/external/v1/inventory/movements X-API-Key scope: inventory:read

Stock movements

Lists stock movements. Filters: `material_id`, `branch_id`, `transaction_type`, `from`/`to`.

Parameters

FieldTypeinRequiredDescription
material_idstring (uuid)queryNoMaterial
transaction_typestringqueryNoIN/OUT/ADJUSTMENT…
fromstring (date)queryNoStart
tostring (date)queryNoEnd
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/inventory/movements" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}
GET /api/external/v1/warehouses X-API-Key scope: inventory:read

Warehouse/location list

Lists warehouses and locations. Filters: `branch_id`, `is_active`.

Parameters

FieldTypeinRequiredDescription
branch_idstring (uuid)queryNoBranch
is_activebooleanqueryNoActive filter
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/warehouses" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
{
  "data": [
    {
      "id": "uuid",
      "code": "DEPO-01",
      "name": "Merkez Depo",
      "location_path": "Merkez Depo",
      "is_active": true
    }
  ],
  "total": 6,
  "page": 0,
  "limit": 20
}
POST /api/external/v1/inventory/movements X-API-Key scope: inventory:write

Create stock movement

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`.

Request Body

FieldTypeRequiredDescription
material_idstring (uuid)YesMaterial ID
transaction_typestringYesIN/OUT/ADJUSTMENT/COUNT_ADJUSTMENT
quantitynumberYesQuantity (positive)
branch_idstring (uuid)NoBranch (required in location mode)
warehouse_location_idstring (uuid)NoWarehouse location
unit_pricenumberNoUnit price (valuation for IN)
notesstringNoNote
Request Example
curl -X POST "https://api.parsekpro.com/api/external/v1/inventory/movements" \
  -H "X-API-Key: pk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"material_id":"uuid","transaction_type":"IN","quantity":100,"unit_price":250,"notes":"Satın alma girişi"}'
Response Example
{
  "id": "uuid",
  "material_id": "uuid",
  "transaction_type": "IN",
  "quantity": 100,
  "unit_price": 250,
  "currency_code": "TRY",
  "created_at": "2026-02-10T10:00:00Z"
}

Attendance / PDKS

GET /api/external/v1/employees X-API-Key scope: attendance:read

Employee directory (mapping)

Returns the employee directory for PDKS card/number mapping. Filters: `q`, `status`, `branch_id`, `updated_since`.

Parameters

FieldTypeinRequiredDescription
qstringqueryNoName / number / card search
statusstringqueryNoactive / passive
updated_sincestring (date)queryNoISO8601 delta sync
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/employees" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}
GET /api/external/v1/attendance X-API-Key scope: attendance:read

Daily attendance records

Lists daily attendance records. Filters: `employee_id`, `branch_id`, `status_code`, `date`, `from`/`to`.

Parameters

FieldTypeinRequiredDescription
employee_idstring (uuid)queryNoEmployee
status_codestringqueryNoX/I/R/YG/DD/UI
fromstring (date)queryNoStart (YYYY-MM-DD)
tostring (date)queryNoEnd (YYYY-MM-DD)
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/attendance" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}
GET /api/external/v1/attendance/punches X-API-Key scope: attendance:read

Raw PDKS punch events

Returns raw device punch events (debug/audit). Filters: `employee_id`, `device_id`, `matched`, `from`/`to`.

Parameters

FieldTypeinRequiredDescription
employee_idstring (uuid)queryNoEmployee
device_idstringqueryNoDevice ID
matchedbooleanqueryNoMatch status
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/attendance/punches" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}
POST /api/external/v1/attendance X-API-Key scope: attendance:write

PDKS attendance push (punch or daily)

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.

Request Body

FieldTypeRequiredDescription
punchesarrayNoPunch mode: [{ card_no|employee_id|employee_number|tc_identity_no, timestamp (ISO8601), direction? (IN/OUT), device_id? }]
recordsarrayNoDaily mode: [{ card_no|employee_id|..., date (YYYY-MM-DD), status_code, work_hours?, overtime_hours?, note? }]
standard_daily_hoursnumberNoOvertime baseline (default 8)
Request Example
curl -X POST "https://api.parsekpro.com/api/external/v1/attendance" \
  -H "X-API-Key: pk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"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"}]}'
Response Example
{
  "mode": "punch",
  "punches_received": 2,
  "punches_inserted": 2,
  "punches_skipped_duplicate": 0,
  "attendance_upserted": 1,
  "unmatched": []
}

Webhooks

GET /api/external/v1/webhooks X-API-Key scope: webhooks:manage

List webhook endpoints

Returns the company webhook endpoints and the subscribable event catalog (`available_events`).

Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/webhooks" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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"
  ]
}
GET /api/external/v1/webhooks/{id} X-API-Key scope: webhooks:manage

Webhook detail

Returns a single webhook endpoint detail (secret masked).

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesWebhook ID
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/webhooks/{id}" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
{
  "id": "uuid",
  "url": "https://ornek.com/webhook",
  "events": [
    "payment.received"
  ],
  "is_active": true,
  "secret_masked": "whsec_…a1b2"
}
POST /api/external/v1/webhooks X-API-Key scope: webhooks:manage

Create webhook

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.

Request Body

FieldTypeRequiredDescription
urlstring (https)YesDelivery URL (https only)
eventsarrayYesEvent(s) to subscribe
descriptionstringNoDescription
Request Example
curl -X POST "https://api.parsekpro.com/api/external/v1/webhooks" \
  -H "X-API-Key: pk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://ornek.com/parsek-webhook","events":["invoice.status_changed","payment.received"],"description":"Muhasebe entegrasyonu"}'
Response 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)"
}
PUT /api/external/v1/webhooks/{id} X-API-Key scope: webhooks:manage

Update webhook

Updates URL, event list, `is_active` (enable/disable) or description. SSRF check is re-applied if the URL changes.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesWebhook ID

Request Body

FieldTypeRequiredDescription
urlstring (https)NoNew URL
eventsarrayNoNew event list
is_activebooleanNoEnable/disable
descriptionstringNoDescription
Request Example
curl -X PUT "https://api.parsekpro.com/api/external/v1/webhooks/{id}" \
  -H "X-API-Key: pk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"is_active":false}'
Response Example
{
  "id": "uuid",
  "url": "https://ornek.com/parsek-webhook",
  "events": [
    "payment.received"
  ],
  "is_active": false
}
DELETE /api/external/v1/webhooks/{id} X-API-Key scope: webhooks:manage

Delete webhook

Deletes the webhook endpoint and its delivery records.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesWebhook ID
Request Example
curl -X DELETE "https://api.parsekpro.com/api/external/v1/webhooks/{id}" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
{
  "success": true
}
POST /api/external/v1/webhooks/{id}/test X-API-Key scope: webhooks:manage

Send test delivery

Sends a `webhook.test` event synchronously and returns the result (HTTP code, attempts).

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesWebhook ID
Request Example
curl -X POST "https://api.parsekpro.com/api/external/v1/webhooks/{id}/test" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
{
  "delivered": true,
  "response_code": 200,
  "error": null,
  "attempts": 1
}
GET /api/external/v1/webhooks/{id}/deliveries X-API-Key scope: webhooks:manage

List delivery logs

Returns delivery attempts for the endpoint (status, attempts, HTTP code, error) with pagination. For debugging.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesWebhook ID
pageintegerqueryNoPage (0-based)
limitintegerqueryNoPage size
Request Example
curl -X GET "https://api.parsekpro.com/api/external/v1/webhooks/{id}/deliveries" \
  -H "X-API-Key: pk_xxxxxxxx"
Response 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
}
POST /api/external/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver X-API-Key scope: webhooks:manage

Redeliver a delivery

Manually re-sends a failed (or any) delivery, resetting the attempt counter; returns the result synchronously.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesWebhook ID
deliveryIdstring (uuid)pathYesDelivery ID
Request Example
curl -X POST "https://api.parsekpro.com/api/external/v1/webhooks/{id}/deliveries/{deliveryId}/redeliver" \
  -H "X-API-Key: pk_xxxxxxxx"
Response Example
{
  "delivered": true,
  "response_code": 200,
  "error": null,
  "attempts": 1,
  "will_retry": false
}

API Keys

GET /api/external/keys Bearer

List API keys

Lists company API keys (admin/super_admin). Keys are returned masked.

Request Example
curl -X GET "https://api.parsekpro.com/api/external/keys" \
  -H "Authorization: Bearer <TOKEN>"
Response Example
[
  {
    "id": "uuid",
    "key_name": "Muhasebe Entegrasyonu",
    "api_key_masked": "...a1b2c3d4",
    "is_active": true,
    "rate_limit": 60,
    "request_count": 128
  }
]
POST /api/external/keys Bearer

Create API key

Generates a new API key (pk_ prefixed). The full key is shown only once at creation.

Request Body

FieldTypeRequiredDescription
key_namestringNoKey name
permissionsarrayNoPermissions (default ['einvoice'])
rate_limitintegerNoPer-minute limit (default 60)
allowed_domainsarrayNoAllowed origins (for browser calls)
Request Example
curl -X POST "https://api.parsekpro.com/api/external/keys" \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"key_name":"Muhasebe Entegrasyonu","permissions":["einvoice"],"rate_limit":60}'
Response Example
{
  "id": "uuid",
  "api_key": "pk_9f...c3",
  "message": "API anahtari olusturuldu. Bu anahtari guvenli bir yerde saklayin."
}
DELETE /api/external/keys/{id} Bearer

Delete API key

Deletes the given API key.

Parameters

FieldTypeinRequiredDescription
idstring (uuid)pathYesKey ID
Request Example
curl -X DELETE "https://api.parsekpro.com/api/external/keys/{id}" \
  -H "Authorization: Bearer <TOKEN>"
Response Example
{
  "success": true
}

Webhooks Active

Parsek sends outbound POST requests to your HTTPS endpoint when subscribed events occur. Manage endpoints via the Webhooks API above.

Event catalog

EventDescription
current_account.createdA current account (cari) was created
current_account.updatedA current account was updated
inventory.movement.createdA stock movement was recorded
inventory.low_stockStock fell below the minimum level
invoice.status_changedAn e-Invoice status changed
payment.receivedA payment was received (PayTR)
webhook.testTest delivery (manual)

Delivery headers

HeaderDescription
X-Parsek-EventEvent name
X-Parsek-DeliveryUnique delivery ID
X-Parsek-TimestampUnix timestamp (seconds)
X-Parsek-Signaturet=<timestamp>,v1=<hmac_sha256>

Payload shape

{
  "id": "3f1c...",
  "event": "payment.received",
  "created": "2026-02-10T10:00:00.000Z",
  "data": {
    "merchant_oid": "SUB123",
    "amount": 649,
    "currency": "TL",
    "request_type": "subscription",
    "received_at": "2026-02-10T10:00:00.000Z"
  }
}

Signature verification (HMAC-SHA256)

const crypto = require('crypto');
// Express: gövdeyi HAM alın → express.raw({ type: 'application/json' })
function verifyParsekWebhook(req, secret) {
  const header = req.headers['x-parsek-signature'] || '';   // 't=...,v1=...'
  const parts = Object.fromEntries(header.split(',').map(p => p.split('=')));
  const timestamp = parts.t, received = parts.v1;
  const body = req.body.toString('utf8');                    // ham JSON string
  const expected = crypto.createHmac('sha256', secret)
    .update(timestamp + '.' + body).digest('hex');
  const ok = received && received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  // Replay koruması: 5 dakikadan eski istekleri reddedin
  const fresh = Math.abs(Date.now()/1000 - Number(timestamp)) < 300;
  return ok && fresh;
}

Retry & reliability

Failed deliveries (non-2xx or timeout) are retried automatically 4 times with backoff (30s, 2m, 10m, 30m). You can inspect attempts via the deliveries endpoint and re-send manually via the redeliver endpoint. Only public https URLs are accepted (private/internal IPs are blocked — SSRF protection).

Coming Soon Soon

The APIs below are under development and not live yet. Only the “Active” endpoints above are usable.

🏗️

ERP Data API

Read-only access to projects and progress payments.

🦺

OHS / IBYS API

Employee health tracking, PPE assignment and IBYS notification integration.

🏭

OIZ API

Participant companies, parcels, dues accruals and utility meter data.