e-Faktura API
v1 Guides MK Get started

e-Faktura API

API reference

Base URL https://api.efaktura.merot.com

OAuth

Client-credentials tokens for vendors integrating on behalf of many client companies.

Get a client-credentials access token

#

POST /v1/oauth/token

For vendors: exchange an OAuth client's client_id + client_secret for a short-lived bearer token. This is the only endpoint that does not use an API key, and the only one whose error body is plain OAuth 2.0 JSON (RFC 6749 §5.2) rather than application/problem+json.

Returns

  • 200

    Access token issued.

  • 400

    invalid_client or invalid_scope (RFC 6749 §5.2 error JSON, not problem+json).

cURL
curl -X POST "https://api.efaktura.merot.com/v1/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=mfc_9f2a1c7e0b3d4e5f&client_secret=<client_secret>&scope=einvoices:read einvoices:write inbox:read inbox:write"
const response = await fetch("https://api.efaktura.merot.com/v1/oauth/token", {
  method: "POST",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
  },
  body: new URLSearchParams({
  "grant_type": "client_credentials",
  "client_id": "mfc_9f2a1c7e0b3d4e5f",
  "client_secret": "<client_secret>",
  "scope": "einvoices:read einvoices:write inbox:read inbox:write"
}).toString(),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/oauth/token",
    headers={
    "Content-Type": "application/x-www-form-urlencoded",
    },
    data={
  "grant_type": "client_credentials",
  "client_id": "mfc_9f2a1c7e0b3d4e5f",
  "client_secret": "<client_secret>",
  "scope": "einvoices:read einvoices:write inbox:read inbox:write"
},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/oauth/token', [
    'headers' => [
        'Content-Type' => 'application/x-www-form-urlencoded',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/oauth/token");



using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/oauth/token"))
    .headers("Content-Type", "application/x-www-form-urlencoded")
    .method("POST", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "einvoices:read einvoices:write inbox:read inbox:write"
}

Companies

The client companies (ЕДБ) an API account acts for.

List client companies

#

GET /v1/companies

Parameters

  • cursor (query)string
  • limit (query)integer

    Default: 25

Returns

  • 200

    A page of companies.

  • 401

    Missing, malformed or revoked credentials.

  • 429

    Too many requests.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/companies" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/companies", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/companies",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/companies', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/companies");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/companies"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "data": [
    {
      "id": "cmp_01J9Z3K2N4R5T6V7W8X9Y0Z1",
      "object": "company",
      "name": "Купувач ДОО",
      "taxNumber": "4012009123456",
      "vatNumber": "MK4012009123456",
      "externalRef": "acct_8841",
      "status": "active",
      "signingMode": "bridge",
      "environments": {
        "sandbox": {
          "enabled": true,
          "signerReady": true
        },
        "production": {
          "enabled": false,
          "signerReady": false
        }
      },
      "createdAt": "2026-09-26T09:12:00Z"
    }
  ],
  "nextCursor": null
}

Add a client company

#

POST /v1/companies

Vendors and businesses onboard a client company by its tax number (ЕДБ). The company's legal name and address come from the UJP registry pre-flight — never from the request body. A mandate e-mail is sent to representative.email; the company becomes active once the representative accepts it.

Parameters

  • Idempotency-Key (header)stringrequired

    Required on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.

Request body

  • taxNumberstringrequired

    ЕДБ of the client company.

  • externalRefstring | null

    Your own identifier for this company.

  • signingModeenum
    bridgesdk

    Default: "bridge"

  • representativeobjectrequired
    Show child parametersHide child parameters
    • namestringrequired
    • emailstringrequired

Returns

  • 201

    Company created, pending mandate acceptance.

  • 400

    The request body failed validation.

  • 503

    UJP registry pre-flight unavailable — no company was created.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/companies" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: a-unique-key-per-request" \
  -H "Content-Type: application/json" \
  -d '{
    "taxNumber": "4012009123456",
    "externalRef": "acct_8841",
    "signingMode": "bridge",
    "representative": {
      "name": "Ана Петровска",
      "email": "ana@buyer.mk"
    }
  }'
const response = await fetch("https://api.efaktura.merot.com/v1/companies", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "taxNumber": "4012009123456",
    "externalRef": "acct_8841",
    "signingMode": "bridge",
    "representative": {
      "name": "Ана Петровска",
      "email": "ana@buyer.mk"
    }
  }),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/companies",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
    },
    json={
    "taxNumber": "4012009123456",
    "externalRef": "acct_8841",
    "signingMode": "bridge",
    "representative": {
        "name": "Ана Петровска",
        "email": "ana@buyer.mk"
    }
},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/companies', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Idempotency-Key' => 'a-unique-key-per-request',
        'Content-Type' => 'application/json',
    ],
    'json' => [
    'taxNumber' => '4012009123456',
    'externalRef' => 'acct_8841',
    'signingMode' => 'bridge',
    'representative' => [
        'name' => 'Ана Петровска',
        'email' => 'ana@buyer.mk',
    ],
],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/companies");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
request.Headers.Add("Idempotency-Key", "a-unique-key-per-request");
var json = /* lang=json */ @"{
  ""taxNumber"": ""4012009123456"",
  ""externalRef"": ""acct_8841"",
  ""signingMode"": ""bridge"",
  ""representative"": {
    ""name"": ""Ана Петровска"",
    ""email"": ""ana@buyer.mk""
  }
}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/companies"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Idempotency-Key", "a-unique-key-per-request", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{   \"taxNumber\": \"4012009123456\",   \"externalRef\": \"acct_8841\",   \"signingMode\": \"bridge\",   \"representative\": {     \"name\": \"Ана Петровска\",     \"email\": \"ana@buyer.mk\"   } }"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "id": "cmp_01J9Z3K2N4R5T6V7W8X9Y0Z1",
  "object": "company",
  "name": "Купувач ДОО",
  "taxNumber": "4012009123456",
  "vatNumber": "MK4012009123456",
  "externalRef": "acct_8841",
  "status": "pending_mandate",
  "signingMode": "bridge",
  "environments": {
    "sandbox": {
      "enabled": true,
      "signerReady": false
    },
    "production": {
      "enabled": false,
      "signerReady": false
    }
  },
  "createdAt": "2026-09-26T09:12:00Z"
}

Retrieve a company

#

GET /v1/companies/{id}

Parameters

  • id (path)stringrequired

Returns

  • 200

    The company.

  • 404

    No such resource for this company.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/companies/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/companies/einv_123", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/companies/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/companies/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/companies/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/companies/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "id": "cmp_01J9Z3K2N4R5T6V7W8X9Y0Z1",
  "object": "company",
  "name": "Купувач ДОО",
  "taxNumber": "4012009123456",
  "vatNumber": "MK4012009123456",
  "externalRef": "acct_8841",
  "status": "active",
  "signingMode": "bridge",
  "environments": {
    "sandbox": {
      "enabled": true,
      "signerReady": true
    },
    "production": {
      "enabled": false,
      "signerReady": false
    }
  },
  "createdAt": "2026-09-26T09:12:00Z"
}

Update a company

#

PATCH /v1/companies/{id}

Only externalRef and signingMode may be changed.

Parameters

  • id (path)stringrequired

Request body

  • externalRefstring | null
  • signingModeenum
    bridgesdk

Returns

  • 200

    Updated company.

  • 404

    No such resource for this company.

cURL
curl -X PATCH "https://api.efaktura.merot.com/v1/companies/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "signingMode": "sdk"
  }'
const response = await fetch("https://api.efaktura.merot.com/v1/companies/einv_123", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "signingMode": "sdk"
  }),
});

const data = await response.json();
console.log(data);
import requests

