Introduction

Invoice Portal is a modern Greek e-invoicing and electronic document management platform designed to help businesses automate invoicing, simplify integrations, and streamline their financial workflows. Our e-invoicing API enables developers, ERP providers, software companies, and businesses to securely create, transmit, manage, and retrieve electronic invoices through a reliable cloud-based infrastructure.

Built with flexibility and ease of integration in mind, Invoice Portal helps businesses connect their existing applications with electronic invoicing services while supporting efficient, compliant, and scalable digital processes. The platform is also designed for security, resilience, and high availability and is hosted on Microsoft Azure.

We currently serve tens of thousands of businesses across Greece. Currently, Invoice Portal successfully issues and transmits millions of electronic documents every month to Greece’s Independent Authority for Public Revenue (AADE/myDATA). Our focus on innovation, reliability, and service quality has established Invoice Portal as a fast-growing e-invoicing provider trusted by some of the country’s most recognized brands.

E-invoicing made effortless. Invoice Portal by Business Cloud is your trusted partner for smarter, faster, and fully compliant digital invoicing.

To get started, please contact us to obtain credentials for our development environment.

Take a look at our Getting Started Guide.

Invoice Portal provides a user-friendly API for issuing, validating, and securely storing invoices for at least five years. Before integrating with the API, we recommend reviewing the following documentation:

  1. AADE myDATA Documentation
  2. The PEPPOL Specification (optional)
  3. The Greek Government official PEPPOL Specification (also optional)

To issue an invoice, two XML files must be generated:

  • A myDATA XML file containing the invoice summary, classifications, and tax information required by AADE.
  • A complete invoice XML file that follows the applicable electronic invoicing specification.

The current API version complies with AADE myDATA specification version 2.0.1.

Our development API is continuously evolving, so we recommend checking this documentation regularly for updates or contacting us for the latest information.

AI Agent Skill

If you use an AI coding assistant, you can install our Invoice Portal API skill. It teaches the agent how to authenticate, build invoice payloads, handle transmission failures and more.

The skill follows the open Agent Skills format and works with Claude Code, Cursor, Codex and other compatible agents. Install it with skills:

npx skills add https://gitlab.com/itlabgr/skills --skill invoice-portal-api

Keep it up to date with npx skills update.

Getting Started

The creation flow for an invoice is simple: you send a POST request to the Create Invoice Endpoint, store the resulting data, and make sure it is included in the printed invoice.
For ease of development we also provide some examples of common use cases:

POS Transactions

In Greece, B2C Transactions are required by law to follow one of the following flows:

Deferred Transaction

In deferred transactions, the invoice is issued first and paid later. Examples include installment payments or, in food service an R.R. (ΑΛΠ) that the customer pays at a later time.

In this case, you issue the invoice normally, obtain the M.AR.K. number, and based on that you generate the signature. Once the payment occurs, you call UpdatePaymentMethod to notify the provider and AADE about the new payment.

In this flow, you can initially issue the invoice using paymentMethodCode = 7 (POS). However, because it is very likely that AADE will in the future restrict this method and reject POS payments without signatures, we recommend issuing the invoice initially using another payment method (we recommend Credit / On account seems ideal).

Synchronous Transaction

Synchronous transactions are those where the invoice is issued at the moment the transaction is completed. This is probably the most common transaction/issuance model.

Initially, the invoice is sent as unsigned and receives a temporary M.AR.K. At this stage the invoice is considered Pending Issuance (Υπό Έκδοση).

On this pending invoice, you obtain all required signatures as well as the aadeTransactionId.

Once these operations are completed, you send the invoice together with its transactions (including signature data, etc.), and the invoice is finalized, receiving its final M.AR.K.

Note:

  • The temporary M.AR.K. must not be sent when requesting a signature.
  • “Pending Issuance” invoices must be closed within the same day.

Pre-Collection

