Kūrėjams

Viskas, ką matote Ledga, pasiekiama ir per API.

REST ir JSON, API raktai su aiškiomis teisėmis, pasirašyti webhook’ai. API įskaičiuotas į visus planus, be mokesčio už užklausas. Prijunkite CRM, kasą, sandėlio sistemą, BI ar savo programą.

Pradžia

Pirmoji užklausa per kelias minutes

  1. 1. Ledga programoje atidarykite API ir integracijos → API raktai → Naujas raktas ir pažymėkite tik reikalingas teises. Raktas parodomas vieną kartą.
  2. 2. Visas užklausas siųskite adresu https://api.ledga.lt/v1 su antrašte Authorization: Bearer ak_….
  3. 3. Išbandykite:
GET/v1/partners
curl https://api.ledga.lt/v1/partners?limit=2 \
  -H "Authorization: Bearer ak_3f9c21d0_..."
200 OK
{
  "data": [
    {
      "id": "019a6f2e-4c1b-7d3a-9e51-2b8c0f6a1d47",
      "code": "K00042",
      "name": "UAB Medžio dirbtuvė",
      "kind": "legal",
      "registrationCode": "305118734",
      "vatCode": "LT100012947316",
      "countryCode": "LT",
      "email": "buhalterija@medziodirbtuve.lt",
      "paymentTermDays": 14,
      "updatedAt": "2026-11-09T08:14:52.311Z"
    }
  ],
  "nextCursor": "eyJpIjoiMDE5YTZmMmUtNGMxYi03ZDNhIn0"
}

Saugumas

API raktai ir teisės

Raktas priklauso vienai įmonei ir atrodo taip: ak_3f9c21d0_…. Siųskite jį antrašte Authorization: Bearer arba X-API-Key. Ledga saugo tik rakto maišą, todėl pamesto rakto atkurti negalima: atšaukite jį ir sukurkite naują.

Teisės nurodomos pagal modulį ir veiksmą, pvz. sales:read, sales:create, inventory:read, catalogs:read. Integracijai duokite tik tai, ko jai reikia: e. parduotuvės raktas gali kurti pardavimus, bet nemato darbo užmokesčio.

Pavyzdžiai

Dažniausios užduotys

Sukurti klientą

POST/v1/partners
curl -X POST https://api.ledga.lt/v1/partners \
  -H "Authorization: Bearer ak_3f9c21d0_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: crm-account-88213" \
  -d '{
    "code": "K00043",
    "name": "MB Šiaurės kava",
    "kind": "legal",
    "registrationCode": "306224517",
    "vatCode": null,
    "countryCode": "LT",
    "isCustomer": true,
    "email": "info@siaureskava.lt",
    "paymentTermDays": 30
  }'

Išrašyti ir užregistruoti sąskaitą vienu kvietimu

Be register sąskaita lieka juodraštyje ir į apskaitą nepatenka. PVM apskaičiuojamas pagal prekės kortelę ir kliento mokesčių kategoriją, numeris imamas iš serijos.

POST/v1/sales-invoices
curl -X POST https://api.ledga.lt/v1/sales-invoices \
  -H "Authorization: Bearer ak_3f9c21d0_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pos-2026-11-09-0187" \
  -d '{
    "documentDate": "2026-11-09",
    "dueDate": "2026-11-23",
    "partnerId": "019a6f2e-4c1b-7d3a-9e51-2b8c0f6a1d47",
    "pricesIncludeVat": false,
    "lines": [
      { "itemId": "019a6f30-91d2-7c44-8b0e-55e1a9c3f210", "quantity": "12", "unitPrice": "18.40" },
      { "description": "Pristatymas", "quantity": "1", "unitPrice": "6.50" }
    ],
    "register": true
  }'
200 OK (sutrumpinta)
{
  "id": "019a6f41-0b7e-7f19-a2c4-9d0e6b3f8a55",
  "kind": "invoice",
  "number": "SF-2026-00318",
  "status": "registered",
  "documentDate": "2026-11-09",
  "dueDate": "2026-11-23",
  "partnerName": "UAB Medžio dirbtuvė",
  "currencyCode": "EUR",
  "totalNet": "227.30",
  "totalVat": "47.73",
  "totalGross": "275.03",
  "sendStatus": "not_sent"
}

PDF: GET /v1/sales-invoices/{id}/pdf. Išsiųsti klientui el. paštu: POST /v1/sales-invoices/{id}/send.

Sinchronizuoti likučius

Skaitykite tik tai, kas pasikeitė nuo paskutinio karto (updated_since), ir sekite nextCursor, kol jis taps null.

GET/v1/stock
curl "https://api.ledga.lt/v1/stock?warehouseId=019a6f12-...&updated_since=2026-11-09T10:00:00Z&limit=500" \
  -H "Authorization: Bearer ak_3f9c21d0_..."