response = requests.patch(
    "https://api.efaktura.merot.com/v1/companies/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    },
    json={
    "signingMode": "sdk"
},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('PATCH', 'https://api.efaktura.merot.com/v1/companies/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Content-Type' => 'application/json',
    ],
    'json' => [
    'signingMode' => 'sdk',
],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Patch, "https://api.efaktura.merot.com/v1/companies/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
var json = /* lang=json */ @"{
  ""signingMode"": ""sdk""
}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/companies/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Content-Type", "application/json")
    .method("PATCH", HttpRequest.BodyPublishers.ofString(/* JSON */ "{   \"signingMode\": \"sdk\" }"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

List e-invoices

#

GET /v1/einvoices

Parameters

  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

  • status (query)enum
    validatinginvalidawaiting_signaturequeuedsubmittingfailedhelddeliveredacceptedauto_acceptedrejectedcancelled_by_stornocorrectedregistereddraft_at_ujp
  • documentType (query)string

    UJP document-type code (e.g. `100` invoice, `110` credit note).

  • issuedFrom (query)string
  • issuedTo (query)string
  • clientReference (query)string
  • euid (query)string
  • cursor (query)string
  • limit (query)integer

    Default: 25

Returns

  • 200

    A page of e-invoices.

  • 401

    Missing, malformed or revoked credentials.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/einvoices" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/einvoices", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/einvoices",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/einvoices', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/einvoices");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/einvoices"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Issue an e-invoice

#

POST /v1/einvoices

Builds the document from your JSON, validates it against the UJP codebooks and the buyer registry, requests a signature from your signing agent, and submits it to UJP. Returns immediately with the document in awaiting_signature or queued state — poll GET /v1/einvoices/{id} or subscribe to einvoice.* webhooks for the outcome.

clientReference makes retries safe: replaying the same clientReference with the same body returns the existing document (200); the same reference with a different body is a conflict (409), even after the Idempotency-Key window has expired.

Parameters

  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

  • Idempotency-Key (header)stringrequired

    Required on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.

Request body

  • clientReferencestringrequired

    Your own idempotent key for this document.

  • documentTypestringrequired

    UJP document-type codebook code (100 invoice, 110 credit note, 130 advance, 150/160 debit/other, ...).

  • numberstringrequired
  • issueDatestringrequired
  • turnoverDatestringrequired
  • deliveryDatestring | null
  • periodStartstring | null
  • periodEndstring | null
  • notesstring | null
  • headerstring | null
  • footerstring | null
  • sellerobject | null

    Only subsidiaryCode/contact/email may be set — the seller's identity always comes from your company.

    Show child parametersHide child parameters
    • subsidiaryCodestring | null
    • contactstring | null
    • emailstring | null
  • buyerobjectrequired
    Show child parametersHide child parameters
    • countrystringrequired

      ISO 3166-1 alpha-2.

    • taxNumberstring | null

      ЕДБ.

    • foreignTaxNumberstring | null
    • vatNumberstring | null
    • namestringrequired
    • addressobjectrequired
      Show child parametersHide child parameters
      • streetstring | null
      • numberstring | null
      • postalCodestring | null
      • citystring | null
    • subsidiaryCodestring | null
    • subsidiaryNamestring | null
    • contactstring | null
    • emailstring | null
  • receiverobject | null
    Show child parametersHide child parameters
    • countrystringrequired

      ISO 3166-1 alpha-2.

    • taxNumberstring | null

      ЕДБ.

    • foreignTaxNumberstring | null
    • vatNumberstring | null
    • namestringrequired
    • addressobjectrequired
      Show child parametersHide child parameters
      • streetstring | null
      • numberstring | null
      • postalCodestring | null
      • citystring | null
    • subsidiaryCodestring | null
    • subsidiaryNamestring | null
    • contactstring | null
    • emailstring | null
  • referencesarray of objectrequired
    Show child parametersHide child parameters
    • typestringrequired

      UJP ref-document-type codebook code.

    • numberstringrequired
    • datestring | null
  • paymentobjectrequired
    Show child parametersHide child parameters
    • typeCodestringrequired
    • dueDatestring | null
    • dueDaysinteger | null
    • termsstring | null
    • notestring | null
    • currencystringrequired
    • exchangeRatestring | null
    • exchangeRateDatestring | null
  • linesarray of objectrequired
    Show child parametersHide child parameters
    • skustring | null
    • descriptionstringrequired
    • unitstring | null
    • quantitystringrequired

      Decimal string.

    • unitPricestringrequired

      A decimal amount as a string, never a JSON number.

    • unitDiscountstring

      A decimal amount as a string, never a JSON number.

    • vatPercentstringrequired

      Decimal string, e.g. "18", "5", "0".

    • taxIndicatorstringrequired

      UJP tax-indicator codebook code.

    • domesticProductboolean | null
  • advanceobject | null
    Show child parametersHide child parameters
    • amountstring

      A decimal amount as a string, never a JSON number.

    • datestring | null
    • descriptionstring | null
  • expectedTotalsobject | null

    Optional — if given and it doesn't match Merot's computed totals, the request fails with 422 totals_mismatch.

    Show child parametersHide child parameters
    • netstring

      A decimal amount as a string, never a JSON number.

    • vatstring

      A decimal amount as a string, never a JSON number.

    • grossstring

      A decimal amount as a string, never a JSON number.

    • currencystring

Returns

  • 200

    Idempotent replay of an identical clientReference — the existing document.

  • 202

    Accepted — document created and queued for signing/submission.

  • 400

    idempotency_key_required — the Idempotency-Key header is missing.

  • 409

    client_reference_conflict — same clientReference, different body.

  • 422

    validation_failed — field-level errors, or totals_mismatch with the computed totals.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/einvoices" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: a-unique-key-per-request" \
  -H "Content-Type: application/json" \
  -d '{
    "clientReference": "inv-2026-000481",
    "documentType": "100",
    "number": "000481",
    "issueDate": "2026-10-08",
    "turnoverDate": "2026-10-08",
    "deliveryDate": null,
    "periodStart": null,
    "periodEnd": null,
    "notes": null,
    "header": null,
    "footer": null,
    "buyer": {
      "country": "MK",
      "taxNumber": "4012009123456",
      "vatNumber": null,
      "name": "Купувач ДОО",
      "address": {
        "street": "Илинденска",
        "number": "1",
        "postalCode": "1000",
        "city": "Скопје"
      },
      "subsidiaryCode": null,
      "subsidiaryName": null,
      "contact": null,
      "email": "faktura@buyer.mk"
    },
    "receiver": null,
    "references": [],
    "payment": {
      "typeCode": "1",
      "currency": "MKD",
      "dueDate": "2026-11-07",
      "dueDays": 30,
      "terms": null,
      "note": null,
      "exchangeRate": null,
      "exchangeRateDate": null
    },
    "lines": [
      {
        "sku": null,
        "description": "Консултантски услуги — септември 2026",
        "unit": "услуга",
        "quantity": "1",
        "unitPrice": "10000.00",
        "unitDiscount": "0",
        "vatPercent": "18",
        "taxIndicator": "1",
        "domesticProduct": null
      }
    ],
    "advance": null,
    "expectedTotals": {
      "net": "10000.00",
      "vat": "1800.00",
      "gross": "11800.00",
      "currency": "MKD"
    }
  }'