When an advance payment needs to be recorded, a pre-collection is performed. This is effectively another Synchronous Transaction, executed using a document of type POS Receipt of Collection (Απόδειξη Είσπραξης POS).

Printing

When printing an invoice through your own systems, you must include:

  1. The UID, M.AR.K, and AthenticationCode of the invoice
  2. A link to the invoice through Invoice Portal
  3. A QR linking to the invoice through Invoice Portal

You can also predict the link & QR codes youself. The link will always be /invoices/{issueYear}-{uid}, whereas the QR code will be on /invoices/{issueYear}-{uid}.

Possible Failures

In accordance with the Greek Government's specifications, Invoice Portal and any client applications must handle a few special failure cases.

Transmission Failure 1 - Invoice Portal / No internet access

In case you're using an offline application, or for some unexpected reason Invoice Portal is unreachable, you can still issue invoices if:

  1. You add the QR, link and URL of the invoice in the printed invoice.
  2. You add a prominent text field in the invoice containing the text Απώλεια Διασύνδεσης Οντότητας - Παρόχου - Transmission Failure_1
  3. You send the invoice to Invoice Portal as soon as Invoice Portal becomes available again (A maximum delay of 24 hours is allowed).

Since Invoice Portal is unreachable in such cases, you must generate the UID yourself. Instructions on how to generate the UID can be found in AADE's specification.

Transmission Failure 2 - AADE is unreachable

In cases where AADE is unavailable or unreachable, our system will be unable to return a valid M.AR.K or Authentication Code for your invoice. In these cases Invoice Portal will store your invoice and transmit it to AADE as wheneter their system is available again. As with Transmission Failure 1, you must:

  1. You add the QR, Link and URL of the invoice in the printed invoice.
  2. You add a prominent text field in the invoice containing the text Απώλεια Διασύνδεσης Παρόχου - ΑΑΔΕ - Transmission Failure_2

As soon as our systems transmit your invoices, your application will be notified via a webhook request for the transmission status.

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Contact us to obtain your own key.

You can also include an X-Company-Secret header with the company's secret. This is especially convenient for self-hosted software, but web-based software can use it as well. It is activated upon request and applies to all companies of your account. Each merchant can find their secret inside their Invoice Portal panel and provide it to you.

Company

Pending Order Notes

GET
https://dev.invoiceportal.gr
/api/v2/order-notes/pending
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

vat_number
string
required
Example:
998914851
branch
string
required
Example:
0
table
string
Example:
table #1
Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/order-notes/pending"
);

const params = {
    "vat_number": "998914851",
    "branch": "0",
    "table": "table #1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
Example response:
{
    "data": [
        {
            "table": "table #1",
            "invoices": {
                "uid": "69C235338728CF9E2429E90348E62FF1D357B85C",
                "mark": "400001929261975",
                "authentication_code": "69C235338728CF9E2429E90348E62FF1D357B85C",
                "issue_date": "2024-09-18 14:55:41.000",
                "items": [
                    {
                        "name": "Item Name",
                        "value": "100.00",
                        "quantity": 4,
                        "seller_id": "e7314833-f451-42b7-8f8a-533b78015187"
                    },
                    {
                        "name": "Item 2",
                        "value": "8.00",
                        "quantity": 1,
                        "seller_id": "643379a0-963e-405d-b544-4af3cbaa0372"
                    }
                ]
            }
        }
    ]
}

Invite a company

POST
https://dev.invoiceportal.gr
/api/v2/companies
requires authentication

Create and invite a company to Invoice Portal. You can also assign one or more invoice buckets to the company, so it can start issuing right away.

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/companies"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "[email protected]",
    "vat_number": "801082480",
    "reseller_email": "[email protected]",
    "buckets": [
        {
            "branch": "0",
            "invoices": "1000",
            "expires_at": "2026-09-14T01:02:03Z"
        }
    ],
    "send_email": false,
    "tags": [
        "retail"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "link": "https://invoiceportal.gr/XXXX"
}
{
    "message": "Invalid Vat Number"
}
{
    "message": "Company Already Exists"
}

Update a company

PUT
https://dev.invoiceportal.gr
/api/v2/companies/{vatNumber}
requires authentication

Update the editable fields of a company.

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

vatNumber
string
required
Example:
998914851

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/companies/998914851"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "reseller_email": "[email protected]"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "message": "ok"
}
{
    "message": "Company Not Found"
}