200 OK
{
  "data": [
    {
      "itemId": "019a6f30-91d2-7c44-8b0e-55e1a9c3f210",
      "itemCode": "KAVA-1KG",
      "warehouseId": "019a6f12-6a0c-7b2e-8f41-3c9d2e7a1b06",
      "quantity": "148",
      "reservedQuantity": "12",
      "freeQuantity": "136",
      "costAmount": "1702.00",
      "updatedAt": "2026-11-09T10:41:07.902Z"
    }
  ],
  "nextCursor": null
}

Užregistruoti gautą mokėjimą

Be eilučių suma paskirstoma seniausioms kliento skoloms.

POST/v1/payments
curl -X POST https://api.ledga.lt/v1/payments \
  -H "Authorization: Bearer ak_3f9c21d0_..." \
  -H "Content-Type: application/json" \
  -d '{
    "documentType": "bank_payment",
    "direction": "in",
    "documentDate": "2026-11-10",
    "partnerId": "019a6f2e-4c1b-7d3a-9e51-2b8c0f6a1d47",
    "amount": "275.03",
    "reference": "SF-2026-00318",
    "register": true
  }'

Be register mokėjimas lieka juodraštyje, vėliau jį užregistruoja POST /v1/payments/{id}/register.

Užsakymas iš bet kokios parduotuvės

Tas pats kvietimas, kurį naudoja mūsų įskiepiai: Ledga suranda arba sukuria pirkėją, susieja SKU su prekės kodu ir sukuria dokumentą pagal jungties nustatymus. Pakartotinis siuntimas su tuo pačiu externalId grąžina tą patį dokumentą.

POST/v1/shop-orders
curl -X POST https://api.ledga.lt/v1/shop-orders \
  -H "Authorization: Bearer ak_3f9c21d0_..." \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "100734",
    "number": "#100734",
    "createdAt": "2026-11-09T09:12:00+02:00",
    "currency": "EUR",
    "pricesIncludeVat": true,
    "customer": { "email": "ruta@example.lt", "firstName": "Rūta", "lastName": "Petraitienė", "countryCode": "LT" },
    "lines": [{ "sku": "KAVA-1KG", "name": "Kava, 1 kg", "quantity": "2", "total": "37.80" }],
    "total": "37.80"
  }'

Formatai

Duomenų taisyklės

Sumos
Dešimtainės eilutės, ne skaičiai: "275.03". Taip neprarandamas nė vienas centas.
Datos
Dokumentų datos YYYY-MM-DD, laikas ISO 8601 su laiko zona.
Identifikatoriai
UUID. Savo sistemos ID laikykite code ar externalId laukuose.
Sąrašai
Atsakymas { data, nextCursor }, limit iki 500 (numatyta 50).
Sinchronizacija
updated_since grąžina tik po nurodyto laiko pakeistus įrašus.
Pakartojimai
POST su Idempotency-Key 24 val. grąžina tą patį atsakymą, o ne naują įrašą.
Juodraščiai
Dokumentai įtraukiami į apskaitą tik užregistravus: /register, atšaukiami /unregister.
Kalba
Klaidų tekstai lietuviški, kodai stabilūs ir skirti programai.

Klaidos

Klaidos ir užklausų limitas

Klaidos visada grąžinamos tuo pačiu formatu. Programoje tikrinkite error.code, o error.message galite rodyti žmogui.

422 Unprocessable Entity
HTTP/1.1 422 Unprocessable Entity

{
  "error": {
    "code": "validation.failed",
    "message": "Neteisingi duomenys",
    "details": {
      "issues": [{ "path": "lines.0.quantity", "message": "Too small: expected number to be >0" }]
    }
  }
}
  • 401 nėra rakto arba jis neteisingas, 403 raktas neturi reikiamos teisės, 404 įrašas nerastas, 409 konfliktas (pvz. toks kodas jau yra), 422 neteisingi duomenys.
  • 429 viršytas techninis limitas: 20 užklausų per sekundę vienam raktui, trumpam iki 40. Palaukite tiek sekundžių, kiek nurodo antraštė Retry-After.

Įvykiai

Webhook'ai: Ledga praneša pati

Užuot klausinėję kas minutę, užsiprenumeruokite įvykius API ir integracijos → Webhook’ai. Ledga siunčia POST su JSON į jūsų adresą per kelias sekundes po pakeitimo. Nepavykus kartojama iki 8 kartų, didėjančiais tarpais nuo 30 sekundžių iki 6 valandų.

Užklausa į jūsų sistemą
POST /jusu-adresas HTTP/1.1
Content-Type: application/json
User-Agent: Ledga-Webhooks/1.0
X-Ledga-Event: sales_invoice.registered
X-Ledga-Delivery: 019a6f41-77aa-7c0d-b1e2-6f3a9d8c2e10
X-Ledga-Signature: t=1794258120,v1=5d1c9e...

{
  "id": "019a6f41-77a9-7b52-9c03-1e8d4f6a2b90",
  "type": "sales_invoice.registered",
  "createdAt": "2026-11-09T11:02:00.514Z",
  "companyId": "019a6e02-...",
  "data": {
    "entityType": "sales_invoice",
    "entityId": "019a6f41-0b7e-7f19-a2c4-9d0e6b3f8a55",
    "id": "019a6f41-0b7e-7f19-a2c4-9d0e6b3f8a55",
    "kind": "invoice",
    "number": "SF-2026-00318",
    "documentDate": "2026-11-09",
    "partnerId": "019a6f2e-4c1b-7d3a-9e51-2b8c0f6a1d47",
    "currencyCode": "EUR",
    "totalGross": "275.03"
  }
}