const response = await fetch("https://api.efaktura.merot.com/v1/einvoices", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "clientReference": "inv-2026-000481",
    "documentType": "100",
    "number": "000481",
    "issueDate": "2026-10-08",
    "turnoverDate": "2026-10-08",
    "deliveryDate": null,
    "periodStart": null,
    "periodEnd": null,
    "notes": null,
    "header": null,
    "footer": null,
    "buyer": {
      "country": "MK",
      "taxNumber": "4012009123456",
      "vatNumber": null,
      "name": "Купувач ДОО",
      "address": {
        "street": "Илинденска",
        "number": "1",
        "postalCode": "1000",
        "city": "Скопје"
      },
      "subsidiaryCode": null,
      "subsidiaryName": null,
      "contact": null,
      "email": "faktura@buyer.mk"
    },
    "receiver": null,
    "references": [],
    "payment": {
      "typeCode": "1",
      "currency": "MKD",
      "dueDate": "2026-11-07",
      "dueDays": 30,
      "terms": null,
      "note": null,
      "exchangeRate": null,
      "exchangeRateDate": null
    },
    "lines": [
      {
        "sku": null,
        "description": "Консултантски услуги — септември 2026",
        "unit": "услуга",
        "quantity": "1",
        "unitPrice": "10000.00",
        "unitDiscount": "0",
        "vatPercent": "18",
        "taxIndicator": "1",
        "domesticProduct": null
      }
    ],
    "advance": null,
    "expectedTotals": {
      "net": "10000.00",
      "vat": "1800.00",
      "gross": "11800.00",
      "currency": "MKD"
    }
  }),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/einvoices",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
    },
    json={
    "clientReference": "inv-2026-000481",
    "documentType": "100",
    "number": "000481",
    "issueDate": "2026-10-08",
    "turnoverDate": "2026-10-08",
    "deliveryDate": None,
    "periodStart": None,
    "periodEnd": None,
    "notes": None,
    "header": None,
    "footer": None,
    "buyer": {
        "country": "MK",
        "taxNumber": "4012009123456",
        "vatNumber": None,
        "name": "Купувач ДОО",
        "address": {
            "street": "Илинденска",
            "number": "1",
            "postalCode": "1000",
            "city": "Скопје"
        },
        "subsidiaryCode": None,
        "subsidiaryName": None,
        "contact": None,
        "email": "faktura@buyer.mk"
    },
    "receiver": None,
    "references": [],
    "payment": {
        "typeCode": "1",
        "currency": "MKD",
        "dueDate": "2026-11-07",
        "dueDays": 30,
        "terms": None,
        "note": None,
        "exchangeRate": None,
        "exchangeRateDate": None
    },
    "lines": [
        {
            "sku": None,
            "description": "Консултантски услуги — септември 2026",
            "unit": "услуга",
            "quantity": "1",
            "unitPrice": "10000.00",
            "unitDiscount": "0",
            "vatPercent": "18",
            "taxIndicator": "1",
            "domesticProduct": None
        }
    ],
    "advance": None,
    "expectedTotals": {
        "net": "10000.00",
        "vat": "1800.00",
        "gross": "11800.00",
        "currency": "MKD"
    }
},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/einvoices', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Idempotency-Key' => 'a-unique-key-per-request',
        'Content-Type' => 'application/json',
    ],
    'json' => [
    'clientReference' => 'inv-2026-000481',
    'documentType' => '100',
    'number' => '000481',
    'issueDate' => '2026-10-08',
    'turnoverDate' => '2026-10-08',
    'deliveryDate' => null,
    'periodStart' => null,
    'periodEnd' => null,
    'notes' => null,
    'header' => null,
    'footer' => null,
    'buyer' => [
        'country' => 'MK',
        'taxNumber' => '4012009123456',
        'vatNumber' => null,
        'name' => 'Купувач ДОО',
        'address' => [
            'street' => 'Илинденска',
            'number' => '1',
            'postalCode' => '1000',
            'city' => 'Скопје',
        ],
        'subsidiaryCode' => null,
        'subsidiaryName' => null,
        'contact' => null,
        'email' => 'faktura@buyer.mk',
    ],
    'receiver' => null,
    'references' => [],
    'payment' => [
        'typeCode' => '1',
        'currency' => 'MKD',
        'dueDate' => '2026-11-07',
        'dueDays' => 30,
        'terms' => null,
        'note' => null,
        'exchangeRate' => null,
        'exchangeRateDate' => null,
    ],
    'lines' => [
        [
            'sku' => null,
            'description' => 'Консултантски услуги — септември 2026',
            'unit' => 'услуга',
            'quantity' => '1',
            'unitPrice' => '10000.00',
            'unitDiscount' => '0',
            'vatPercent' => '18',
            'taxIndicator' => '1',
            'domesticProduct' => null,
        ],
    ],
    'advance' => null,
    'expectedTotals' => [
        'net' => '10000.00',
        'vat' => '1800.00',
        'gross' => '11800.00',
        'currency' => 'MKD',
    ],
],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/einvoices");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
request.Headers.Add("Idempotency-Key", "a-unique-key-per-request");
var json = /* lang=json */ @"{
  ""clientReference"": ""inv-2026-000481"",
  ""documentType"": ""100"",
  ""number"": ""000481"",
  ""issueDate"": ""2026-10-08"",
  ""turnoverDate"": ""2026-10-08"",
  ""deliveryDate"": null,
  ""periodStart"": null,
  ""periodEnd"": null,
  ""notes"": null,
  ""header"": null,
  ""footer"": null,
  ""buyer"": {
    ""country"": ""MK"",
    ""taxNumber"": ""4012009123456"",
    ""vatNumber"": null,
    ""name"": ""Купувач ДОО"",
    ""address"": {
      ""street"": ""Илинденска"",
      ""number"": ""1"",
      ""postalCode"": ""1000"",
      ""city"": ""Скопје""
    },
    ""subsidiaryCode"": null,
    ""subsidiaryName"": null,
    ""contact"": null,
    ""email"": ""faktura@buyer.mk""
  },
  ""receiver"": null,
  ""references"": [],
  ""payment"": {
    ""typeCode"": ""1"",
    ""currency"": ""MKD"",
    ""dueDate"": ""2026-11-07"",
    ""dueDays"": 30,
    ""terms"": null,
    ""note"": null,
    ""exchangeRate"": null,
    ""exchangeRateDate"": null
  },
  ""lines"": [
    {
      ""sku"": null,
      ""description"": ""Консултантски услуги — септември 2026"",
      ""unit"": ""услуга"",
      ""quantity"": ""1"",
      ""unitPrice"": ""10000.00"",
      ""unitDiscount"": ""0"",
      ""vatPercent"": ""18"",
      ""taxIndicator"": ""1"",
      ""domesticProduct"": null
    }
  ],
  ""advance"": null,
  ""expectedTotals"": {
    ""net"": ""10000.00"",
    ""vat"": ""1800.00"",
    ""gross"": ""11800.00"",
    ""currency"": ""MKD""
  }
}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/einvoices"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Idempotency-Key", "a-unique-key-per-request", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{   \"clientReference\": \"inv-2026-000481\",   \"documentType\": \"100\",   \"number\": \"000481\",   \"issueDate\": \"2026-10-08\",   \"turnoverDate\": \"2026-10-08\",   \"deliveryDate\": null,   \"periodStart\": null,   \"periodEnd\": null,   \"notes\": null,   \"header\": null,   \"footer\": null,   \"buyer\": {     \"country\": \"MK\",     \"taxNumber\": \"4012009123456\",     \"vatNumber\": null,     \"name\": \"Купувач ДОО\",     \"address\": {       \"street\": \"Илинденска\",       \"number\": \"1\",       \"postalCode\": \"1000\",       \"city\": \"Скопје\"     },     \"subsidiaryCode\": null,     \"subsidiaryName\": null,     \"contact\": null,     \"email\": \"faktura@buyer.mk\"   },   \"receiver\": null,   \"references\": [],   \"payment\": {     \"typeCode\": \"1\",     \"currency\": \"MKD\",     \"dueDate\": \"2026-11-07\",     \"dueDays\": 30,     \"terms\": null,     \"note\": null,     \"exchangeRate\": null,     \"exchangeRateDate\": null   },   \"lines\": [     {       \"sku\": null,       \"description\": \"Консултантски услуги — септември 2026\",       \"unit\": \"услуга\",       \"quantity\": \"1\",       \"unitPrice\": \"10000.00\",       \"unitDiscount\": \"0\",       \"vatPercent\": \"18\",       \"taxIndicator\": \"1\",       \"domesticProduct\": null     }   ],   \"advance\": null,   \"expectedTotals\": {     \"net\": \"10000.00\",     \"vat\": \"1800.00\",     \"gross\": \"11800.00\",     \"currency\": \"MKD\"   } }"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Validate an e-invoice without submitting it

#

POST /v1/einvoices/validate

Runs the full UJP rule check and the buyer ЕДБ registry pre-flight. Nothing is sent to UJP.

Parameters

  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

Request body

  • clientReferencestringrequired

    Your own idempotent key for this document.

  • documentTypestringrequired

    UJP document-type codebook code (100 invoice, 110 credit note, 130 advance, 150/160 debit/other, ...).

  • numberstringrequired
  • issueDatestringrequired
  • turnoverDatestringrequired
  • deliveryDatestring | null
  • periodStartstring | null
  • periodEndstring | null
  • notesstring | null
  • headerstring | null
  • footerstring | null
  • sellerobject | null

    Only subsidiaryCode/contact/email may be set — the seller's identity always comes from your company.

    Show child parametersHide child parameters
    • subsidiaryCodestring | null
    • contactstring | null
    • emailstring | null
  • buyerobjectrequired
    Show child parametersHide child parameters
    • countrystringrequired

      ISO 3166-1 alpha-2.

    • taxNumberstring | null

      ЕДБ.

    • foreignTaxNumberstring | null
    • vatNumberstring | null
    • namestringrequired
    • addressobjectrequired
      Show child parametersHide child parameters
      • streetstring | null
      • numberstring | null
      • postalCodestring | null
      • citystring | null
    • subsidiaryCodestring | null
    • subsidiaryNamestring | null
    • contactstring | null
    • emailstring | null
  • receiverobject | null
    Show child parametersHide child parameters
    • countrystringrequired

      ISO 3166-1 alpha-2.

    • taxNumberstring | null

      ЕДБ.

    • foreignTaxNumberstring | null
    • vatNumberstring | null
    • namestringrequired
    • addressobjectrequired
      Show child parametersHide child parameters
      • streetstring | null
      • numberstring | null
      • postalCodestring | null
      • citystring | null
    • subsidiaryCodestring | null
    • subsidiaryNamestring | null
    • contactstring | null
    • emailstring | null
  • referencesarray of objectrequired
    Show child parametersHide child parameters
    • typestringrequired

      UJP ref-document-type codebook code.

    • numberstringrequired
    • datestring | null
  • paymentobjectrequired
    Show child parametersHide child parameters
    • typeCodestringrequired
    • dueDatestring | null
    • dueDaysinteger | null
    • termsstring | null
    • notestring | null
    • currencystringrequired
    • exchangeRatestring | null
    • exchangeRateDatestring | null
  • linesarray of objectrequired
    Show child parametersHide child parameters
    • skustring | null
    • descriptionstringrequired
    • unitstring | null
    • quantitystringrequired

      Decimal string.

    • unitPricestringrequired

      A decimal amount as a string, never a JSON number.

    • unitDiscountstring

      A decimal amount as a string, never a JSON number.

    • vatPercentstringrequired

      Decimal string, e.g. "18", "5", "0".

    • taxIndicatorstringrequired

      UJP tax-indicator codebook code.

    • domesticProductboolean | null
  • advanceobject | null
    Show child parametersHide child parameters
    • amountstring

      A decimal amount as a string, never a JSON number.

    • datestring | null
    • descriptionstring | null
  • expectedTotalsobject | null

    Optional — if given and it doesn't match Merot's computed totals, the request fails with 422 totals_mismatch.

    Show child parametersHide child parameters
    • netstring

      A decimal amount as a string, never a JSON number.

    • vatstring

      A decimal amount as a string, never a JSON number.

    • grossstring

      A decimal amount as a string, never a JSON number.

    • currencystring

Returns

  • 200

    Valid — computed totals and any non-blocking warnings.

  • 422

    validation_failed — field-level errors, or totals_mismatch with the computed totals.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/einvoices/validate" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/einvoices/validate", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/einvoices/validate",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/einvoices/validate', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/einvoices/validate");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/einvoices/validate"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "valid": true,
  "totals": {
    "net": "10000.00",
    "vat": "1800.00",
    "gross": "11800.00",
    "currency": "MKD"
  },
  "warnings": []
}