Status

GET
https://dev.invoiceportal.gr
/api/v2/companies/{vatNumber}/status
requires authentication

Get information regarding the current status of a company. The following statuses are available:

  • PENDING: The company hasn't completed the onboarding process.
  • ACTIVE: The company is active and able to issue invoices.
  • SUSPENDED: The company is suspended and cannot issue invoices.
  • BANNED: The company has been banned and is unable to issue invoices

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

vatNumber
string
required
Example:
998914851
Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/companies/998914851/status"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
Example response:
{
    "status": "ACTIVE",
    "onboarding_status": null,
    "reseller_email": "[email protected]",
    "available": 35,
    "used": 20003,
    "capacity": 20038,
    "statement": {
        "b2c": true,
        "b2b": false
    },
    "invoice_provider": {
        "name": "Invoice Portal",
        "site": "https://invoiceportal.gr",
        "license": "2024_07_122BUSINESS CLOUD_001_Invoice Portal_V1_25072024",
        "aade_provider_id": 22
    },
    "buckets": [
        {
            "branch": 0,
            "capacity": 38,
            "available": 35,
            "used": 3,
            "expires_at": "2024-08-10T00:00:00.000000Z",
            "created_at": "2024-07-16T18:27:27.000000Z",
            "updated_at": "2024-08-07T10:10:34.000000Z"
        },
        {
            "branch": null,
            "capacity": 20000,
            "available": 0,
            "used": 20000,
            "expires_at": null,
            "created_at": "2024-07-16T18:27:27.000000Z",
            "updated_at": "2024-07-16T18:27:27.000000Z"
        }
    ]
}
{
    "message": "Not Found"
}

Resend Invitation email

POST
https://dev.invoiceportal.gr
/api/v2/companies/{vatNumber}/resend-email
requires authentication

Resend the invitation email to a company. The company must be in a PENDING status.

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

vatNumber
string
required
Example:
998914851

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/companies/998914851/resend-email"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "[email protected]"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "link": "https://invoiceportal.gr/XXX"
}

Renew Contract

POST
https://dev.invoiceportal.gr
/api/v2/companies/{vatNumber}/renew-contract
requires authentication

Restart the onboarding process of a company, so it can sign a new contract. The company's status is set to PENDING_LINK and the onboarding link is returned.

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

vatNumber
string
required
Example:
998914851

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/companies/998914851/renew-contract"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "send_email": true,
    "email": "[email protected]"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "link": "https://invoiceportal.gr/XXX"
}
{
    "message": "Company Not Found"
}

Assign invoices to a company

POST
https://dev.invoiceportal.gr
/api/v2/companies/{vatNumber}/invoices
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

vatNumber
string
required
Example:
801082480

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/companies/801082480/invoices"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "buckets": [
        {
            "branch": 2,
            "expires_at": "2030-12-31T23:59:59Z",
            "invoices": 1000
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Activate a company

POST
https://dev.invoiceportal.gr
/api/v2/companies/{vatNumber}/activate
requires authentication

Activate a company. The company must have completed the onboarding proccess.

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

vatNumber
string
required
Example:
801082480
Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/companies/801082480/activate"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
Example response:
{
    "message": "ok"
}
{
    "message": "Invalid Vat Number"
}
{
    "message": "Onboarding proccess incomplete"
}

Store Branch

POST
https://dev.invoiceportal.gr
/api/v2/companies/{vatNumber}/branches
requires authentication

Stores a branch of a company. Branches are unique by their serial number. If you store a branch with a serial number that already exists, the existing branch will be updated instead

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

vatNumber
string
required
Example:
998914851

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/companies/998914851/branches"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "serial_number": 1,
    "street": "Mixalakopoulou 38",
    "city": "Athens",
    "zip_code": "99999"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "message": "ok"
}