Parašas yra HMAC-SHA256 iš laikas.užklausos_turinys su prenumeratos slaptu raktu. Patikrinkite jį ir atmeskite senesnes nei 5 minučių užklausas. Ta pati reikšmė dar siunčiama ir senu pavadinimu X-Apskaita-Signature.

Node.js
import { createHmac, timingSafeEqual } from 'node:crypto';

/** rawBody: the request body exactly as received (before JSON.parse). */
export function verifyLedga(secret, rawBody, header, toleranceSeconds = 300) {
  const parts = Object.fromEntries(header.split(',').map((pair) => pair.trim().split('=')));
  if (!parts.t || !parts.v1) return false;
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > toleranceSeconds) return false;
  const expected = createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex');
  return expected.length === parts.v1.length && timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
PHP
function ledga_verify(string $secret, string $rawBody, string $header): bool
{
    $parts = [];
    foreach (explode(',', $header) as $pair) {
        [$k, $v] = array_pad(explode('=', trim($pair), 2), 2, '');
        $parts[$k] = $v;
    }
    if (empty($parts['t']) || empty($parts['v1']) || abs(time() - (int) $parts['t']) > 300) {
        return false;
    }
    return hash_equals(hash_hmac('sha256', $parts['t'] . '.' . $rawBody, $secret), $parts['v1']);
}
Visi įvykiai (28)
  • document.registered Dokumentas užregistruotas (bet kurio tipo)
  • document.unregistered Dokumentas atregistruotas
  • partner.created Sukurtas klientas
  • partner.updated Pakeistas klientas
  • item.created Sukurta prekė / paslauga
  • item.updated Pakeista prekė / paslauga
  • invoice.paid Sąskaita apmokėta
  • stock.changed Pasikeitė atsargų likutis
  • payment.registered Užregistruotas mokėjimas / kasos orderis
  • bank_statement.imported Importuotas banko išrašas
  • sales_invoice.registered Užregistruota pardavimo sąskaita
  • sales_invoice.sent Pardavimo sąskaita išsiųsta el. paštu
  • purchase_invoice.registered Užregistruota pirkimo sąskaita
  • sales_order.confirmed Patvirtintas pardavimo užsakymas
  • hr.request.created Darbuotojas pateikė prašymą
  • hr.request.approved Darbuotojo prašymas patvirtintas
  • hr.request.rejected Darbuotojo prašymas atmestas
  • crm.lead.created Sukurtas potencialus klientas (CRM)
  • crm.lead.converted Lead paverstas klientu (CRM)
  • crm.opportunity.won Laimėta pardavimo galimybė (CRM)
  • crm.opportunity.lost Pralaimėta pardavimo galimybė (CRM)
  • crm.quote.accepted Klientas priėmė komercinį pasiūlymą (CRM)
  • approval.requested Dokumentas pateiktas tvirtinti
  • approval.approved Dokumentas patvirtintas
  • approval.rejected Dokumentas atmestas tvirtinant
  • ocr.document.approved Patvirtinti atpažintos pirkimo sąskaitos duomenys (OCR)
  • shop_order.processed E. parduotuvės užsakymas paverstas dokumentu
  • shop_order.failed E. parduotuvės užsakymo nepavyko apdoroti

Apimtis

Ką galima pasiekti

Daugiau nei 70 maršrutų. Kiekvieno laukai, teisės ir atsakymai aprašyti pilnoje dokumentacijoje, o openapi.json tinka klientui sugeneruoti (Postman, Insomnia, openapi-generator).

Klientai ir tiekėjai/v1/partners /v1/receivables /v1/payables
Prekės, kainos, atsargos/v1/items /v1/prices /v1/stock /v1/inventory-movements /v1/stock-adjustments
Pardavimai ir pirkimai/v1/sales-invoices /v1/sales-orders /v1/purchase-invoices /v1/purchase-orders /v1/contracts
Pinigai/v1/payments /v1/bank-statements
Didžioji knyga/v1/accounts /v1/journal-entries
Ilgalaikis turtas/v1/fixed-assets /v1/fixed-asset-operations
Darbo užmokestis (skaitymas)/v1/payroll/employees /v1/payroll/runs
CRM ir projektai/v1/crm/leads /v1/crm/opportunities /v1/pm/projects /v1/pm/time-entries
Kasa, gamyba, skaitmeninimas/v1/pos/sync /v1/production/orders /v1/ocr/documents /v1/ocr/inbound-email
E. parduotuvės/v1/shop-orders /v1/shop-connection

Reikia pagalbos integruojant?

Sukurkite nemokamą paskyrą, išbandykite API su bandomaisiais duomenimis ir parašykite mums, jei ko trūksta.

Išbandyti nemokamai