Retrieve an e-invoice

#

GET /v1/einvoices/{id}

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

Returns

  • 200

    The e-invoice.

  • 404

    No such resource for this company.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/einvoices/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/einvoices/einv_123", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/einvoices/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/einvoices/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/einvoices/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/einvoices/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "id": "einv_01J9Z4M2N3P4Q5R6S7T8U9V0",
  "object": "einvoice",
  "companyId": "cmp_01J9Z3K2N4R5T6V7W8X9Y0Z1",
  "environment": "sandbox",
  "direction": "outbound",
  "clientReference": "inv-2026-000481",
  "documentType": "100",
  "storno": "none",
  "number": "000481",
  "issueDate": "2026-10-08",
  "status": "delivered",
  "ujpStatus": {
    "code": "01",
    "name": "Delivered",
    "at": "2026-10-08T09:31:04Z"
  },
  "euid": "MK-SB-2026-000481",
  "qrLink": "https://efakturatest.ujp.gov.mk/…",
  "ujpTimestamp": "2026-10-08T09:31:04Z",
  "recipientIsEInvoiceUser": true,
  "totals": {
    "net": "10000.00",
    "vat": "1800.00",
    "gross": "11800.00",
    "currency": "MKD"
  },
  "originalId": null,
  "stornoIds": [],
  "correctedById": null,
  "signing": {
    "state": "signed",
    "requestId": "sr_01J9Z4H1G2F3E4D5C6B7A8Z9",
    "expiresAt": null
  },
  "problems": null,
  "issuedInOutage": false,
  "createdAt": "2026-10-08T09:30:41Z",
  "updatedAt": "2026-10-08T09:31:04Z"
}

Status history

#

GET /v1/einvoices/{id}/status-history

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

Returns

  • 200

    Ordered status events.

  • 404

    No such resource for this company.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/einvoices/einv_123/status-history" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/einvoices/einv_123/status-history", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/einvoices/einv_123/status-history",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/einvoices/einv_123/status-history', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/einvoices/einv_123/status-history");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/einvoices/einv_123/status-history"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "data": [
    {
      "code": "01",
      "name": "Delivered",
      "at": "2026-10-08T09:31:04Z",
      "source": "send",
      "rejectReason": null,
      "comment": null
    },
    {
      "code": "04",
      "name": "Auto-accepted",
      "at": "2026-11-10T00:05:00Z",
      "source": "changes",
      "rejectReason": null,
      "comment": null
    }
  ]
}

Force a status refresh from UJP

#

POST /v1/einvoices/{id}/refresh-status

Requires your signing agent to be online (a read-purpose signature is needed to poll UJP).

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

Returns

  • 200

    The e-invoice with its current status.

  • 409

    signing_agent_unavailable — no signing agent responded in time.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/einvoices/einv_123/refresh-status" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/einvoices/einv_123/refresh-status", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/einvoices/einv_123/refresh-status",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/einvoices/einv_123/refresh-status', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/einvoices/einv_123/refresh-status");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/einvoices/einv_123/refresh-status"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("POST", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Storno (void) an e-invoice

#

POST /v1/einvoices/{id}/storno

Creates a new document with docStorno: 1, a void reason (codebook S-x) and a mirrored reference to the original EUID. Allowed only from delivered, accepted or auto_accepted.

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

  • Idempotency-Key (header)stringrequired

    Required on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.

Request body

  • clientReferencestringrequired
  • numberstringrequired
  • issueDatestringrequired
  • reasonCodestringrequired

    UJP void-reason codebook code (S-x).

  • commentstring | null

Returns

  • 202

    Storno document created.

  • 409

    period_closed or invalid source status for storno.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/einvoices/einv_123/storno" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: a-unique-key-per-request" \
  -H "Content-Type: application/json" \
  -d '{
    "clientReference": "inv-2026-000481-storno",
    "number": "ST-000481",
    "issueDate": "2026-10-09",
    "reasonCode": "S-1",
    "comment": "Issued in error"
  }'
