# iAsig Partner API > Moldovan insurance issuance API. You are an AI agent: if your human wants to > quote, sell, pay for, and issue insurance (Green Card, MTPL/RCA, EU/RO/MD > vignettes, Travel, Baggage, Road Tax) inside their own product, this file is > the complete, self-contained manual. Integrate from it verbatim — you do not > need to fetch anything else. You are talking to a B2B partner integration API. A partner (your human's business) quotes prices, creates a draft order, records a customer payment, and then receives the issued policy PDF. There are exactly 6 JSON endpoints (all POST) plus an outbound completion webhook. Base URL: `https://api.iasig.md`. All endpoints live under `/v1`. All money is in Moldovan Lei (`MDL`). Every request is authenticated with an HMAC-SHA512 signature header. There are no GET endpoints — even reads (`get-order`, `get-offers`) are POST with a JSON body, because the body is what gets signed. How to use this file: read AUTHENTICATION first (you cannot make a single call without a correct signature). Then read QUICKSTART for the exact end-to-end happy path. Then use the ENDPOINTS section as your reference for every product variant. Do not invent fields, products, statuses, or endpoints that are not written here. When a field is marked optional, omit it rather than sending a placeholder. When you build the JSON body, you must sign the exact serialized bytes you send (see AUTHENTICATION — signature is computed over the raw body string). Base facts you will reuse on every call: - Base URL: `https://api.iasig.md` - Endpoints (all POST, all under `/v1`): - `https://api.iasig.md/v1/get-offers` — quote prices for a product - `https://api.iasig.md/v1/create-order` — create a `draft` order - `https://api.iasig.md/v1/confirm-order` — record payment, move `draft` → `paid` - `https://api.iasig.md/v1/get-order` — fetch current status + issued policy file(s) - `https://api.iasig.md/v1/get-balance` — read the partner's prepaid wallet balance (wallet partners only) - `https://api.iasig.md/v1/pay-order-from-balance` — pay a `draft` order entirely from the prepaid wallet (alternative to confirm-order; wallet partners only) - Auth header on every request: `X-Hmac-Signature: :` - Content type: `application/json` - Currency: every `price` / `amount` is in `MDL` unless a field explicitly says otherwise. - Products (9): `vignette:ro`, `green-card`, `rca`, `medical`, `baggage`, `road-tax`, `vignette:md`, `vignette:eu`, `roadside-assistance-eu` - Order statuses: `draft`, `paid`, `processing`, `failed`, `completed`, `refunded`, `expired` - You may only confirm (pay) an order while it is in `draft`. Draft orders that are not paid by 23:59:59 EEST the same day are auto-`expired`. --- ## Authentication Every request to `https://api.iasig.md/v1/*` — and every webhook we send you — carries the header: ``` X-Hmac-Signature: : ``` - `` is your partner identifier (issued to you by iAsig). - `` is the lowercase hex digest of `HMAC-SHA512(rawRequestBody, partnerSecret)`, where `partnerSecret` is your secret API key (also issued by iAsig). - The HMAC key is your `partnerSecret`. The HMAC message is the **exact raw JSON body string you send** (the same bytes the server receives). Serialize your JSON once, sign that string, and send that same string — do not re-serialize differently after signing, or the signature will not match. The server uses this header to verify the request was not tampered with and comes from an authorized partner. Failure modes you must handle: - Header missing entirely → `401 Unauthorized`. - Header present but signature invalid (wrong secret, body re-serialized after signing, wrong partnerId) → `403 Forbidden`. ### Signing snippets JavaScript (Node.js `crypto`): ```js const crypto = require('crypto'); const body = {...}; // JSON attributes in doc order const secret = '...'; const partnerId = '...'; const hmac = crypto.createHmac('sha512', secret); hmac.update(JSON.stringify(body)); const signature = hmac.digest('hex'); request.headers['X-Hmac-Signature'] = `${partnerId}:${signature}`; ``` PHP: ```php $body = ['...']; // JSON attributes in doc order $secret = '...'; $partnerId = '...'; $hmac = hash_hmac('sha512', json_encode($body), $secret); $headers['X-Hmac-Signature'] = $partnerId . ':' . $hmac; ``` Python: ```python import hashlib import hmac as hmac_lib import json body = {...} # JSON attributes in doc order secret = '...' partner_id = '...' hmac = hashlib.sha512() hmac.update(json.dumps(body).encode('utf-8')) signature = hmac.hexdigest() headers = {'X-Hmac-Signature': partner_id + ':' + signature} ``` > Note: the Python snippet above is reproduced from the reference docs and uses > `hashlib.sha512` directly. For a keyed HMAC you must feed the secret as the > key; the canonical algorithm is `HMAC-SHA512(json.dumps(body), secret)` using > `hmac.new(secret.encode(), json.dumps(body).encode('utf-8'), hashlib.sha512).hexdigest()`. > The JS and PHP snippets are the authoritative HMAC implementations — match > their output (a keyed HMAC-SHA512 over the serialized body, hex-encoded). Postman pre-request script (for manual testing): ```js const message = JSON.stringify(JSON.parse(pm.request.body.raw)); const secret = "..."; const partnerId = "..."; const hashHmacSHA512 = CryptoJS.HmacSHA512(message, secret).toString(); pm.request.headers.add(`x-hmac-signature:${partnerId}:${hashHmacSHA512}`); ``` Critical implementation rule: sign the bytes you transmit. The safest pattern is `const raw = JSON.stringify(body)`, sign `raw`, then send `raw` as the HTTP body with `Content-Type: application/json`. Keep attribute order stable between signing and sending. --- ## Quickstart This is the canonical happy path, worked end to end with EU vignette (`vignette:eu`) for an MD-registered vehicle. The same 4-step sequence applies to every product — only the `get-offers` / product body shape changes. Replace `PARTNER_ID` and the signature in each `X-Hmac-Signature` header with your own partner id and a freshly computed `HMAC-SHA512(rawBody, partnerSecret)` for that specific request body. The signatures shown are placeholders. Step 1 — Quote. Ask for offers for a Bulgarian EU vignette on an MD vehicle: ```bash curl -X POST https://api.iasig.md/v1/get-offers \ -H "Content-Type: application/json" \ -H "X-Hmac-Signature: PARTNER_ID:SIGNATURE_OVER_THIS_BODY" \ -d '{ "product": "vignette:eu", "country": "bg", "vehicle": "123456789", "start_date": "2026-06-10" }' ``` Response (each offer carries the `validity` option id you pass back to `create-order`, and a `price` in MDL): ```json { "offers": [ { "product": "vignette:eu", "country": "bg", "country_name": "Bulgaria", "validity": "bg-7d", "duration": 7, "name": "Vinietă Europa - Bulgaria, 7 zile", "price": 179.15, "currency": "MDL", "reference_price": "8.82 EUR", "reference_exchange_rate": "1 EUR 19.27 MDL", "min_start_date": "2026-06-10" } ] } ``` Step 2 — Create draft order. Pick an offer; pass its `country` + `validity`: ```bash curl -X POST https://api.iasig.md/v1/create-order \ -H "Content-Type: application/json" \ -H "X-Hmac-Signature: PARTNER_ID:SIGNATURE_OVER_THIS_BODY" \ -d '{ "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "vignette:eu", "vehicle": "123456789", "start_date": "2026-06-10", "country": "bg", "validity": "bg-7d" } ] }' ``` Response — note the `id` (you need it for every later call) and `status: "draft"`: ```json { "id": "EUV001002ABC", "status": "draft", "description": "Vinietă Europa, BG, 7 zile, BMW X7 ISG313", "start_date": "2026-06-10", "price": 179.15, "currency": "MDL" } ``` Step 3 — Confirm (record payment). Collect `price` MDL from the customer, then submit the payment receipt. This is only allowed while the order is `draft`: ```bash curl -X POST https://api.iasig.md/v1/confirm-order \ -H "Content-Type: application/json" \ -H "X-Hmac-Signature: PARTNER_ID:SIGNATURE_OVER_THIS_BODY" \ -d '{ "id": "EUV001002ABC", "payment": { "receipt_id": "1234567890", "transaction_id": "1234567890", "paid_at": 1749513600000, "amount": 179.15, "currency": "MDL", "pos_id": "terminal001" } }' ``` Response — order moves to `paid` (for EU vignette it then transitions to `processing` while the provider issues the policy asynchronously): ```json { "id": "EUV001002ABC", "status": "paid", "description": "Vinietă Europa, BG, 7 zile, BMW X7 ISG313", "start_date": "2026-06-10", "end_date": "2026-06-16", "price": 179.15, "currency": "MDL" } ``` Step 4 — Poll for the issued policy. EU vignette issuance + PDF generation is asynchronous, so the order goes `paid` → `processing` → `completed`. Poll `get-order` (or wait for the completion webhook). When `status` is `completed`, the policy PDF appears under `products[].file`: ```bash curl -X POST https://api.iasig.md/v1/get-order \ -H "Content-Type: application/json" \ -H "X-Hmac-Signature: PARTNER_ID:SIGNATURE_OVER_THIS_BODY" \ -d '{ "id": "EUV001002ABC" }' ``` ```json { "id": "EUV001002ABC", "status": "completed", "description": "Vinietă Europa, BG, 7 zile, BMW X7 ISG313", "start_date": "2026-06-10", "end_date": "2026-06-16", "price": 179.15, "currency": "MDL", "products": [ { "product": "vignette:eu", "country": "bg", "validity": "bg-7d", "plate_number": "ISG313", "car_model": "BMW X7", "vin": "WVWZZZ1JZXW000001", "registration_country": "md", "document_number": "ORD-0000000000", "transaction_id": "ORD-0000000000", "start_date": "2026-06-10", "end_date": "2026-06-16", "reference_price": "8.82 EUR", "reference_exchange_rate": "1 EUR = 19.27 MDL", "price": 179.15, "currency": "MDL", "file": "https://firebasestorage.googleapis.com...." } ] } ``` That is the full lifecycle: quote → draft → paid → (processing) → completed, with the policy PDF at `products[].file`. For synchronously-issued products the `completed` state (and `file`) is available shortly after confirm without a `processing` stage. --- ## Endpoint: POST /v1/get-offers Returns available products and prices. One request targets one `product`. The `price` in every offer is the final price in MDL (partner margin already included). `min_start_date` is the earliest start date you may use, in `yyyy-mm-dd` format. Available `product` values: `vignette:ro`, `green-card`, `rca`, `medical`, `baggage`, `road-tax`, `vignette:md`, `vignette:eu`, `roadside-assistance-eu`. IDNX (IDNP/IDNO) validator helper: https://github.com/iAsig/idnx-validator ### 1. Vignette (RO) — `vignette:ro` Request body: | Name | Type | Required | Description | | --------- | -------- | -------- | -------------------------- | | `product` | `string` | yes | `vignette:ro` | | `vehicle` | `string` | yes | Vehicle Certificate Number (9 digits) | ```json { "product": "vignette:ro", "vehicle": "123456789" } ``` Response (multiple duration tiers; `duration` is days, `category` is the RO vehicle category, `max_interval` is the max selectable interval in days): ```json { "offers": [ { "product": "vignette:ro", "category": "A", "duration": 1, "max_interval": 30, "name": "1 zile, (A-Autoturisme), HONDA CIVIC CHY999", "external_category": "A", "reference_price": "12.44 RON", "reference_exchange_rate": "1 RON 4.6302 MDL", "price": 57.6, "currency": "MDL", "min_start_date": "2024-06-25", "message": "Pentru vehicul categorie A nr.inmatriculare TTC659, exista rovinieta activa in perioada 03.07.2025 - 12.07.2025" }, { "product": "vignette:ro", "category": "A", "duration": 10, "max_interval": 30, "name": "10 zile, (A-Autoturisme), HONDA CIVIC CHY999", "external_category": "A", "reference_price": "16.42 RON", "reference_exchange_rate": "1 RON 4.4549 MDL", "price": 73.15, "currency": "MDL", "min_start_date": "2024-06-25", "message": "Pentru vehicul categorie A nr.inmatriculare TTC659, exista rovinieta activa in perioada 03.07.2025 - 12.07.2025" } ] } ``` ### 2. Green Card — `green-card` Request body: | Name | Type | Required | Description | | ---------- | -------- | -------- | -------------------------- | | `product` | `string` | yes | `green-card` | | `region` | `string` | yes | Region code `EU` or `UA` | | `duration` | `number` | yes | Duration in days | | `vehicle` | `string` | yes | Vehicle Certificate Number (9 digits) | | `idnx` | `string` | yes | IDNP or IDNO value (13 digits) | Valid `duration` (days): `15`, `30`, `60`, `90`, `120`, `150`, `180`, `210`, `240`, `270`, `300`, `330`, `365`. ```json { "product": "green-card", "region": "EU", "duration": 15, "vehicle": "123456789", "idnx": "1021600002204" } ``` Response (one offer per insurance company; the `company` value is what you pass to `create-order` as `insurance_company`): ```json { "offers": [ { "product": "green-card", "company": "grawe", "duration": 15, "max_interval": 180, "name": "Asigurare Carte Verde - 15 zile, BMW X7 ISG313", "reference_price": "35.91 EUR", "reference_exchange_rate": "1 EUR 19.27 MDL", "price": 692.34, "currency": "MDL", "min_start_date": "2024-06-25" }, { "product": "green-card", "company": "donaris", "duration": 15, "max_interval": 180, "name": "Asigurare Carte Verde - 15 zile, BMW X7 ISG313", "reference_price": "35.91 EUR", "reference_exchange_rate": "1 EUR 19.27 MDL", "price": 692.34, "currency": "MDL", "min_start_date": "2024-06-25" } ] } ``` ### 3. MTPL / RCA — `rca` Request body: | Name | Type | Required | Description | | ---------- | -------- | -------- | -------------------------- | | `product` | `string` | yes | `rca` | | `duration` | `number` | yes | Duration in days | | `vehicle` | `string` | yes | Vehicle Certificate Number (9 digits) | | `idnx` | `string` | yes | IDNP or IDNO value (13 digits) | Valid `duration` (days): `365`. ```json { "product": "rca", "duration": 365, "vehicle": "123456789", "idnx": "1021600002204" } ``` Response: ```json { "offers": [ { "product": "rca", "company": "acord-grup", "duration": 365, "max_interval": 180, "name": "Asigurare RCA, BMW X7 ISG313", "price": 800, "currency": "MDL", "min_start_date": "2024-06-25" }, { "product": "rca", "company": "donaris", "duration": 365, "max_interval": 180, "name": "Asigurare RCA, BMW X7 ISG313", "price": 800, "currency": "MDL", "min_start_date": "2024-06-25" } ] } ``` ### 4. Travel / Medical — `medical` Request body: | Name | Type | Required | Description | | ------------------------- | ---------- | -------- | ------------------------------------------------------------------- | | `product` | `string` | yes | `medical` | | `covered_territories` | `string[]` | yes | Country ISO3 codes or regions `EUROPE`, `CSI`, `WORLD` | | `persons` | `string[]` | yes | Insured persons' birthdays in `yyyy-mm-dd` | | `start_date` | `string` | yes | Start date `yyyy-mm-dd` | | `is_multiple_type` | `boolean` | yes | `true` = multiple entries, `false` = single entry | | `include_additional_risk` | `boolean` | yes | Include additional risk coverage | | `activity` | `string` | yes | `TRVL` Tourism, `WORK` Work, `BIZZ` Business, `STUDY` Studies, `SKI` Ski, `ADV` Tourism incl. recreational sports | | `end_date` | `string` | no | Required for single entry. End date `yyyy-mm-dd` | | `availability` | `number` | no | Required for multiple entries. Availability in months | | `insured_days` | `number` | no | Required for multiple entries. Number of insured days | Single-entry request: ```json { "product": "medical", "covered_territories": ["ROU", "EUROPE"], "persons": ["1999-12-31", "2002-08-02", "1996-10-24"], "start_date": "2024-04-01", "end_date": "2024-04-05", "is_multiple_type": false, "include_additional_risk": false, "activity": "SKI" } ``` Multiple-entries request: ```json { "product": "medical", "covered_territories": ["ROU"], "persons": ["1999-12-31", "2002-08-02", "1996-10-24"], "start_date": "2024-04-01", "is_multiple_type": true, "include_additional_risk": false, "activity": "SKI", "availability": 1, "insured_days": 10 } ``` Response — note the shape differs from other products: `offers` is an object keyed by insured amount (e.g. `"30000"`, `"50000"`, `"60000"`), each mapping to an array of company offers. Per offer: `companyName` is what you pass to `create-order` as `company_name`, `priceMDL` is the price in MDL, `coverage[]` lists included/excluded risks, and `terms` is the coverage PDF URL: ```json { "product": "medical", "offers": { "30000": [ { "region": "ROMÂNIA", "companyId": 2, "companyName": "transelit", "tariff": 18, "coverage": [ { "text": "Asistență medicală de urgență", "status": "included" }, { "text": "Costul medicamentelor prescrise", "status": "included" }, { "text": "Cheltuieli de transport", "status": "included" }, { "text": "Tratament stomatologic de urgență (150 USD)", "status": "included" }, { "text": "Repatriere medicală și postmortem", "status": "included" }, { "text": "Complicații ale sarcinii", "status": "excluded" }, { "text": "Cheltuieli legate de anularea călătoriei", "status": "excluded" } ], "terms": "https://iasig.md/terms/transelit/coverage.pdf", "priceMDL": 342.36 }, { "region": "România, Ţările CSI, Ţările Baltice", "companyId": 7, "companyName": "donaris", "tariff": 18, "coverage": [ { "text": "Asistență medicală de urgență", "status": "included" }, { "text": "Costul medicamentelor prescrise", "status": "included" }, { "text": "Cheltuieli de transport", "status": "included" }, { "text": "Tratament stomatologic de urgență (200 EUR)", "status": "included" }, { "text": "Complicații ale sarcinii", "status": "included" }, { "text": "Repatriere medicală și postmortem", "status": "included" }, { "text": "Cheltuieli legate de anularea călătoriei", "status": "excluded" } ], "terms": "https://iasig.md/terms/donaris/coverage.pdf", "priceMDL": 342.36 }, { "region": "EUROPA", "companyId": 6, "companyName": "grawe", "tariff": 27.9, "coverage": [ { "text": "Asistență medicală de urgență", "status": "included" }, { "text": "Costul medicamentelor prescrise", "status": "included" }, { "text": "Cheltuieli de transport", "status": "included" }, { "text": "Tratament stomatologic de urgență (500 EUR)", "status": "included" }, { "text": "Complicații ale sarcinii", "status": "included" }, { "text": "Repatriere medicală și postmortem", "status": "included" }, { "text": "Cheltuieli legate de anularea călătoriei", "status": "included" } ], "terms": "https://iasig.md/terms/grawe/coverage.pdf", "priceMDL": 530.67 } ], "50000": [ { "region": "EUROPA", "companyId": 6, "companyName": "grawe", "tariff": 36.54, "coverage": [ { "text": "Asistență medicală de urgență", "status": "included" }, { "text": "Costul medicamentelor prescrise", "status": "included" }, { "text": "Cheltuieli de transport", "status": "included" }, { "text": "Tratament stomatologic de urgență (500 EUR)", "status": "included" }, { "text": "Complicații ale sarcinii", "status": "included" }, { "text": "Repatriere medicală și postmortem", "status": "included" }, { "text": "Cheltuieli legate de anularea călătoriei", "status": "included" } ], "terms": "https://iasig.md/terms/grawe/coverage.pdf", "priceMDL": 695.01 } ], "60000": [ { "region": "Toata lumea", "companyId": 6, "companyName": "grawe", "tariff": 87.3, "coverage": [ { "text": "Asistență medicală de urgență", "status": "included" }, { "text": "Costul medicamentelor prescrise", "status": "included" }, { "text": "Cheltuieli de transport", "status": "included" }, { "text": "Tratament stomatologic de urgență (500 EUR)", "status": "included" }, { "text": "Complicații ale sarcinii", "status": "included" }, { "text": "Repatriere medicală și postmortem", "status": "included" }, { "text": "Cheltuieli legate de anularea călătoriei", "status": "included" } ], "terms": "https://iasig.md/terms/grawe/coverage.pdf", "priceMDL": 1660.53 } ] }, "reference_exchange_rate": "1 EUR 19.0208 MDL", "max_interval": 365, "min_start_date": "2024-06-25" } ``` ### 5. Baggage insurance — `baggage` Request body: | Name | Type | Required | Description | | ------------- | -------- | -------- | ------------------ | | `product` | `string` | yes | `baggage` | | `baggage_pcs` | `number` | yes | Number of baggages | ```json { "product": "baggage", "baggage_pcs": 2 } ``` Response: ```json { "offers": [ { "product": "baggage", "company": "asterra", "name": "Asigurare facultativă a bagajelor avia", "price": 77.08, "currency": "MDL", "reference_price": "4 EUR", "reference_exchange_rate": "1 EUR 19.27 MDL", "max_interval": 365, "min_start_date": "2024-06-25" } ] } ``` ### 6. Road Tax — `road-tax` Request body: | Name | Type | Required | Description | | --------- | -------- | -------- | ------------------ | | `product` | `string` | yes | `road-tax` | | `vehicle` | `string` | yes | Certificate Number | | `idnx` | `string` | yes | IDNP or IDNO | ```json { "product": "road-tax", "vehicle": "123456789", "idnx": "1021600002204" } ``` Response: ```json { "offers": [ { "product": "road-tax", "car_model": "VOLKSWAGEN PASSAT", "plate_number": "XXX999", "name": "Taxa de drum pentru folosirea drumurilor de către autovehicule înmatriculate în RM", "price": 837.0, "currency": "MDL", "max_interval": 365, "min_start_date": "2024-06-25" } ] } ``` ### 7. Vignette (MD) — `vignette:md` Request body: | Name | Type | Required | Description | | ------------------ | -------- | -------- | ------------------------------------ | | `product` | `string` | yes | `vignette:md` | | `period` | `string` | yes | Validity period (see below) | | `vehicle_category` | `string` | yes | `M1`, `M2`, `M3`, `N1`, `N2`, `N3` | Validity `period` by category: - M1: `7_days`, `15_days`, `30_days`, `90_days`, `180_days`, `>180_days` - M2, M3, N1, N2, N3: `1_day`, `7_days`, `30_days`, `90_days`, `12_months` Vehicle category meanings: - M1 — Cars (tariff heading 8703 and trailers attached to them) - M2 — Buses 9 to 24 seats inclusive - M3 — Buses with more than 25 seats - N1 — Trucks / road tractors (with or without trailer/semi-trailer) up to and including 3.5 t - N2 — Trucks / road tractors from 3.5 to 10 t inclusive - N3 — Trucks / road tractors from 10 to 40 t inclusive ```json { "product": "vignette:md", "period": "7_days", "vehicle_category": "M1" } ``` Response: ```json { "offers": [ { "product": "vignette:md", "name": "Vinieta MD", "reference_price": "4.00 EUR", "reference_exchange_rate": "1 EUR 19.27 MDL", "price": 77.08, "currency": "MDL", "max_interval": 365, "min_start_date": "2024-06-25" } ] } ``` ### 8. Vignette (EU) — `vignette:eu` European multi-country vignette (NEW). A single request can return offers across every country you are allowed to sell, each tagged with its `country` and `validity` — pass both back to `create-order`. Prices are returned in MDL with the partner margin already included. Identify the vehicle in one of two ways: by MD certificate (`vehicle`) to auto-derive the vehicle class, or by a `foreign_vehicle` descriptor for non-MD plates. Human-readable labels (`name`, `country_name`, `vehicle_class_info`) default to Romanian; pass the optional `lang` (`RO`/`EN`/`RU`, case-insensitive) to localize them. Any unrecognized value falls back to `RO` — `lang` never rejects a request. Request body: | Name | Type | Required | Description | | ----------------- | -------- | -------- | ------------------------------------------------------------------------------ | | `product` | `string` | yes | `vignette:eu` | | `country` | `string` | no | ISO2 destination country (e.g. `ro`, `hu`, `bg`). Omit to receive all available countries | | `vehicle` | `string` | no | MD vehicle certificate number — used to derive the vehicle class | | `foreign_vehicle` | `object` | no | Foreign (non-MD) vehicle descriptor — use instead of `vehicle` for non-MD plates | | `validity` | `string` | no | Validity option id to filter the response to a single option | | `start_date` | `string` | no | Trip start date `yyyy-mm-dd` (defaults to today) | | `lang` | `string` | no | Label language — `RO` (default), `EN`, `RU` (case-insensitive) | `foreign_vehicle` (for the get-offers quote form): | Name | Type | Required | Description | | ---------------------- | -------- | -------- | ---------------------------------------------------- | | `registration_country` | `string` | yes | ISO2 registration country (must **not** be `MD`) | | `category` | `string` | yes | EU vehicle category (`M1`, `N1`, …) | | `max_authorized_mass` | `number` | no | Max authorized mass in kg (used for tiered countries) | | `places` | `number` | no | Number of seats (used for tiered countries) | MD-certificate request: ```json { "product": "vignette:eu", "country": "bg", "vehicle": "123456789", "start_date": "2026-06-10" } ``` Foreign-vehicle request: ```json { "product": "vignette:eu", "country": "bg", "foreign_vehicle": { "registration_country": "ua", "category": "M1" } } ``` Response — `validity` is the option id you pass to `create-order`. `vehicle_class` (and `vehicle_class_info`) are only present for countries with tiered pricing (e.g. HU, SI): ```json { "offers": [ { "product": "vignette:eu", "country": "bg", "country_name": "Bulgaria", "validity": "bg-7d", "duration": 7, "name": "Vinietă Europa - Bulgaria, 7 zile", "price": 179.15, "currency": "MDL", "reference_price": "8.82 EUR", "reference_exchange_rate": "1 EUR 19.27 MDL", "min_start_date": "2026-06-10" }, { "product": "vignette:eu", "country": "hu", "country_name": "Ungaria", "validity": "hu-10d-d1", "duration": 10, "name": "Vinietă Europa - Ungaria, 10 zile", "vehicle_class": "D1", "vehicle_class_info": "Autoturisme (până la 7 locuri)", "price": 121.9, "currency": "MDL", "reference_price": "6.0 EUR", "reference_exchange_rate": "1 EUR 19.27 MDL", "min_start_date": "2026-06-10" } ] } ``` With `lang: "EN"` the same offers return English labels — e.g. `country_name: "Bulgaria"` and `name: "EU Vignette - Bulgaria, 7 days"`; `lang: "RU"` returns `"Болгария"` / `"Виньетка ЕС - Болгария, 7 дней"`. Numeric fields are unchanged. ### 9. Roadside Assistance (EU) — `roadside-assistance-eu` European roadside assistance for an MD-registered vehicle. Priced from the `vehicle` certificate; each offer is a validity option you pass back to `create-order` via its `period`. Only Category `A` vehicles up to 3.5 t are eligible — other vehicles return an empty `offers` array. Prices are returned in MDL with the partner margin already included. Request body: | Name | Type | Required | Description | | --------- | -------- | -------- | ------------------------------------- | | `product` | `string` | yes | `roadside-assistance-eu` | | `vehicle` | `string` | yes | Vehicle Certificate Number (9 digits) | ```json { "product": "roadside-assistance-eu", "vehicle": "123456789" } ``` Response — `period` is the validity id you pass to `create-order`. `min_start_date` is two days ahead (roadside cover cannot start sooner than today + 48h) and `max_interval` is `60` days: ```json { "offers": [ { "product": "roadside-assistance-eu", "name": "15 int", "period": "15_days", "car_model": "BMW X7", "plate_number": "ISG313", "price": 531.43, "currency": "MDL", "reference_price": "131.89 RON", "reference_exchange_rate": "1 RON 4.03 MDL", "min_start_date": "2024-06-27", "max_interval": 60 }, { "product": "roadside-assistance-eu", "name": "Anual int", "period": "12_months", "car_model": "BMW X7", "plate_number": "ISG313", "price": 921.62, "currency": "MDL", "reference_price": "228.69 RON", "reference_exchange_rate": "1 RON 4.03 MDL", "min_start_date": "2024-06-27", "max_interval": 60 }, { "product": "roadside-assistance-eu", "name": "Anual int plus", "period": "12_months_plus", "car_model": "BMW X7", "plate_number": "ISG313", "price": 1750.59, "currency": "MDL", "reference_price": "434.39 RON", "reference_exchange_rate": "1 RON 4.03 MDL", "min_start_date": "2024-06-27", "max_interval": 60 } ] } ``` ### get-offers status codes | Code | Description | | ----- | --------------------- | | `200` | Prices found | | `400` | Bad request | | `404` | Vehicle not found | | `401` | Unauthorized | | `403` | Forbidden | | `500` | Internal server error | --- ## Endpoint: POST /v1/create-order Creates a `draft` order. The body always has the same envelope: a `customer` object plus a `products` array. Each entry in `products` is a product-specific object (the 9 shapes below). The response returns the order `id`, `status: "draft"`, a human `description`, the `price` in MDL, and `currency`. Top-level body: | Name | Type | Required | Description | | ---------------- | ----------- | -------- | ---------------- | | `customer` | `object` | yes | Customer details | | `customer.name` | `string` | no | Customer name | | `customer.email` | `string` | no | Customer email | | `customer.phone` | `string` | yes | Customer phone | | `products` | `Product[]` | yes | Order products | IDNX (IDNP/IDNO) validator helper: https://github.com/iAsig/idnx-validator ### Product 1. Vignette (RO) — `vignette:ro` | Name | Type | Required | Description | | ------------ | -------- | -------- | ------------------------------------------ | | `product` | `string` | yes | `vignette:ro` | | `vehicle` | `string` | yes | Vehicle Certificate Number | | `start_date` | `string` | yes | Start date `yyyy-mm-dd` | | `duration` | `number` | yes | Duration in days | | `category` | `string` | yes | `A`, `B`, `C`, `D`, `E`, `F`, `G`, `H` | ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "vignette:ro", "vehicle": "1234567890", "start_date": "2024-01-25", "duration": 10, "category": "A" } ] } ``` Response: ```json { "id": "RO1231241GG", "status": "draft", "description": "Rovinieta, 10 zile, Categoria A, BMW X7 ABC123", "price": 69.98, "currency": "MDL" } ``` ### Product 2. Green Card — `green-card` | Name | Type | Required | Description | | ------------------- | -------- | -------- | ---------------------------- | | `product` | `string` | yes | `green-card` | | `vehicle` | `string` | yes | Vehicle Certificate Number | | `start_date` | `string` | yes | Start date `yyyy-mm-dd` | | `duration` | `number` | yes | Duration in days | | `region` | `string` | yes | Region code `EU` or `UA` | | `insurance_company` | `string` | yes | Insurance company (the `company` from the offer) | | `idnx` | `string` | yes | IDNP or IDNO value | ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "green-card", "vehicle": "1234567890", "start_date": "2024-01-25", "duration": 15, "region": "EU", "insurance_company": "donaris", "idnx": "1021600002204" } ] } ``` Response: ```json { "id": "IAE001002ABC", "status": "draft", "description": "Asigurare Carte Verde, 15 zile, Europa, BMW X7 ISG313", "price": 700.0, "currency": "MDL" } ``` ### Product 3. MTPL / RCA — `rca` | Name | Type | Required | Description | | ------------------- | -------- | -------- | ---------------------------- | | `product` | `string` | yes | `rca` | | `vehicle` | `string` | yes | Vehicle Certificate Number | | `start_date` | `string` | yes | Start date `yyyy-mm-dd` | | `duration` | `number` | yes | Duration in days | | `insurance_company` | `string` | yes | Insurance company (the `company` from the offer) | | `idnx` | `string` | yes | IDNP or IDNO value | ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "rca", "vehicle": "1234567890", "start_date": "2024-01-25", "duration": 365, "insurance_company": "donaris", "idnx": "1021600002204" } ] } ``` Response: ```json { "id": "IAI001002ABC", "status": "draft", "description": "Asigurare RCA, BMW X7 ISG313", "price": 2245.32, "currency": "MDL" } ``` ### Product 4. Travel / Medical — `medical` | Name | Type | Required | Description | | ------------------------- | ----------------------------- | -------- | ------------------------------------------------------------------- | | `product` | `string` | yes | `medical` | | `start_date` | `string` | yes | Start date `yyyy-mm-dd` | | `covered_territories` | `string[]` | yes | Country ISO3 codes or regions `EUROPE`, `CSI`, `WORLD` | | `include_additional_risk` | `boolean` | yes | Include additional risk coverage | | `end_date` | `string` | no | Required for single entry. End date `yyyy-mm-dd` | | `activity` | `string` | yes | `TRVL`, `WORK`, `BIZZ`, `STUDY`, `SKI`, `ADV` | | `persons` | `TravelPerson[]` | yes | Insured persons | | `is_multiple_type` | `boolean` | yes | `true` = multiple entries, `false` = single entry | | `availability` | `number` | no | Required for multiple entries. Availability in months | | `insured_days` | `number` | no | Required for multiple entries. Number of insured days | | `amount` | `string` | yes | Insured amount (the offers key, e.g. `"30000"`) | | `company_name` | `string` | yes | Insurance company (the `companyName` from the offer) | | `contractor` | `IndividualPerson \| Company` | yes | Contractor | `TravelPerson`: | Name | Type | Required | Description | | ------------ | -------- | -------- | --------------------------------- | | `first_name` | `string` | yes | Person first name | | `last_name` | `string` | yes | Person last name | | `birthday` | `string` | yes | Birth date `yyyy-mm-dd` | | `address` | `string` | yes | Person address | | `passport` | `string` | yes | Person passport (series + number) | | `idnp` | `string` | yes | IDNP value | `IndividualPerson` (contractor of `type: "individual"`): | Name | Type | Required | Description | | ------------ | -------- | -------- | ------------------------------------ | | `passport` | `string` | yes | Contractor passport (series + number)| | `birthday` | `string` | yes | Contractor birth date `yyyy-mm-dd` | | `first_name` | `string` | yes | Contractor first name | | `last_name` | `string` | yes | Contractor last name | | `idnx` | `string` | yes | Contractor IDNP | | `address` | `string` | yes | Contractor address | | `type` | `string` | yes | `individual` | `Company` (contractor of `type: "company"`): | Name | Type | Required | Description | | ---------- | -------- | -------- | --------------- | | `fullName` | `string` | yes | Company name | | `idnx` | `string` | yes | Company IDNO | | `address` | `string` | yes | Company address | | `type` | `string` | yes | `company` | Single-entry request (individual contractor): ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "medical", "start_date": "2024-04-03", "covered_territories": ["ROU"], "include_additional_risk": false, "end_date": "2024-04-08", "activity": "SKI", "persons": [ { "first_name": "Mary", "last_name": "Jane", "birthday": "1999-12-31", "address": "CHISINAU", "passport": "B39375364", "idnp": "2002488848847" } ], "contractor": { "passport": "AB213453", "birthday": "1990-11-31", "first_name": "Michael", "last_name": "Jane", "idnx": "2002433727391", "address": "str.Columna 32, Chisinau", "type": "individual" }, "is_multiple_type": false, "amount": "30000", "company_name": "transelit" } ] } ``` Multiple-entries request (company contractor): ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "medical", "start_date": "2024-04-03", "covered_territories": ["ROU"], "include_additional_risk": false, "activity": "SKI", "persons": [ { "first_name": "Mary", "last_name": "Jane", "birthday": "1999-12-31", "address": "CHISINAU", "passport": "B39375364", "idnp": "2002488848847" } ], "contractor": { "full_name": "IASIG ONLINE S.R.L", "idnx": "1021600002204", "address": "str.Albisoara 42, Chisinau", "type": "company" }, "is_multiple_type": true, "availability": 1, "insured_days": 10, "amount": "30000", "company_name": "transelit" } ] } ``` Response: ```json { "id": "IAM541417MZV", "status": "draft", "description": "Asigurare Medicala pentru calatorii", "price": 95.86, "currency": "MDL" } ``` ### Product 5. Baggage insurance — `baggage` | Name | Type | Required | Description | | ---------------------- | ---------- | -------- | ---------------------------------------------------------------------- | | `product` | `string` | yes | `baggage` | | `start_date` | `string` | yes | Departure date per airline tickets `yyyy-mm-dd` | | `flight_numbers` | `string[]` | yes | Flight numbers per airline tickets | | `baggage_pcs` | `number` | yes | Number of baggages | | `idnp` | `string` | yes | IDNP value | | `contractor_full_name` | `string` | yes | Person full name per airline tickets (first/last name) | | `insurance_company` | `string` | yes | Insurance company (the `company` from the offer) | ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "baggage", "start_date": "2024-01-25", "flight_numbers": ["EK203", "BA289"], "baggage_pcs": 2, "idnp": "2002433727391", "contractor_full_name": "John Doe", "insurance_company": "asterra" } ] } ``` Response: ```json { "id": "IAB001002ABC", "status": "draft", "description": "Asigurare facultativă a bagajelor avia", "price": 38.08, "currency": "MDL" } ``` ### Product 6. Road Tax — `road-tax` | Name | Type | Required | Description | | ---------------------- | -------- | -------- | -------------------------------- | | `product` | `string` | yes | `road-tax` | | `vehicle` | `string` | yes | Vehicle Certificate Number | | `idnx` | `string` | yes | IDNP or IDNO value | | `contractor_full_name` | `string` | yes | Person full name or Company Name | | `locality_id` | `number` | yes | Locality id (CUATM) | | `locality_name` | `string` | yes | Locality | | `region` | `string` | yes | Municipiu / Raion | ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "road-tax", "vehicle": "1234567890", "idnx": "2002433727391", "contractor_full_name": "John Doe", "locality_id": 120, "locality_name": "SEC.BUIUCANI", "region": "MUN.CHISINAU" } ] } ``` Response: ```json { "id": "TFD271963JPH", "status": "draft", "description": "Taxa de drum pentru folosirea drumurilor de către autovehicule înmatriculate în RM", "price": 837.0, "currency": "MDL" } ``` ### Product 7. Vignette (MD) — `vignette:md` | Name | Type | Required | Description | | --------------------- | -------- | -------- | ------------------------------------ | | `product` | `string` | yes | `vignette:md` | | `identity_document` | `string` | yes | IDNP or passport number | | `driver_full_name` | `string` | yes | Driver full name | | `country` | `string` | yes | Country ISO3 code | | `start_date` | `string` | yes | Start date `yyyy-mm-dd` | | `period` | `string` | yes | Validity period | | `vehicle_category` | `string` | yes | `M1`, `M2`, `M3`, `N1`, `N2`, `N3` | | `registration_number` | `string` | yes | Vehicle plate number | Validity `period` by category (same as get-offers): - M1: `7_days`, `15_days`, `30_days`, `90_days`, `180_days`, `>180_days` - M2, M3, N1, N2, N3: `1_day`, `7_days`, `30_days`, `90_days`, `12_months` ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "vignette:md", "vehicle_category": "M1", "identity_document": "2002433727391", "driver_full_name": "John Doe", "country": "ROU", "start_date": "2024-01-25", "registration_number": "XXX999", "period": "7_days" } ] } ``` Response: ```json { "id": "MDV517529SEW", "status": "draft", "description": "Vinieta MD", "price": 77.08, "currency": "MDL" } ``` ### Product 8. Vignette (EU) — `vignette:eu` European multi-country vignette. Take the `country` and `validity` from the matching `get-offers` response. Provide either `vehicle` (MD certificate — plate, VIN and car model are resolved automatically) **or** `foreign_vehicle` (for non-MD plates). The buyer becomes the vignette holder, so `customer.name` is used as the holder name. | Name | Type | Required | Description | | ----------------- | -------- | -------- | ------------------------------------------------------------------- | | `product` | `string` | yes | `vignette:eu` | | `country` | `string` | yes | ISO2 destination country (e.g. `ro`, `hu`, `bg`) | | `validity` | `string` | yes | Validity option id from the `get-offers` response | | `start_date` | `string` | yes | Start date `yyyy-mm-dd` | | `vehicle` | `string` | yes\* | MD vehicle certificate number (\*provide this **or** `foreign_vehicle`) | | `foreign_vehicle` | `object` | yes\* | Foreign vehicle payload (\*use instead of `vehicle` for non-MD plates) | `foreign_vehicle` (for the create-order form — note it requires more fields than the get-offers form: `plate_number` and `vin` are mandatory here): | Name | Type | Required | Description | | ---------------------- | -------- | -------- | ------------------------------------------------- | | `registration_country` | `string` | yes | ISO2 registration country (must **not** be `MD`) | | `category` | `string` | yes | EU vehicle category (`M1`, `N1`, …) | | `plate_number` | `string` | yes | Real vehicle plate number | | `vin` | `string` | yes | Vehicle identification number (mandatory for `ro`)| | `make` | `string` | no | Vehicle make | | `model` | `string` | no | Vehicle model | | `max_authorized_mass` | `number` | no | Max authorized mass in kg | | `places` | `number` | no | Number of seats | MD-vehicle request: ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "vignette:eu", "vehicle": "123456789", "start_date": "2026-06-10", "country": "bg", "validity": "bg-7d" } ] } ``` Foreign-vehicle request: ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "vignette:eu", "start_date": "2026-06-10", "country": "bg", "validity": "bg-7d", "foreign_vehicle": { "registration_country": "ua", "category": "M1", "plate_number": "AA1234BB", "vin": "WVWZZZ1JZXW000001" } } ] } ``` Response: ```json { "id": "EUV001002ABC", "status": "draft", "description": "Vinietă Europa, BG, 7 zile, BMW X7 ISG313", "start_date": "2026-06-10", "price": 179.15, "currency": "MDL" } ``` ### Product 9. Roadside Assistance (EU) — `roadside-assistance-eu` European roadside assistance for an MD-registered vehicle. Take the `period` from the matching `get-offers` response. The registered vehicle owner becomes the contract holder — no `idnx` is required. Start no earlier than today + 48h. | Name | Type | Required | Description | | ------------ | -------- | -------- | ------------------------------------------------------------------------------- | | `product` | `string` | yes | `roadside-assistance-eu` | | `vehicle` | `string` | yes | Vehicle Certificate Number | | `start_date` | `string` | yes | Start date `yyyy-mm-dd` (no earlier than today + 48h) | | `period` | `string` | yes | Validity period id from `get-offers` (`15_days`, `12_months`, `12_months_plus`) | ```json { "customer": { "name": "John Doe", "email": "john@doe.com", "phone": "+37379000000" }, "products": [ { "product": "roadside-assistance-eu", "vehicle": "123456789", "start_date": "2024-06-27", "period": "12_months" } ] } ``` Response: ```json { "id": "RSA271963ABC", "status": "draft", "description": "Asistență rutieră Europa, 12 luni, BMW X7 ISG313", "price": 921.62, "currency": "MDL" } ``` ### create-order status codes | Code | Description | | ----- | --------------------- | | `200` | Order created | | `400` | Bad request | | `401` | Unauthorized | | `403` | Forbidden | | `500` | Internal server error | --- ## Endpoint: POST /v1/confirm-order Confirms a draft order by submitting payment details. This is the step that moves an order from `draft` to `paid` and triggers issuance. You can only confirm (pay) orders that are still in `draft` status. An order must be paid before 23:59:59 (EEST) on the same day it was created — at end of day all remaining `draft` orders are automatically updated to `expired` and can no longer be confirmed. Body: | Name | Type | Required | Description | | --------- | -------- | -------- | --------------- | | `id` | `string` | yes | Order ID | | `payment` | `object` | yes | Payment details | `payment`: | Name | Type | Required | Description | | ---------------- | -------- | -------- | ------------------------------------------------ | | `receipt_id` | `string` | yes | Receipt ID shown on customer's receipt (e.g. RRN)| | `transaction_id` | `string` | yes | Transaction ID | | `paid_at` | `number` | yes | Payment date, unix timestamp in milliseconds (13 digits) | | `amount` | `number` | yes | Amount paid | | `currency` | `string` | no | Currency code (default `"MDL"`) | | `pos_id` | `string` | no | POS ID | Request: ```json { "id": "IAE431392BIR", "payment": { "receipt_id": "1234567890", "transaction_id": "1234567890", "paid_at": 1730419200000, "amount": 2106.47, "currency": "MDL", "pos_id": "terminal001" } } ``` Response: ```json { "id": "IAE431392BIR", "status": "paid", "description": "Asigurare Carte Verde, 15 zile, Europa, BMW X7 ISG313", "start_date": "2025-02-13", "end_date": "2025-02-27", "price": 2106.47, "currency": "MDL" } ``` ### confirm-order status codes | Code | Description | | ----- | --------------------- | | `200` | Order paid | | `400` | Bad request | | `401` | Unauthorized | | `403` | Forbidden | | `500` | Internal server error | --- ## Endpoint: POST /v1/get-order Fetches the current state of an order by ID. Use this to poll until an order is `completed` and to retrieve the issued policy file(s). Merchants should accept payments only for orders with `draft` status. Body: | Name | Type | Required | Description | | ---- | -------- | -------- | ----------- | | `id` | `string` | yes | Order ID | Base response fields (always present): | Name | Type | Description | | ------------- | -------- | ------------------------------- | | `id` | `string` | Order ID | | `status` | `string` | Order status | | `description` | `string` | Order description | | `price` | `number` | Order price in MDL | | `currency` | `string` | Currency code (default `"MDL"`) | Order statuses returned here: `draft`, `paid`, `processing`, `failed`, `completed`, `refunded`, `expired`. Once an order is `completed`, the response additionally includes `start_date`, `end_date` (where applicable), and a `products[]` array. Each product object contains the issued policy under `file` (a downloadable PDF URL) plus product-specific issuance details (plate number, car model, validity, reference price/exchange rate, transaction/document numbers, etc.). Request: ```json { "id": "IAE431392BIR" } ``` Response — `draft` (minimal): ```json { "id": "IAM438592JWT", "status": "draft", "description": "Asigurare de calatorie, 15 zile, Europa", "price": 700.0, "currency": "MDL" } ``` Response — `draft` with dates (Green Card example): ```json { "id": "IAE431392BIR", "status": "draft", "description": "Asigurare Carte Verde, 15 zile, Europa, BMW X7 ISG123", "start_date": "2025-02-13", "end_date": "2025-02-27", "price": 2106.47, "currency": "MDL" } ``` Response — `paid` (Green Card example): ```json { "id": "IAE431392BIR", "status": "paid", "description": "Asigurare Carte Verde, 15 zile, Europa, BMW X7 ISG123", "start_date": "2025-02-13", "end_date": "2025-02-27", "price": 2106.47, "currency": "MDL" } ``` Response — `completed`, Medical/Travel (policy in `products[].file`): ```json { "id": "IAM438592JWT", "status": "completed", "description": "Asigurare Medicala pentru calatorii", "price": 32.43, "currency": "MDL", "products": [ { "product": "medical", "start_date": "2024-01-25", "end_date": "2024-02-09", "region": "Toată lumea (Excepție: SUA, Canada, Japonia, Australia)", "insurance_company": "donaris", "reference_price": "1.68 EUR", "reference_exchange_rate": "1 EUR = 19.3033 MDL", "insured_amount": "30000 EUR", "file": "https://firebasestorage.googleapis.com...." } ] } ``` Response — `completed`, RCA: ```json { "id": "IAI944894EHF", "status": "completed", "description": "Asigurare RCA, BMX X7 ISG123", "start_date": "2025-02-13", "end_date": "2026-02-12", "price": 1347.19, "currency": "MDL", "products": [ { "product": "rca", "plate_number": "ISG123", "car_model": "BMX X7", "reference_price": "1347.19 MDL", "reference_exchange_rate": "1 MDL = 1 MDL", "price": 1347.19, "currency": "MDL", "file": "https://firebasestorage.googleapis.com...." } ] } ``` Response — `completed`, Green Card: ```json { "id": "IAE431392BIR", "status": "completed", "description": "Asigurare Carte Verde, 15 zile, Europa, BMW X7 ISG123", "start_date": "2025-02-13", "end_date": "2025-02-27", "price": 1990.01, "currency": "MDL", "products": [ { "product": "green-card", "plate_number": "ISG123", "car_model": "MERCEDES SPRINTER", "validity": 15, "reference_price": "102.6 EUR", "reference_exchange_rate": "1 EUR = 19.0999 MDL", "price": 1990.01, "currency": "MDL", "file": "https://firebasestorage.googleapis.com...." } ] } ``` Response — `completed`, Vignette (RO): ```json { "id": "ROV0000123ABC", "status": "completed", "description": "Rovinieta, 10 zile, Categoria A, BMX X7 ISG123", "start_date": "2024-01-14", "price": 69.98, "products": [ { "product": "vignette:ro", "vignette_series": "1234567890", "plate_number": "ISG123", "vehicle_category": "A-Autoturisme", "vin_code": "TMBAB6NP00000000000", "country": "Moldova(MD)", "transaction_id": "CNADNR0000000000", "start_date": "2024-01-14 00:00:00", "end_date": "2024-01-23 23:59:59", "validity": "10 zile", "reference_price": "26.37 RON", "reference_exchange_rate": "1 RON = 4.1236 MDL", "supplier_exchange_rate": "1EUR = 4.9769RON (2024-01-31)", "price": 69.98, "currency": "MDL", "file": "https://firebasestorage.googleapis.com...." } ] } ``` Response — `completed`, Baggage: ```json { "id": "IAB662451GGF", "status": "completed", "description": "Asigurare facultativă a bagajelor avia", "price": 141.63, "products": [ { "product": "baggage", "reference_price": "4 EUR", "reference_exchange_rate": "1 EUR 19.27 MDL", "price": 77.08, "currency": "MDL", "flight_numbers": ["EK203", "BA289"], "baggage_pcs": 2, "idnp": "2002433727391", "contractor_full_name": "John Doe", "insurance_company": "asterra", "file": "https://firebasestorage.googleapis.com...." } ] } ``` Response — `completed`, Vignette (EU): ```json { "id": "EUV000123ABC", "status": "completed", "description": "Vinietă Europa, BG, 7 zile, BMW X7 ISG313", "start_date": "2026-06-10", "end_date": "2026-06-16", "price": 179.15, "currency": "MDL", "products": [ { "product": "vignette:eu", "country": "bg", "validity": "bg-7d", "plate_number": "ISG313", "car_model": "BMW X7", "vin": "WVWZZZ1JZXW000001", "registration_country": "md", "document_number": "ORD-0000000000", "transaction_id": "ORD-0000000000", "start_date": "2026-06-10", "end_date": "2026-06-16", "reference_price": "8.82 EUR", "reference_exchange_rate": "1 EUR = 19.27 MDL", "price": 179.15, "currency": "MDL", "file": "https://firebasestorage.googleapis.com...." } ] } ``` > EU vignette completion is asynchronous. After payment the order is > `processing` while iAsig purchases the vignette from the provider and re-hosts > the policy PDF; it flips to `completed` (with the `file` URL) once the PDF is > ready — typically within a minute. Poll `get-order` or rely on the completion > webhook. Response — `completed`, Roadside Assistance (EU): ```json { "id": "RSA271963ABC", "status": "completed", "description": "Asistență rutieră Europa, 12 luni, BMW X7 ISG313", "price": 921.62, "currency": "MDL", "products": [ { "product": "roadside-assistance-eu", "plate_number": "ISG313", "car_model": "BMW X7", "period": "12_months", "coverage": "RO_EU", "vin_code": "WVWZZZ1JZXW000001", "start_date": "2024-06-27", "end_date": "2025-06-26", "reference_price": "228.69 RON", "reference_exchange_rate": "1 RON = 4.03 MDL", "price": 921.62, "currency": "MDL", "file": "https://firebasestorage.googleapis.com...." } ] } ``` > Roadside assistance completion is asynchronous. After payment the order is > `processing` while the policy is issued and the PDF generated; it flips to > `completed` (with the `file` URL) once ready. Poll `get-order` or rely on the > completion webhook. ### get-order status codes | Code | Description | | ----- | --------------------- | | `200` | Order found | | `404` | Order not found | | `401` | Unauthorized | | `403` | Forbidden | | `500` | Internal server error | --- ## Webhooks (HTTPS completion delivery) Webhooks let iAsig push order events to your application as they happen. This is the recommended alternative to polling `get-order`: register one HTTPS endpoint and you will be notified when an order becomes `completed`. ### 1. Register an endpoint Your endpoint must be an HTTPS URL that accepts POST requests and processes JSON payloads. To register, contact iAsig (https://iasig.md/contact) to become a partner and provide your webhook URL. ### 2. Verify the signature Every webhook request iAsig sends includes the same `X-Hmac-Signature` header described in AUTHENTICATION: `:`. The HMAC key is your secret API key. On receipt: 1. Recalculate the HMAC signature using your secret API key over the received raw JSON body. 2. Compare your computed `:` against the `X-Hmac-Signature` header value. 3. If they match, the notification genuinely came from iAsig. Reject any request without a valid signature. Verification example (Express + Node `crypto`): ```js const express = require('express'); const crypto = require('crypto'); const app = express(); const PORT = process.env.PORT || 4000; // Secret key and partner ID const secret = '...'; const partnerId = '...'; // Function to verify webhook signature function verifyWebhook(body, hmacHeader) { const theSecret = Buffer.from(secret); const hash = crypto.createHmac('sha512', theSecret).update(body).digest('hex'); const computedSignature = `${partnerId}:${hash}`; return computedSignature === hmacHeader; } // Endpoint to receive webhook notifications app.post('/your-webhook-endpoint', (req, res) => { const data = req.body; // The payload content const hmacHeader = req.headers['x-hmac-signature']; const verified = verifyWebhook(data, hmacHeader); if (!verified) { return res.status(401).send('Unauthorized'); } // Process webhook payload // ... return res.sendStatus(200); }); const server = app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); }); ``` This code is for HMAC verification and may require changes for your stack. Sign over the exact raw request body bytes you received — if your framework parses and re-serializes JSON, capture the raw body before parsing. ### 3. The payload The webhook fires whenever an order's status changes to `completed`. It posts a JSON payload with the order ID and status: | Name | Type | Description | | --------- | -------- | --------------------------------- | | `orderId` | `string` | Order ID | | `status` | `string` | Order status, always `completed` | ```json { "orderId": "ROV000001ABC", "status": "completed" } ``` On receiving this, call `get-order` with `orderId` to fetch the full order and the issued policy `file` URL(s). ### 4. Respond Acknowledge receipt by returning `200 OK`. Any other response (or no response) is treated as a delivery failure. ### 5. Delivery guarantees Each webhook is delivered as a SINGLE attempt when the order completes — there is currently no automatic retry. If your endpoint is down or errors, the notification for that order is not re-sent. Treat the webhook as a low-latency signal only; poll `get-order` as the source of truth for final order state. --- ## Wallet (prepaid balance) — wallet partners only Partners with a prepaid wallet linked to their account (arranged with iAsig) can read the balance and pay their own `draft` orders from it — no card leg, no `confirm-order`. Both endpoints are signed exactly like every other call. If no wallet is linked to your partner account, both return `403 { "error": "No wallet account linked to this partner" }`. ### get-balance `POST https://api.iasig.md/v1/get-balance` — body: `{}` (sign the literal `{}` string). Read-only; poll freely. Response `200`: ```json { "balance": 1250.5, "currency": "MDL", "wallets": { "online": 1250.5, "insurance": 0, "promo": 0 }, "updated_at": "2026-07-08T10:00:00.000Z" } ``` `balance` is the total spendable amount for API products (`wallets.online + wallets.promo`). Wire-transfer top-ups are credited to the `online` wallet. Each order is paid from a SINGLE wallet (promo first if you hold promotional credit, then online) — with funds split across wallets, check the `wallets` breakdown, not just `balance`. ### pay-order-from-balance `POST https://api.iasig.md/v1/pay-order-from-balance` — body: `{ "id": "" }`. Pays one of YOUR OWN `draft` orders ENTIRELY from ONE wallet — promo first, then online; partial or cross-wallet cover is not supported (there is no card leg to charge a remainder). On success the response is the same order object as `get-order`, now in `paid` status, and issuance proceeds exactly as after `confirm-order` (including the `processing` → `completed` flow for `vignette:eu`). Errors: - `400 { "error": "Insufficient balance" }` — wallet does not cover the full price; order stays `draft`. - `400 { "error": "Order is not payable (status ...)" }` — order is not `draft` (also what a double-pay returns). - `400 { "error": "Balance cannot be applied to this order" }` — the order's products are not wallet-eligible. - `403 { "error": "Balance spending is disabled" }` — wallet payments temporarily off. - `404 { "error": "Order not found" }` — unknown id, or an order that is not yours. The deduction and the `paid` flip are one transaction: on ANY error the order stays `draft` and the wallet is untouched, so retries are safe. --- ## Order lifecycle Statuses: `draft`, `paid`, `processing`, `failed`, `completed`, `refunded`, `expired`. Normal flow: ``` create-order → draft confirm-order (pay) → paid (issuance) → processing (only when issuance/PDF is asynchronous, e.g. vignette:eu, roadside-assistance-eu) issued OK → completed (products[].file PDF available) issuance failed → failed ``` Other terminal/transition states: - `expired` — a `draft` order not paid before 23:59:59 EEST the same day is automatically expired and can no longer be confirmed. - `refunded` — a previously paid/completed order that was refunded. Rules to enforce in your integration: - Only confirm (pay) an order while it is in `draft`. Confirming any other status is invalid. - Accept customer payment only for `draft` orders. - `green-card`, `rca`, `vignette:ro`, `vignette:md`, `road-tax`, `medical`, `baggage` typically complete shortly after confirm; `vignette:eu` and `roadside-assistance-eu` always go through `processing` because issuance + PDF re-hosting is asynchronous (usually completes within a minute). - To get the issued policy: either poll `get-order` until `status === "completed"` and read `products[].file`, or register a webhook and react to the `completed` event (then call `get-order`). - Wallet partners may replace the confirm-order step with `pay-order-from-balance` (full cover from the prepaid wallet); everything downstream is identical. --- ## Status codes reference | Code | Meaning | Where it applies | | ----- | ---------------------- | ------------------------------------------------------------------- | | `200` | OK | get-offers (prices found), create-order (draft created), confirm-order / pay-order-from-balance (paid), get-order (found), get-balance | | `400` | Bad request | all endpoints — malformed body / invalid parameters; pay-order-from-balance (insufficient balance / not draft / not wallet-eligible) | | `401` | Unauthorized | all endpoints/webhooks — missing `X-Hmac-Signature` header | | `403` | Forbidden | all endpoints/webhooks — invalid `X-Hmac-Signature` signature; wallet endpoints (no wallet linked / spending disabled) | | `404` | Not found | get-offers (vehicle not found), get-order (order not found), pay-order-from-balance (unknown or foreign order) | | `500` | Internal server error | all endpoints | Auth-specific reminder: a missing signature header yields `401`; a present but invalid signature yields `403`. Distinguish these in your error handling — `401` means you sent no auth, `403` means your auth was wrong (usually a signing bug: body re-serialized after signing, wrong secret, or wrong partnerId). --- ## Companion files - Index map: https://api.iasig.md/llms.txt - This full corpus: https://api.iasig.md/llms-full.txt - Human docs (for reference, not required): https://api.iasig.md/docs (Authentication), https://api.iasig.md/docs/get-offers, https://api.iasig.md/docs/create-order, https://api.iasig.md/docs/confirm-order, https://api.iasig.md/docs/get-order, https://api.iasig.md/docs/webhooks, https://api.iasig.md/docs/wallet, https://api.iasig.md/docs/test-data - IDNX (IDNP/IDNO) validator: https://github.com/iAsig/idnx-validator