Invoices

Map a JSON invoice to UBL & AADE xml

POST
https://dev.invoiceportal.gr
/api/v2/transform
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

output
ubl|aade
required

If provided only the selected xml will be returned

Example:
aade

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/transform"
);

const params = {
    "output": "aade",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "uid": "F2B1762EF3380A47FDDD74FC14BD4F9E4FFF12AE",
    "issue_date": "2024-07-26 10:03:16",
    "self_pricing": false,
    "dispatch_date": "2026-09-25 10:00:00",
    "vehicle_number": "ΙΚΤ1234",
    "vat_payment_suspension": false,
    "correlated": [
        400001929722136
    ],
    "comments": "Free text",
    "gross_value": 124,
    "header": {
        "code": "11.1",
        "serial_number": 53,
        "series": "ΤΔΑ-Α",
        "special_invoice_category": 12,
        "is_cancel_order": false,
        "table_name": "A1",
        "non_obligated_recipient": false,
        "without_digital_transport_tracking": false
    },
    "move_purpose": "1",
    "currency": {
        "code": "EUR",
        "exchange_rate": 1
    },
    "issuer": {
        "name": "Some Company",
        "vat_number": "9000000000",
        "tax_office": "ΚΕΦΟΔΕ ΑΤΤΙΚΗΣ - 1190",
        "activity": "ΔΡΑΣΤΗΡΙΟΤΗΤΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ ΗΛΕΚΤΡΟΝΙΚΩΝ ΣΥΣΤΗΜΑΤΩΝ",
        "phone": "+30 2100000000",
        "country": "GR",
        "branch": 0,
        "address": {
            "postal_code": "11528",
            "city": "Αθήνα",
            "number": "10",
            "street": "Μιχαλακοπούλου"
        }
    },
    "counterpart": {
        "name": "Other Company",
        "vat_number": "9000000000",
        "tax_office": "ΦΑΕ ΑΘΗΝΩΝ",
        "activity": "ΕΜΠΟΡΙΟ",
        "phone": "+30 2100000000",
        "country": "GR",
        "branch": 0,
        "address": {
            "postal_code": "10431",
            "city": "Αθήνα",
            "number": "10",
            "street": "Πατησίων"
        }
    },
    "payment_methods": [
        {
            "code": "3",
            "amount": 100
        }
    ],
    "other_correlated_entities": [
        {
            "entity": {
                "name": null,
                "vat_number": null,
                "country": null
            }
        }
    ],
    "details": [
        {
            "line_number": 1,
            "name": "EXAMPLE PRODUCT",
            "code": "00000",
            "not_vat_195": false,
            "detail_type": 1,
            "quantity": 2,
            "price_per_unit": 100,
            "net_value": 200,
            "discount": 0,
            "deductions": 0,
            "tax": {
                "code": "1",
                "value": 48,
                "rate": 24
            },
            "unit": {
                "code": "1",
                "display_name": "ΤΕΜ"
            },
            "other_taxes": {
                "amount": 0
            },
            "stamp_duty": {
                "amount": 0
            },
            "retention_tax": {
                "rate": 0,
                "amount": 0
            },
            "fee": {
                "amount": 0
            },
            "income": [
                {
                    "type": "E3_561_002",
                    "category": "category1_1",
                    "amount": 100
                }
            ]
        }
    ],
    "taxes_totals": [
        {
            "underlying_value": 100,
            "id": 1,
            "tax_type": 1,
            "tax_amount": 4
        }
    ],
    "packings_declarations": [
        {
            "packaging_type": null,
            "quantity": null
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "aade": "**xml file**",
    "peppol": "**xml file**"
}

View Invoice Status

GET
https://dev.invoiceportal.gr
/api/v2/invoices/{uid}
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

URL Parameters

uid
string
required
Example:
D4EB1048870839BCAB165550D388EFBCA2134D54
Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/invoices/D4EB1048870839BCAB165550D388EFBCA2134D54"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
Example response:
{
    "uid": "BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D",
    "authentication_code": "92A60F7464481B1BE2AD203A15E934BE542D786F",
    "mark": "400001929722136",
    "qr": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D/qr",
    "url": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D"
}
[]

Upload Invoice PDF

POST
https://dev.invoiceportal.gr
/api/v2/invoices/{uid}/pdf
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
multipart/form-data
Accept
Example:
application/json

URL Parameters

uid
string
required
Example:
D4EB1048870839BCAB165550D388EFBCA2134D54

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/invoices/D4EB1048870839BCAB165550D388EFBCA2134D54/pdf"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('pdf', document.querySelector('input[name="pdf"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Create a new Invoice (PEPPOL & myDATA)

POST
https://dev.invoiceportal.gr
/api/v2/invoices
requires authentication

Issue a new invoice. This requires two xml files, one according to AADE's spec, and one according to the PEPPOL protocol.
Users can either generate those xml's on the fly themselves, or use our mapping endpoint to generate these files using a more user-friendly json format.

You can use this validator to make sure the PEPPOL Invoice is correct.

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/invoices"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "aade_invoice": "...",
    "peppol_invoice": "...",
    "emails": [
        "[email protected]"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "uid": "BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D",
    "authentication_code": "92A60F7464481B1BE2AD203A15E934BE542D786F",
    "mark": "400001929722136",
    "transmission_failure": null,
    "remaining_invoices": 1000,
    "total_invoices": 3,
    "qr": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D/qr",
    "url": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D"
}
{
    "uid": "BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D",
    "authentication_code": null,
    "mark": null,
    "transmission_failure": "AADE_DOWN",
    "remaining_invoices": 1000,
    "total_invoices": 3,
    "qr": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D/qr",
    "url": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D"
}
{
    "message": "Vat category must have value other than 8 for this invoice type",
    "code": 217
}
{
    "message": "INVALID_COMPANY"
}
{
    "message": "INVALID_SIGNATURE"
}
{
    "message": "DEPLETED_INVOICES"
}

Create a new Invoice

POST
https://dev.invoiceportal.gr
/api/v2/invoices/json
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/invoices/json"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "uid": "F2B1762EF3380A47FDDD74FC14BD4F9E4FFF12AE",
    "issue_date": "2024-07-26 10:03:16",
    "self_pricing": false,
    "dispatch_date": "2026-09-25 10:00:00",
    "vehicle_number": "ΙΚΤ1234",
    "vat_payment_suspension": false,
    "correlated": [
        400001929722136
    ],
    "comments": "Free text",
    "gross_value": 124,
    "header": {
        "code": "11.1",
        "serial_number": 53,
        "series": "ΤΔΑ-Α",
        "special_invoice_category": 12,
        "is_cancel_order": false,
        "table_name": "A1",
        "non_obligated_recipient": false,
        "without_digital_transport_tracking": false
    },
    "move_purpose": "1",
    "currency": {
        "code": "EUR",
        "exchange_rate": 1
    },
    "issuer": {
        "name": "Some Company",
        "vat_number": "9000000000",
        "tax_office": "ΚΕΦΟΔΕ ΑΤΤΙΚΗΣ - 1190",
        "activity": "ΔΡΑΣΤΗΡΙΟΤΗΤΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ ΗΛΕΚΤΡΟΝΙΚΩΝ ΣΥΣΤΗΜΑΤΩΝ",
        "phone": "+30 2100000000",
        "country": "GR",
        "branch": 0,
        "address": {
            "postal_code": "11528",
            "city": "Αθήνα",
            "number": "10",
            "street": "Μιχαλακοπούλου"
        }
    },
    "counterpart": {
        "name": "Other Company",
        "vat_number": "9000000000",
        "tax_office": "ΦΑΕ ΑΘΗΝΩΝ",
        "activity": "ΕΜΠΟΡΙΟ",
        "phone": "+30 2100000000",
        "country": "GR",
        "branch": 0,
        "address": {
            "postal_code": "10431",
            "city": "Αθήνα",
            "number": "10",
            "street": "Πατησίων"
        }
    },
    "payment_methods": [
        {
            "code": "3",
            "amount": 100
        }
    ],
    "other_correlated_entities": [
        {
            "entity": {
                "name": null,
                "vat_number": null,
                "country": null
            }
        }
    ],
    "details": [
        {
            "line_number": 1,
            "name": "EXAMPLE PRODUCT",
            "code": "00000",
            "not_vat_195": false,
            "detail_type": 1,
            "quantity": 2,
            "price_per_unit": 100,
            "net_value": 200,
            "discount": 0,
            "deductions": 0,
            "tax": {
                "code": "1",
                "value": 48,
                "rate": 24
            },
            "unit": {
                "code": "1",
                "display_name": "ΤΕΜ"
            },
            "other_taxes": {
                "amount": 0
            },
            "stamp_duty": {
                "amount": 0
            },
            "retention_tax": {
                "rate": 0,
                "amount": 0
            },
            "fee": {
                "amount": 0
            },
            "income": [
                {
                    "type": "E3_561_002",
                    "category": "category1_1",
                    "amount": 100
                }
            ]
        }
    ],
    "taxes_totals": [
        {
            "underlying_value": 100,
            "id": 1,
            "tax_type": 1,
            "tax_amount": 4
        }
    ],
    "packings_declarations": [
        {
            "packaging_type": null,
            "quantity": null
        }
    ],
    "emails": [
        "[email protected]",
        "[email protected]"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "uid": "BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D",
    "authentication_code": "92A60F7464481B1BE2AD203A15E934BE542D786F",
    "mark": "400001929722136",
    "transmission_failure": null,
    "remaining_invoices": 1000,
    "total_invoices": 3,
    "qr": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D/qr",
    "url": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D",
    "aade_qr": "https://mydataapidev.aade.gr/TimologioQR/QRInfo?q=ztPMXpx5acftaLNTX2BOZOkI3dQiud%2ff5pIbfsxBh50yYizADY%2bsM%2bCzoo2PB5toOtRCfFL6APZAIQd0fUGjMLpCchWxpGxG2Xms6oS8A6o%3d"
}
{
    "uid": "BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D",
    "authentication_code": null,
    "mark": null,
    "transmission_failure": "AADE_DOWN",
    "remaining_invoices": 1000,
    "total_invoices": 3,
    "qr": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D/qr",
    "url": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D",
    "aade_qr": "https://mydataapidev.aade.gr/TimologioQR/QRInfo?q=ztPMXpx5acftaLNTX2BOZOkI3dQiud%2ff5pIbfsxBh50yYizADY%2bsM%2bCzoo2PB5toOtRCfFL6APZAIQd0fUGjMLpCchWxpGxG2Xms6oS8A6o%3d"
}
{
    "message": "INVALID_COMPANY"
}
{
    "message": "INVALID_SIGNATURE"
}
{
    "message": "DEPLETED_INVOICES"
}

Cancel a delivery note

POST
https://dev.invoiceportal.gr
/api/v2/delivery-notes/cancel
requires authentication

Cancels a delivery note, and returns a cancellation mark. Only invoices of type 9.3 can be canceled

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/delivery-notes/cancel"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "issuer_vat_number": "801082480",
    "uid": "C1574181AE8DE7019BB06B0912CD0A37850D5062"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "cancellation_mark": "400001942783398"
}
{
    "code": "251",
    "message": "Invoice with MARK 400001942783398 has already been cancelled"
}

Cancel a receiving note

POST
https://dev.invoiceportal.gr
/api/v2/receiving-notes/cancel
requires authentication

Cancels a receiving note, and returns a cancellation mark. Only invoices of type 10.X can be canceled

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/receiving-notes/cancel"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "issuer_vat_number": "801082480",
    "uid": "C1574181AE8DE7019BB06B0912CD0A37850D5062"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "cancellation_mark": "400001942783398"
}
{
    "code": "251",
    "message": "Invoice with MARK 400001942783398 has already been cancelled"
}