const response = await fetch("https://api.efaktura.merot.com/v1/einvoices/einv_123/storno", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "clientReference": "inv-2026-000481-storno",
    "number": "ST-000481",
    "issueDate": "2026-10-09",
    "reasonCode": "S-1",
    "comment": "Issued in error"
  }),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/einvoices/einv_123/storno",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
    },
    json={
    "clientReference": "inv-2026-000481-storno",
    "number": "ST-000481",
    "issueDate": "2026-10-09",
    "reasonCode": "S-1",
    "comment": "Issued in error"
},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/einvoices/einv_123/storno', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Idempotency-Key' => 'a-unique-key-per-request',
        'Content-Type' => 'application/json',
    ],
    'json' => [
    'clientReference' => 'inv-2026-000481-storno',
    'number' => 'ST-000481',
    'issueDate' => '2026-10-09',
    'reasonCode' => 'S-1',
    'comment' => 'Issued in error',
],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/einvoices/einv_123/storno");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
request.Headers.Add("Idempotency-Key", "a-unique-key-per-request");
var json = /* lang=json */ @"{
  ""clientReference"": ""inv-2026-000481-storno"",
  ""number"": ""ST-000481"",
  ""issueDate"": ""2026-10-09"",
  ""reasonCode"": ""S-1"",
  ""comment"": ""Issued in error""
}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/einvoices/einv_123/storno"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Idempotency-Key", "a-unique-key-per-request", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{   \"clientReference\": \"inv-2026-000481-storno\",   \"number\": \"ST-000481\",   \"issueDate\": \"2026-10-09\",   \"reasonCode\": \"S-1\",   \"comment\": \"Issued in error\" }"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Correct an e-invoice

#

POST /v1/einvoices/{id}/correction

Creates a full replacement document with docStorno: 2 and a correction reason (codebook C0x).

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

  • Idempotency-Key (header)stringrequired

    Required on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.

Request body

  • reasonCodestringrequired

    UJP correction-reason codebook code (C0x).

  • commentstring | null
  • replacementobjectrequired
    Show child parametersHide child parameters
    • clientReferencestringrequired

      Your own idempotent key for this document.

    • documentTypestringrequired

      UJP document-type codebook code (100 invoice, 110 credit note, 130 advance, 150/160 debit/other, ...).

    • numberstringrequired
    • issueDatestringrequired
    • turnoverDatestringrequired
    • deliveryDatestring | null
    • periodStartstring | null
    • periodEndstring | null
    • notesstring | null
    • headerstring | null
    • footerstring | null
    • sellerobject | null

      Only subsidiaryCode/contact/email may be set — the seller's identity always comes from your company.

      Show child parametersHide child parameters
      • subsidiaryCodestring | null
      • contactstring | null
      • emailstring | null
    • buyerobjectrequired
      Show child parametersHide child parameters
      • countrystringrequired

        ISO 3166-1 alpha-2.

      • taxNumberstring | null

        ЕДБ.

      • foreignTaxNumberstring | null
      • vatNumberstring | null
      • namestringrequired
      • addressobjectrequired
        Show child parametersHide child parameters
        • streetstring | null
        • numberstring | null
        • postalCodestring | null
        • citystring | null
      • subsidiaryCodestring | null
      • subsidiaryNamestring | null
      • contactstring | null
      • emailstring | null
    • receiverobject | null
      Show child parametersHide child parameters
      • countrystringrequired

        ISO 3166-1 alpha-2.

      • taxNumberstring | null

        ЕДБ.

      • foreignTaxNumberstring | null
      • vatNumberstring | null
      • namestringrequired
      • addressobjectrequired
        Show child parametersHide child parameters
        • streetstring | null
        • numberstring | null
        • postalCodestring | null
        • citystring | null
      • subsidiaryCodestring | null
      • subsidiaryNamestring | null
      • contactstring | null
      • emailstring | null
    • referencesarray of objectrequired
      Show child parametersHide child parameters
      • typestringrequired

        UJP ref-document-type codebook code.

      • numberstringrequired
      • datestring | null
    • paymentobjectrequired
      Show child parametersHide child parameters
      • typeCodestringrequired
      • dueDatestring | null
      • dueDaysinteger | null
      • termsstring | null
      • notestring | null
      • currencystringrequired
      • exchangeRatestring | null
      • exchangeRateDatestring | null
    • linesarray of objectrequired
      Show child parametersHide child parameters
      • skustring | null
      • descriptionstringrequired
      • unitstring | null
      • quantitystringrequired

        Decimal string.

      • unitPricestringrequired

        A decimal amount as a string, never a JSON number.

      • unitDiscountstring

        A decimal amount as a string, never a JSON number.

      • vatPercentstringrequired

        Decimal string, e.g. "18", "5", "0".

      • taxIndicatorstringrequired

        UJP tax-indicator codebook code.

      • domesticProductboolean | null
    • advanceobject | null
      Show child parametersHide child parameters
      • amountstring

        A decimal amount as a string, never a JSON number.

      • datestring | null
      • descriptionstring | null
    • expectedTotalsobject | null

      Optional — if given and it doesn't match Merot's computed totals, the request fails with 422 totals_mismatch.

      Show child parametersHide child parameters
      • netstring

        A decimal amount as a string, never a JSON number.

      • vatstring

        A decimal amount as a string, never a JSON number.

      • grossstring

        A decimal amount as a string, never a JSON number.

      • currencystring

Returns

  • 202

    Correction document created.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/einvoices/einv_123/correction" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: a-unique-key-per-request" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/einvoices/einv_123/correction", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/einvoices/einv_123/correction",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/einvoices/einv_123/correction', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Idempotency-Key' => 'a-unique-key-per-request',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/einvoices/einv_123/correction");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
request.Headers.Add("Idempotency-Key", "a-unique-key-per-request");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/einvoices/einv_123/correction"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Idempotency-Key", "a-unique-key-per-request", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Download the UJP PDF rendering

#

GET /v1/einvoices/{id}/pdf

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

Returns

  • 200

    The PDF (UJP's rendering, archived by Merot).

  • 409

    pdf_not_ready — the document has not settled at UJP yet.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/einvoices/einv_123/pdf" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/einvoices/einv_123/pdf", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/einvoices/einv_123/pdf",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/einvoices/einv_123/pdf', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/einvoices/einv_123/pdf");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/einvoices/einv_123/pdf"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response

application/pdf — binary/file response, no JSON body to preview.

List incoming e-invoices

#

GET /v1/inbox

Parameters

  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

  • status (query)enum
    pendingacceptedauto_acceptedrejected
  • deadlineBefore (query)string
  • cursor (query)string

Returns

  • 200

    A page of inbox documents.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/inbox" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/inbox", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/inbox",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/inbox', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/inbox");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/inbox"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "data": [
    {
      "id": "inbd_01J9Z5A2B3C4D5E6F7G8H9J0",
      "object": "inbox_document",
      "companyId": "cmp_01J9Z3K2N4R5T6V7W8X9Y0Z1",
      "euid": "MK-SB-2026-000512",
      "documentType": "100",
      "number": "SL-000512",
      "issueDate": "2026-10-09",
      "transactionDate": "2026-10-09",
      "seller": {
        "country": "MK",
        "taxNumber": "4030007636033",
        "vatNumber": null,
        "name": "Добавувач ДООЕЛ",
        "address": {
          "street": "Партизанска",
          "number": "12",
          "postalCode": "1000",
          "city": "Скопје"
        },
        "subsidiaryCode": null,
        "subsidiaryName": null,
        "contact": null,
        "email": null
      },
      "totals": {
        "net": "5000.00",
        "vat": "900.00",
        "gross": "5900.00",
        "currency": "MKD"
      },
      "ujpStatus": {
        "code": "00",
        "name": "Received",
        "at": "2026-10-09T14:02:11Z"
      },
      "decision": {
        "state": "pending",
        "reasonCode": null,
        "comment": null,
        "decidedAt": null
      },
      "decideBy": "2026-11-10",
      "daysLeft": 32,
      "receivedAt": "2026-10-09T14:02:11Z",
      "links": {
        "payload": "/v1/inbox/inbd_01J9Z5A2B3C4D5E6F7G8H9J0/payload",
        "pdf": "/v1/inbox/inbd_01J9Z5A2B3C4D5E6F7G8H9J0/pdf"
      }
    }
  ]
}

Retrieve an incoming e-invoice

#

GET /v1/inbox/{id}

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