Misc

Calculate UID

POST
https://dev.invoiceportal.gr
/api/v2/uid
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/uid"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "issuer": "998914851",
    "date": "2025-01-01",
    "branch": "0",
    "type": "1.1",
    "series": "A",
    "serial_number": "12345"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "uid": "6937509F49384F7D521CFA1D5FCB65A349662979"
}

Setup webhooks

POST
https://dev.invoiceportal.gr
/api/v2/webhook
requires authentication

Set up a webhook URL for cases where the invoices are sent asynchronously. A webhook key is returned, which will be used as a bearer token in the webhook request headers.

Example webhook request:

{
    "vat_number": "example vat number",
    "successes": [
        { "uid": "XXX", "mark": "YYY", "authentication_code": "YYY"},
        { "uid": "XXX", "mark": "YYY", "authentication_code": "YYY"},
    ],
}

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/webhook"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "url": "https:\/\/example.com\/invoice-portal"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "key": "XXXXX"
}

Payments

Create a new POS payment request

POST
https://dev.invoiceportal.gr
/api/v2/signature
requires authentication

Create a provider signature, used for activating POS devices.
You must also specify the payment provider, since each one requires a different output type.
If your payment includes tip then it must be included in the net_value and gross_value fields.

If the payment is for an invoice that has not yet been issued you can set the mark field to null, otherwise it must be equal to the mark of an existing invoice whose payment methods will be updated.

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/signature"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "issuer": "999999999",
    "uid": "6E7297D2828B1DFF02CE85094AADBCFF0043892C",
    "payment_amount": 124,
    "net_value": 100,
    "vat_amount": 24,
    "gross_value": 124,
    "terminal": "160000000",
    "type": "mellon",
    "mark": "160000000"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "signature": "MEUCIQD6SCJw5mEK5PHDYqrfi+CCIyCfdi4OKk7WODq3YFKB2gIgITLVnyhC9sTrJ4f+WN7FHXoLxe2B5Q9h6IpNyNxZX7o=",
    "data": "6E7297D2828B1DFF02CE85094AADBCFF0043892C;400001929268735;20240625153412;2260;2260;0;2260;160000000",
    "provider_id": "123"
}

Update the payments of an invoice

POST
https://dev.invoiceportal.gr
/api/v2/payments
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/payments"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "mark": 400001929592800,
    "payments": [
        {
            "signature": "MEUCIQDHPN9WXEDWinhbyCyTYf0cH+o66K7OufkuKl3RVMXqcgIgS2UkaK5Gg64T3QWB9CR6MIQMfbHSgbisLxj3VBSSihY=",
            "transaction_id": "9258762217454285091123",
            "tip": 1,
            "paid_amount": 9,
            "code": 7
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "message": "Invalid Signature for Payment index $index"
}

Unsigned Invoices

Initiate an unsigned Invoice (myDATA)

POST
https://dev.invoiceportal.gr
/api/v2/unsigned
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/unsigned"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "aade_invoice": "...",
    "peppol_invoice": "..."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "uid": "BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D",
    "authentication_code": null,
    "mark": "400001929722136",
    "transmission_failure": null,
    "remaining_invoices": 1000,
    "total_invoices": 3,
    "qr": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D/qr",
    "url": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D"
}
{
    "message": "INVALID_COMPANY"
}
{
    "message": "INVALID_SIGNATURE"
}

Initiate an unsigned Invoice (JSON)

POST
https://dev.invoiceportal.gr
/api/v2/unsigned/json
requires authentication