Returns

  • 200

    The inbox document.

  • 404

    No such resource for this company.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/inbox/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/inbox/einv_123", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/inbox/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/inbox/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/inbox/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/inbox/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "id": "inbd_01J9Z5A2B3C4D5E6F7G8H9J0",
  "object": "inbox_document",
  "companyId": "cmp_01J9Z3K2N4R5T6V7W8X9Y0Z1",
  "euid": "MK-SB-2026-000512",
  "documentType": "100",
  "number": "SL-000512",
  "issueDate": "2026-10-09",
  "transactionDate": "2026-10-09",
  "seller": {
    "country": "MK",
    "taxNumber": "4030007636033",
    "vatNumber": null,
    "name": "Добавувач ДООЕЛ",
    "address": {
      "street": "Партизанска",
      "number": "12",
      "postalCode": "1000",
      "city": "Скопје"
    },
    "subsidiaryCode": null,
    "subsidiaryName": null,
    "contact": null,
    "email": null
  },
  "totals": {
    "net": "5000.00",
    "vat": "900.00",
    "gross": "5900.00",
    "currency": "MKD"
  },
  "ujpStatus": {
    "code": "00",
    "name": "Received",
    "at": "2026-10-09T14:02:11Z"
  },
  "decision": {
    "state": "pending",
    "reasonCode": null,
    "comment": null,
    "decidedAt": null
  },
  "decideBy": "2026-11-10",
  "daysLeft": 32,
  "receivedAt": "2026-10-09T14:02:11Z",
  "links": {
    "payload": "/v1/inbox/inbd_01J9Z5A2B3C4D5E6F7G8H9J0/payload",
    "pdf": "/v1/inbox/inbd_01J9Z5A2B3C4D5E6F7G8H9J0/pdf"
  }
}

Accept an incoming e-invoice

#

POST /v1/inbox/{id}/accept

Silence until the 10th of the month after the transaction date is also acceptance (UJP auto-accepts it) — see Document lifecycle. Accepting explicitly needs no reason.

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

  • Idempotency-Key (header)stringrequired

    Required on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.

Request body

  • commentstring | null

Returns

  • 202

    Decision recorded (pending your signing agent's signature).

  • 409

    decision_deadline_passed — the 10th has already passed (UJP auto-accepted it).

cURL
curl -X POST "https://api.efaktura.merot.com/v1/inbox/einv_123/accept" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: a-unique-key-per-request" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/inbox/einv_123/accept", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/inbox/einv_123/accept",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/inbox/einv_123/accept', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Idempotency-Key' => 'a-unique-key-per-request',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/inbox/einv_123/accept");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
request.Headers.Add("Idempotency-Key", "a-unique-key-per-request");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/inbox/einv_123/accept"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Idempotency-Key", "a-unique-key-per-request", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Reject an incoming e-invoice

#

POST /v1/inbox/{id}/reject

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

  • Idempotency-Key (header)stringrequired

    Required on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.

Request body

  • reasonCodestringrequired

    UJP reject-reason codebook code (O-1…O-7).

  • commentstring | null

Returns

  • 202

    Decision recorded.

  • 409

    decision_deadline_passed

cURL
curl -X POST "https://api.efaktura.merot.com/v1/inbox/einv_123/reject" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: a-unique-key-per-request" \
  -H "Content-Type: application/json" \
  -d '{
    "reasonCode": "O-3",
    "comment": "Goods not received"
  }'
const response = await fetch("https://api.efaktura.merot.com/v1/inbox/einv_123/reject", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "reasonCode": "O-3",
    "comment": "Goods not received"
  }),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/inbox/einv_123/reject",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Idempotency-Key": "a-unique-key-per-request",
    "Content-Type": "application/json",
    },
    json={
    "reasonCode": "O-3",
    "comment": "Goods not received"
},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/inbox/einv_123/reject', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Idempotency-Key' => 'a-unique-key-per-request',
        'Content-Type' => 'application/json',
    ],
    'json' => [
    'reasonCode' => 'O-3',
    'comment' => 'Goods not received',
],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/inbox/einv_123/reject");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
request.Headers.Add("Idempotency-Key", "a-unique-key-per-request");
var json = /* lang=json */ @"{
  ""reasonCode"": ""O-3"",
  ""comment"": ""Goods not received""
}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/inbox/einv_123/reject"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Idempotency-Key", "a-unique-key-per-request", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{   \"reasonCode\": \"O-3\",   \"comment\": \"Goods not received\" }"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Download the exact UJP JSON payload

#

GET /v1/inbox/{id}/payload

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

Returns

  • 200

    The seller's original document JSON, unmodified.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/inbox/einv_123/payload" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/inbox/einv_123/payload", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/inbox/einv_123/payload",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/inbox/einv_123/payload', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/inbox/einv_123/payload");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/inbox/einv_123/payload"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Archive

The 10-year WORM archive of every sent and received document.

List the archived artefacts for a document

#

GET /v1/archive/einvoices/{id}

Accepts either an outbound or an inbound document id.

Parameters

  • id (path)stringrequired
  • X-Company-Id (header)string

    Required when your key/token has access to more than one company.

Returns

  • 200

    The document's artefacts.

  • 404

    No such resource for this company.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/archive/einvoices/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/archive/einvoices/einv_123", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/archive/einvoices/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/archive/einvoices/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/archive/einvoices/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/archive/einvoices/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "items": [
    {
      "kind": "json",
      "sha256": "9f2b...a01c",
      "size": 2140,
      "contentType": "application/json",
      "retainUntil": "2036-10-08",
      "url": "https://archive.efaktura.merot.com/…?X-Amz-Expires=900"
    }
  ]
}

Request a bulk archive export

#

POST /v1/archive/exports

Request body

  • environmentenumrequired
    sandboxproduction
  • directionenum | null
    outboundinbound
  • issuedFromstringrequired
  • issuedTostringrequired
  • kindsarray of enum

Returns

  • 202

    Export queued.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/archive/exports" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/archive/exports", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/archive/exports",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/archive/exports', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/archive/exports");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/archive/exports"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Get an archive export

#

GET /v1/archive/exports/{id}

The ZIP contains a manifest.json listing every file's sha256, EUID and document number. Expires 7 days after it becomes ready.

Parameters

  • id (path)stringrequired

Returns

  • 200

    The export status (and download URL once ready).

cURL
curl -X GET "https://api.efaktura.merot.com/v1/archive/exports/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/archive/exports/einv_123", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/archive/exports/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/archive/exports/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/archive/exports/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/archive/exports/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

List webhook endpoints

#

GET /v1/webhook-endpoints

Returns

  • 200

    A list of webhook endpoints.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/webhook-endpoints" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/webhook-endpoints", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/webhook-endpoints",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/webhook-endpoints', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/webhook-endpoints");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/webhook-endpoints"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Create a webhook endpoint

#

POST /v1/webhook-endpoints

Request body

  • urlstringrequired

    Must be https in production.

  • eventsarray of enumrequired
  • companyIdsarray of string | null
  • descriptionstring | null

Returns

  • 201

    Endpoint created. The signing secret is shown once.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/webhook-endpoints" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/merot-efaktura",
    "events": [
      "einvoice.submitted",
      "einvoice.rejected",
      "inbox.received",
      "inbox.deadline_approaching"
    ]
  }'
const response = await fetch("https://api.efaktura.merot.com/v1/webhook-endpoints", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "url": "https://example.com/hooks/merot-efaktura",
    "events": [
      "einvoice.submitted",
      "einvoice.rejected",
      "inbox.received",
      "inbox.deadline_approaching"
    ]
  }),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/webhook-endpoints",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    },
    json={
    "url": "https://example.com/hooks/merot-efaktura",
    "events": [
        "einvoice.submitted",
        "einvoice.rejected",
        "inbox.received",
        "inbox.deadline_approaching"
    ]
},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/webhook-endpoints', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Content-Type' => 'application/json',
    ],
    'json' => [
    'url' => 'https://example.com/hooks/merot-efaktura',
    'events' => [
        'einvoice.submitted',
        'einvoice.rejected',
        'inbox.received',
        'inbox.deadline_approaching',
    ],
],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/webhook-endpoints");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
var json = /* lang=json */ @"{
  ""url"": ""https://example.com/hooks/merot-efaktura"",
  ""events"": [
    ""einvoice.submitted"",
    ""einvoice.rejected"",
    ""inbox.received"",
    ""inbox.deadline_approaching""
  ]
}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/webhook-endpoints"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{   \"url\": \"https://example.com/hooks/merot-efaktura\",   \"events\": [     \"einvoice.submitted\",     \"einvoice.rejected\",     \"inbox.received\",     \"inbox.deadline_approaching\"   ] }"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "id": "we_01J9Z4A1B2C3D4E5F6G7H8",
  "url": "https://example.com/hooks/merot-efaktura",
  "events": [
    "einvoice.submitted",
    "einvoice.rejected",
    "inbox.received",
    "inbox.deadline_approaching"
  ],
  "companyIds": null,
  "status": "enabled",
  "secret": "whsec_5f2a...c9e1",
  "createdAt": "2026-09-26T09:00:00Z"
}

Retrieve a webhook endpoint

#

GET /v1/webhook-endpoints/{id}

Parameters

  • id (path)stringrequired

Returns

  • 200

    The webhook endpoint.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Update a webhook endpoint

#

PATCH /v1/webhook-endpoints/{id}

Parameters

  • id (path)stringrequired

Request body

  • urlstring
  • eventsarray of enum
  • companyIdsarray of string | null
  • descriptionstring | null

Returns

  • 200

    Updated webhook endpoint.

cURL
curl -X PATCH "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.patch(
    "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('PATCH', 'https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Patch, "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Content-Type", "application/json")
    .method("PATCH", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Disable a webhook endpoint

#

DELETE /v1/webhook-endpoints/{id}

Sets the endpoint to disabled_by_user; it stops receiving new deliveries.

Parameters

  • id (path)stringrequired

Returns

  • 204

    Disabled.

cURL
curl -X DELETE "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123", {
  method: "DELETE",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.delete(
    "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Delete, "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("DELETE", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Rotate a webhook endpoint's signing secret

#

POST /v1/webhook-endpoints/{id}/rotate-secret

The old secret keeps signing deliveries for 24 hours alongside the new one (two v1= entries on Merot-Signature).

Parameters

  • id (path)stringrequired

Returns

  • 200

    New secret.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/rotate-secret" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/rotate-secret", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/rotate-secret",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/rotate-secret', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/rotate-secret");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/rotate-secret"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("POST", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Send a test ping event

#

POST /v1/webhook-endpoints/{id}/test

Parameters

  • id (path)stringrequired

Returns

  • 202

    Ping queued for delivery.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/test" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/test", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/test",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/test', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/test");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/test"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("POST", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

List delivery attempts for an endpoint

#

GET /v1/webhook-endpoints/{id}/deliveries

Parameters

  • id (path)stringrequired
  • state (query)enum
    pendingsucceededfailedabandoned
  • cursor (query)string

Returns

  • 200

    A page of deliveries.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/deliveries" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/deliveries", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/deliveries",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/deliveries', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/deliveries");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/deliveries"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

List events

#

GET /v1/events

Events are retained for 30 days.

Parameters

  • type (query)enum
    einvoice.validated_failedeinvoice.signature_requiredeinvoice.submittedeinvoice.acceptedeinvoice.auto_acceptedeinvoice.rejectedeinvoice.cancelled_by_stornoeinvoice.correctedeinvoice.failedinbox.receivedinbox.deadline_approachinginbox.auto_acceptedsigning_agent.offlinesigning_agent.onlinearchive.export_ready
  • createdFrom (query)string
  • cursor (query)string

Returns

  • 200

    A page of events.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/events" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/events", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/events",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/events', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/events");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/events"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Retrieve an event

#

GET /v1/events/{id}

Parameters

  • id (path)stringrequired

Returns

  • 200

    The event.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/events/einv_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/events/einv_123", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/events/einv_123",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/events/einv_123', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/events/einv_123");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/events/einv_123"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Replay an event

#

POST /v1/events/{id}/replay

Parameters

  • id (path)stringrequired

Request body

  • endpointIdstring | null

    Replay to one endpoint only; omit to replay to all subscribed endpoints.

Returns

  • 202

    A new delivery was queued (is_replay: true).

cURL
curl -X POST "https://api.efaktura.merot.com/v1/events/einv_123/replay" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/events/einv_123/replay", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/events/einv_123/replay",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/events/einv_123/replay', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/events/einv_123/replay");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/events/einv_123/replay"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Pair a Merot Bridge or SDK signing worker

#

POST /v1/agents/pair

Exchanges a one-time, 10-minute pairing code (generated in the console) for agent credentials. Called by Merot Bridge or the SDK's SigningWorker, not typically by your own code directly.

Request body

  • codestringrequired
  • kindenumrequired
    bridgesdk
  • namestringrequired
  • platformenum | null
    windowsmacoslinuxserver
  • versionstring | null
  • publicKeyJwkobjectrequired

    The agent's Ed25519 device key (OKP).