Headers

Authorization
Example:
Bearer {YOUR_AUTH_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
const url = new URL(
    "https://dev.invoiceportal.gr/api/v2/unsigned/json"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "uid": "F2B1762EF3380A47FDDD74FC14BD4F9E4FFF12AE",
    "issue_date": "2024-07-26 10:03:16",
    "self_pricing": false,
    "dispatch_date": "2026-09-25 10:00:00",
    "vehicle_number": "ΙΚΤ1234",
    "vat_payment_suspension": false,
    "correlated": [
        400001929722136
    ],
    "comments": "Free text",
    "gross_value": 124,
    "header": {
        "code": "11.1",
        "serial_number": 53,
        "series": "ΤΔΑ-Α",
        "special_invoice_category": 12,
        "is_cancel_order": false,
        "table_name": "A1",
        "non_obligated_recipient": false,
        "without_digital_transport_tracking": false
    },
    "move_purpose": "1",
    "currency": {
        "code": "EUR",
        "exchange_rate": 1
    },
    "issuer": {
        "name": "Some Company",
        "vat_number": "9000000000",
        "tax_office": "ΚΕΦΟΔΕ ΑΤΤΙΚΗΣ - 1190",
        "activity": "ΔΡΑΣΤΗΡΙΟΤΗΤΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ ΗΛΕΚΤΡΟΝΙΚΩΝ ΣΥΣΤΗΜΑΤΩΝ",
        "phone": "+30 2100000000",
        "country": "GR",
        "branch": 0,
        "address": {
            "postal_code": "11528",
            "city": "Αθήνα",
            "number": "10",
            "street": "Μιχαλακοπούλου"
        }
    },
    "counterpart": {
        "name": "Other Company",
        "vat_number": "9000000000",
        "tax_office": "ΦΑΕ ΑΘΗΝΩΝ",
        "activity": "ΕΜΠΟΡΙΟ",
        "phone": "+30 2100000000",
        "country": "GR",
        "branch": 0,
        "address": {
            "postal_code": "10431",
            "city": "Αθήνα",
            "number": "10",
            "street": "Πατησίων"
        }
    },
    "payment_methods": [
        {
            "code": "3",
            "amount": 100
        }
    ],
    "other_correlated_entities": [
        {
            "entity": {
                "name": null,
                "vat_number": null,
                "country": null
            }
        }
    ],
    "details": [
        {
            "line_number": 1,
            "name": "EXAMPLE PRODUCT",
            "code": "00000",
            "not_vat_195": false,
            "detail_type": 1,
            "quantity": 2,
            "price_per_unit": 100,
            "net_value": 200,
            "discount": 0,
            "deductions": 0,
            "tax": {
                "code": "1",
                "value": 48,
                "rate": 24
            },
            "unit": {
                "code": "1",
                "display_name": "ΤΕΜ"
            },
            "other_taxes": {
                "amount": 0
            },
            "stamp_duty": {
                "amount": 0
            },
            "retention_tax": {
                "rate": 0,
                "amount": 0
            },
            "fee": {
                "amount": 0
            },
            "income": [
                {
                    "type": "E3_561_002",
                    "category": "category1_1",
                    "amount": 100
                }
            ]
        }
    ],
    "taxes_totals": [
        {
            "underlying_value": 100,
            "id": 1,
            "tax_type": 1,
            "tax_amount": 4
        }
    ],
    "packings_declarations": [
        {
            "packaging_type": null,
            "quantity": null
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
Example response:
{
    "uid": "BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D",
    "authentication_code": null,
    "mark": "400001929722136",
    "transmission_failure": null,
    "qr": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D/qr",
    "url": "https://invoiceportal.gr/invoices/2024-BF3C1C867FC4B97DEA1728900F0FD8CFE4E7BA1D"
}
{
    "message": "INVALID_COMPANY"
}
{
    "message": "DEPLETED_INVOICES"
}