Returns

  • 200

    Agent credentials — shown once.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/agents/pair" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/agents/pair", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/agents/pair",
    headers={
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/agents/pair', [
    'headers' => [
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/agents/pair");

var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/agents/pair"))
    .headers("Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Register a signing certificate for an agent

#

POST /v1/agents/{id}/certificates

Parameters

  • id (path)stringrequired

Request body

  • certificateDerstringrequired

    Base64-encoded DER certificate.

  • companyIdstringrequired

Returns

  • 201

    Certificate registered and linked to the company.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/agents/einv_123/certificates" \
  -H "Authorization: Agent AGENT_ID.AGENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/agents/einv_123/certificates", {
  method: "POST",
  headers: {
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/agents/einv_123/certificates",
    headers={
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/agents/einv_123/certificates', [
    'headers' => [
        'Authorization' => 'Agent AGENT_ID.AGENT_SECRET',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/agents/einv_123/certificates");
request.Headers.Add("Authorization", "Agent AGENT_ID.AGENT_SECRET");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/agents/einv_123/certificates"))
    .headers("Authorization", "Agent AGENT_ID.AGENT_SECRET", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Long-poll pending signing requests (WebSocket fallback)

#

GET /v1/agents/{id}/signing-requests

Merot Bridge normally receives signing requests over a wss:// connection at this same path; this long-poll form is the fallback for networks that block WebSockets.

Parameters

  • id (path)stringrequired
  • wait (query)integer

    Default: 25

Returns

  • 200

    Pending signing requests for this agent.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/agents/einv_123/signing-requests" \
  -H "Authorization: Agent AGENT_ID.AGENT_SECRET"
const response = await fetch("https://api.efaktura.merot.com/v1/agents/einv_123/signing-requests", {
  method: "GET",
  headers: {
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/agents/einv_123/signing-requests",
    headers={
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/agents/einv_123/signing-requests', [
    'headers' => [
        'Authorization' => 'Agent AGENT_ID.AGENT_SECRET',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/agents/einv_123/signing-requests");
request.Headers.Add("Authorization", "Agent AGENT_ID.AGENT_SECRET");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/agents/einv_123/signing-requests"))
    .headers("Authorization", "Agent AGENT_ID.AGENT_SECRET")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

List pending signing requests (Mode B inline signing)

#

GET /v1/signing-requests

Parameters

  • state (query)enum
    pending
  • companyId (query)string

Returns

  • 200

    Pending signing requests.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/signing-requests" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/signing-requests", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/signing-requests",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/signing-requests', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/signing-requests");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/signing-requests"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Retrieve a signing request

#

GET /v1/signing-requests/{id}

Parameters

  • id (path)stringrequired

Returns

  • 200

    The signing request.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/signing-requests/einv_123" \
  -H "Authorization: Agent AGENT_ID.AGENT_SECRET"
const response = await fetch("https://api.efaktura.merot.com/v1/signing-requests/einv_123", {
  method: "GET",
  headers: {
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/signing-requests/einv_123",
    headers={
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/signing-requests/einv_123', [
    'headers' => [
        'Authorization' => 'Agent AGENT_ID.AGENT_SECRET',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/signing-requests/einv_123");
request.Headers.Add("Authorization", "Agent AGENT_ID.AGENT_SECRET");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/signing-requests/einv_123"))
    .headers("Authorization", "Agent AGENT_ID.AGENT_SECRET")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Claim a signing request

#

POST /v1/signing-requests/{id}/claim

Parameters

  • id (path)stringrequired

Returns

  • 200

    Claimed.

  • 409

    already_claimed

cURL
curl -X POST "https://api.efaktura.merot.com/v1/signing-requests/einv_123/claim" \
  -H "Authorization: Agent AGENT_ID.AGENT_SECRET"
const response = await fetch("https://api.efaktura.merot.com/v1/signing-requests/einv_123/claim", {
  method: "POST",
  headers: {
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/signing-requests/einv_123/claim",
    headers={
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/signing-requests/einv_123/claim', [
    'headers' => [
        'Authorization' => 'Agent AGENT_ID.AGENT_SECRET',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/signing-requests/einv_123/claim");
request.Headers.Add("Authorization", "Agent AGENT_ID.AGENT_SECRET");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/signing-requests/einv_123/claim"))
    .headers("Authorization", "Agent AGENT_ID.AGENT_SECRET")
    .method("POST", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Submit a signature

#

POST /v1/signing-requests/{id}/signature

The agent computes RS256 over base64url(header).base64url(payload) and returns the compact JWS. Also usable by a Mode B API key with the signing:agent scope for inline signing.

Parameters

  • id (path)stringrequired

Request body

  • jwsstringrequired

    Compact JWS (header.payload.signature).

Returns

  • 200

    Signature accepted.

  • 410

    signature_expired — a new signing request has been issued.

  • 422

    signature_invalid, payload_mismatch or certificate_mismatch.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/signing-requests/einv_123/signature" \
  -H "Authorization: Agent AGENT_ID.AGENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/signing-requests/einv_123/signature", {
  method: "POST",
  headers: {
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/signing-requests/einv_123/signature",
    headers={
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/signing-requests/einv_123/signature', [
    'headers' => [
        'Authorization' => 'Agent AGENT_ID.AGENT_SECRET',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/signing-requests/einv_123/signature");
request.Headers.Add("Authorization", "Agent AGENT_ID.AGENT_SECRET");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/signing-requests/einv_123/signature"))
    .headers("Authorization", "Agent AGENT_ID.AGENT_SECRET", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Refuse a signing request

#

POST /v1/signing-requests/{id}/refuse

Parameters

  • id (path)stringrequired

Request body

  • reasonenumrequired
    user_declinedpolicytoken_missingpin_lockedpayload_invalid
  • messagestring | null

Returns

  • 200

    Refusal recorded.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/signing-requests/einv_123/refuse" \
  -H "Authorization: Agent AGENT_ID.AGENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/signing-requests/einv_123/refuse", {
  method: "POST",
  headers: {
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/signing-requests/einv_123/refuse",
    headers={
    "Authorization": "Agent AGENT_ID.AGENT_SECRET",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/signing-requests/einv_123/refuse', [
    'headers' => [
        'Authorization' => 'Agent AGENT_ID.AGENT_SECRET',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/signing-requests/einv_123/refuse");
request.Headers.Add("Authorization", "Agent AGENT_ID.AGENT_SECRET");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/signing-requests/einv_123/refuse"))
    .headers("Authorization", "Agent AGENT_ID.AGENT_SECRET", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Usage

Monthly document usage against your plan.

Endpoints

Monthly document usage

#

GET /v1/usage

Production usage only — sandbox usage is shown separately with environment=sandbox and is never billable.

Parameters

  • period (query)stringrequired
  • companyId (query)string

Returns

  • 200

    Usage for the period.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/usage" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch("https://api.efaktura.merot.com/v1/usage", {
  method: "GET",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/usage",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/usage', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/usage");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");


using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/usage"))
    .headers("Authorization", "Bearer YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "period": "2026-10",
  "plan": {
    "code": "business",
    "includedDocuments": 1000
  },
  "totals": {
    "sent": 340,
    "received": 128,
    "billable": 468
  },
  "byCompany": [
    {
      "companyId": "cmp_01J9Z3K2N4R5T6V7W8X9Y0Z1",
      "sent": 340,
      "received": 128
    }
  ]
}

Sandbox

The UJP-test/simulator-only endpoints available on sandbox keys.

Simulate a status transition (sandbox simulator only)

#

POST /v1/sandbox/einvoices/{id}/simulate

Only available when the company's sandbox backend is the Merot simulator (not UJP test). Lets you move a document between statuses without a real qualified token.

Parameters

  • id (path)stringrequired

Request body

  • statusenumrequired
    030504
  • rejectReasonCodestring | null

Returns

  • 200

    The e-invoice with its new simulated status.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/sandbox/einvoices/einv_123/simulate" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/sandbox/einvoices/einv_123/simulate", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/sandbox/einvoices/einv_123/simulate",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/sandbox/einvoices/einv_123/simulate', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/sandbox/einvoices/einv_123/simulate");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/sandbox/einvoices/einv_123/simulate"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Inject a simulated incoming e-invoice (sandbox simulator only)

#

POST /v1/sandbox/inbox

Request body

  • fromTaxNumberstring | null
  • linesarray of object
    Show child parametersHide child parameters
    • skustring | null
    • descriptionstringrequired
    • unitstring | null
    • quantitystringrequired

      Decimal string.

    • unitPricestringrequired

      A decimal amount as a string, never a JSON number.

    • unitDiscountstring

      A decimal amount as a string, never a JSON number.

    • vatPercentstringrequired

      Decimal string, e.g. "18", "5", "0".

    • taxIndicatorstringrequired

      UJP tax-indicator codebook code.

    • domesticProductboolean | null

Returns

  • 201

    Simulated inbox document created.

cURL
curl -X POST "https://api.efaktura.merot.com/v1/sandbox/inbox" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const response = await fetch("https://api.efaktura.merot.com/v1/sandbox/inbox", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

const data = await response.json();
console.log(data);
import requests

response = requests.post(
    "https://api.efaktura.merot.com/v1/sandbox/inbox",
    headers={
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
    },
    json={},
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.efaktura.merot.com/v1/sandbox/inbox', [
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Content-Type' => 'application/json',
    ],
    'json' => [],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.efaktura.merot.com/v1/sandbox/inbox");
request.Headers.Add("Authorization", "Bearer YOUR_API_KEY");
var json = /* lang=json */ @"{}";
request.Content = new StringContent(json, Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/sandbox/inbox"))
    .headers("Authorization", "Bearer YOUR_API_KEY", "Content-Type", "application/json")
    .method("POST", HttpRequest.BodyPublishers.ofString(/* JSON */ "{}"))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Bridge

Merot Bridge release metadata (public, unauthenticated).

List Merot Bridge releases

#

GET /v1/bridge/releases

Public and unauthenticated. Backs the downloads page and Bridge's own auto-updater.

Parameters

  • channel (query)enum
    stablebeta

    Default: "stable"

Returns

  • 200

    Releases on the requested channel.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/bridge/releases"
const response = await fetch("https://api.efaktura.merot.com/v1/bridge/releases", {
  method: "GET",
  headers: {

  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/bridge/releases",
    headers={

    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/bridge/releases', [
    'headers' => [

    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/bridge/releases");



using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/bridge/releases"))
    .headers()
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Health

Public status endpoint (unauthenticated).

Service and UJP reachability status

#

GET /v1/health

Returns

  • 200

    Current status.

cURL
curl -X GET "https://api.efaktura.merot.com/v1/health"
const response = await fetch("https://api.efaktura.merot.com/v1/health", {
  method: "GET",
  headers: {

  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    "https://api.efaktura.merot.com/v1/health",
    headers={

    },
)

print(response.json())
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.efaktura.merot.com/v1/health', [
    'headers' => [

    ],
]);

echo $response->getBody();
using System.Net.Http;
using System.Text;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.efaktura.merot.com/v1/health");



using var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.efaktura.merot.com/v1/health"))
    .headers()
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
  "status": "ok",
  "version": "2026-09-26",
  "ujp": {
    "test": "up",
    "production": "not_configured"
  }
}