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.
Endpoints
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).
### POST /v1/oauth/token
Get a client-credentials access 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`.
```bash
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"
```
**Example response**
```json
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 900,
"scope": "einvoices:read einvoices:write inbox:read inbox:write"
}
``` 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()); {
"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)stringlimit (query)integerDefault:
25
Returns
- 200
A page of companies.
- 401
Missing, malformed or revoked credentials.
- 429
Too many requests.
### GET /v1/companies
List client companies
```bash
curl -X GET "https://api.efaktura.merot.com/v1/companies" \
-H "Authorization: Bearer YOUR_API_KEY"
```
**Example response**
```json
{
"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
}
``` 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()); {
"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)stringrequiredRequired on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.
Request body
taxNumberstringrequiredЕДБ of the client company.
externalRefstring | nullYour own identifier for this company.
signingModeenumbridgesdkDefault:
"bridge"representativeobjectrequiredShow child parameters
namestringrequiredemailstringrequired
Returns
- 201
Company created, pending mandate acceptance.
- 400
The request body failed validation.
- 503
UJP registry pre-flight unavailable — no company was created.
### POST /v1/companies
Add a client company
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.
```bash
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"
}
}'
```
**Example response**
```json
{
"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"
}
``` 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()); {
"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.
### GET /v1/companies/{id}
Retrieve a company
```bash
curl -X GET "https://api.efaktura.merot.com/v1/companies/einv_123" \
-H "Authorization: Bearer YOUR_API_KEY"
```
**Example response**
```json
{
"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"
}
``` 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()); {
"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 | nullsigningModeenumbridgesdk
Returns
- 200
Updated company.
- 404
No such resource for this company.
### PATCH /v1/companies/{id}
Update a company
Only `externalRef` and `signingMode` may be changed.
```bash
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"
}'
``` 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()); E-Invoices
Issue, validate, look up, storno and correct outbound e-invoices.
List e-invoices
# GET /v1/einvoices
Parameters
X-Company-Id (header)stringRequired when your key/token has access to more than one company.
status (query)enumvalidatinginvalidawaiting_signaturequeuedsubmittingfailedhelddeliveredacceptedauto_acceptedrejectedcancelled_by_stornocorrectedregistereddraft_at_ujpdocumentType (query)stringUJP document-type code (e.g. `100` invoice, `110` credit note).
issuedFrom (query)stringissuedTo (query)stringclientReference (query)stringeuid (query)stringcursor (query)stringlimit (query)integerDefault:
25
Returns
- 200
A page of e-invoices.
- 401
Missing, malformed or revoked credentials.
### GET /v1/einvoices List e-invoices ```bash curl -X GET "https://api.efaktura.merot.com/v1/einvoices" \ -H "Authorization: Bearer YOUR_API_KEY" ```
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)stringRequired when your key/token has access to more than one company.
Idempotency-Key (header)stringrequiredRequired on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.
Request body
clientReferencestringrequiredYour own idempotent key for this document.
documentTypestringrequiredUJP document-type codebook code (100 invoice, 110 credit note, 130 advance, 150/160 debit/other, ...).
numberstringrequiredissueDatestringrequiredturnoverDatestringrequireddeliveryDatestring | nullperiodStartstring | nullperiodEndstring | nullnotesstring | nullheaderstring | nullfooterstring | nullsellerobject | nullOnly subsidiaryCode/contact/email may be set — the seller's identity always comes from your company.
Show child parameters
subsidiaryCodestring | nullcontactstring | nullemailstring | null
buyerobjectrequiredShow child parameters
countrystringrequiredISO 3166-1 alpha-2.
taxNumberstring | nullЕДБ.
foreignTaxNumberstring | nullvatNumberstring | nullnamestringrequiredaddressobjectrequiredShow child parameters
streetstring | nullnumberstring | nullpostalCodestring | nullcitystring | null
subsidiaryCodestring | nullsubsidiaryNamestring | nullcontactstring | nullemailstring | null
receiverobject | nullShow child parameters
countrystringrequiredISO 3166-1 alpha-2.
taxNumberstring | nullЕДБ.
foreignTaxNumberstring | nullvatNumberstring | nullnamestringrequiredaddressobjectrequiredShow child parameters
streetstring | nullnumberstring | nullpostalCodestring | nullcitystring | null
subsidiaryCodestring | nullsubsidiaryNamestring | nullcontactstring | nullemailstring | null
referencesarray of objectrequiredShow child parameters
typestringrequiredUJP ref-document-type codebook code.
numberstringrequireddatestring | null
paymentobjectrequiredShow child parameters
typeCodestringrequireddueDatestring | nulldueDaysinteger | nulltermsstring | nullnotestring | nullcurrencystringrequiredexchangeRatestring | nullexchangeRateDatestring | null
linesarray of objectrequiredShow child parameters
skustring | nulldescriptionstringrequiredunitstring | nullquantitystringrequiredDecimal string.
unitPricestringrequiredA decimal amount as a string, never a JSON number.
unitDiscountstringA decimal amount as a string, never a JSON number.
vatPercentstringrequiredDecimal string, e.g. "18", "5", "0".
taxIndicatorstringrequiredUJP tax-indicator codebook code.
domesticProductboolean | null
advanceobject | nullShow child parameters
amountstringA decimal amount as a string, never a JSON number.
datestring | nulldescriptionstring | null
expectedTotalsobject | nullOptional — if given and it doesn't match Merot's computed totals, the request fails with 422 totals_mismatch.
Show child parameters
netstringA decimal amount as a string, never a JSON number.
vatstringA decimal amount as a string, never a JSON number.
grossstringA 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-Keyheader is missing. - 409
client_reference_conflict — same clientReference, different body.
- 422
validation_failed — field-level errors, or totals_mismatch with the computed totals.
### POST /v1/einvoices
Issue an e-invoice
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.
```bash
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"
}
}'
``` 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)stringRequired when your key/token has access to more than one company.
Request body
clientReferencestringrequiredYour own idempotent key for this document.
documentTypestringrequiredUJP document-type codebook code (100 invoice, 110 credit note, 130 advance, 150/160 debit/other, ...).
numberstringrequiredissueDatestringrequiredturnoverDatestringrequireddeliveryDatestring | nullperiodStartstring | nullperiodEndstring | nullnotesstring | nullheaderstring | nullfooterstring | nullsellerobject | nullOnly subsidiaryCode/contact/email may be set — the seller's identity always comes from your company.
Show child parameters
subsidiaryCodestring | nullcontactstring | nullemailstring | null
buyerobjectrequiredShow child parameters
countrystringrequiredISO 3166-1 alpha-2.
taxNumberstring | nullЕДБ.
foreignTaxNumberstring | nullvatNumberstring | nullnamestringrequiredaddressobjectrequiredShow child parameters
streetstring | nullnumberstring | nullpostalCodestring | nullcitystring | null
subsidiaryCodestring | nullsubsidiaryNamestring | nullcontactstring | nullemailstring | null
receiverobject | nullShow child parameters
countrystringrequiredISO 3166-1 alpha-2.
taxNumberstring | nullЕДБ.
foreignTaxNumberstring | nullvatNumberstring | nullnamestringrequiredaddressobjectrequiredShow child parameters
streetstring | nullnumberstring | nullpostalCodestring | nullcitystring | null
subsidiaryCodestring | nullsubsidiaryNamestring | nullcontactstring | nullemailstring | null
referencesarray of objectrequiredShow child parameters
typestringrequiredUJP ref-document-type codebook code.
numberstringrequireddatestring | null
paymentobjectrequiredShow child parameters
typeCodestringrequireddueDatestring | nulldueDaysinteger | nulltermsstring | nullnotestring | nullcurrencystringrequiredexchangeRatestring | nullexchangeRateDatestring | null
linesarray of objectrequiredShow child parameters
skustring | nulldescriptionstringrequiredunitstring | nullquantitystringrequiredDecimal string.
unitPricestringrequiredA decimal amount as a string, never a JSON number.
unitDiscountstringA decimal amount as a string, never a JSON number.
vatPercentstringrequiredDecimal string, e.g. "18", "5", "0".
taxIndicatorstringrequiredUJP tax-indicator codebook code.
domesticProductboolean | null
advanceobject | nullShow child parameters
amountstringA decimal amount as a string, never a JSON number.
datestring | nulldescriptionstring | null
expectedTotalsobject | nullOptional — if given and it doesn't match Merot's computed totals, the request fails with 422 totals_mismatch.
Show child parameters
netstringA decimal amount as a string, never a JSON number.
vatstringA decimal amount as a string, never a JSON number.
grossstringA 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.
### POST /v1/einvoices/validate
Validate an e-invoice without submitting it
Runs the full UJP rule check and the buyer ЕДБ registry pre-flight. Nothing is sent to UJP.
```bash
curl -X POST "https://api.efaktura.merot.com/v1/einvoices/validate" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
**Example response**
```json
{
"valid": true,
"totals": {
"net": "10000.00",
"vat": "1800.00",
"gross": "11800.00",
"currency": "MKD"
},
"warnings": []
}
``` 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()); {
"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)stringrequiredX-Company-Id (header)stringRequired when your key/token has access to more than one company.
Returns
- 200
The e-invoice.
- 404
No such resource for this company.
### GET /v1/einvoices/{id}
Retrieve an e-invoice
```bash
curl -X GET "https://api.efaktura.merot.com/v1/einvoices/einv_123" \
-H "Authorization: Bearer YOUR_API_KEY"
```
**Example response**
```json
{
"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"
}
``` 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()); {
"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)stringrequiredX-Company-Id (header)stringRequired when your key/token has access to more than one company.
Returns
- 200
Ordered status events.
- 404
No such resource for this company.
### GET /v1/einvoices/{id}/status-history
Status history
```bash
curl -X GET "https://api.efaktura.merot.com/v1/einvoices/einv_123/status-history" \
-H "Authorization: Bearer YOUR_API_KEY"
```
**Example response**
```json
{
"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
}
]
}
``` 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()); {
"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)stringrequiredX-Company-Id (header)stringRequired 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.
### POST /v1/einvoices/{id}/refresh-status
Force a status refresh from UJP
Requires your signing agent to be online (a read-purpose signature is needed to poll UJP).
```bash
curl -X POST "https://api.efaktura.merot.com/v1/einvoices/einv_123/refresh-status" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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)stringrequiredX-Company-Id (header)stringRequired when your key/token has access to more than one company.
Idempotency-Key (header)stringrequiredRequired on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.
Request body
clientReferencestringrequirednumberstringrequiredissueDatestringrequiredreasonCodestringrequiredUJP void-reason codebook code (S-x).
commentstring | null
Returns
- 202
Storno document created.
- 409
period_closed or invalid source status for storno.
### POST /v1/einvoices/{id}/storno
Storno (void) an e-invoice
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`.
```bash
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"
}'
``` 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)stringrequiredX-Company-Id (header)stringRequired when your key/token has access to more than one company.
Idempotency-Key (header)stringrequiredRequired on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.
Request body
reasonCodestringrequiredUJP correction-reason codebook code (C0x).
commentstring | nullreplacementobjectrequiredShow child parameters
clientReferencestringrequiredYour own idempotent key for this document.
documentTypestringrequiredUJP document-type codebook code (100 invoice, 110 credit note, 130 advance, 150/160 debit/other, ...).
numberstringrequiredissueDatestringrequiredturnoverDatestringrequireddeliveryDatestring | nullperiodStartstring | nullperiodEndstring | nullnotesstring | nullheaderstring | nullfooterstring | nullsellerobject | nullOnly subsidiaryCode/contact/email may be set — the seller's identity always comes from your company.
Show child parameters
subsidiaryCodestring | nullcontactstring | nullemailstring | null
buyerobjectrequiredShow child parameters
countrystringrequiredISO 3166-1 alpha-2.
taxNumberstring | nullЕДБ.
foreignTaxNumberstring | nullvatNumberstring | nullnamestringrequiredaddressobjectrequiredShow child parameters
streetstring | nullnumberstring | nullpostalCodestring | nullcitystring | null
subsidiaryCodestring | nullsubsidiaryNamestring | nullcontactstring | nullemailstring | null
receiverobject | nullShow child parameters
countrystringrequiredISO 3166-1 alpha-2.
taxNumberstring | nullЕДБ.
foreignTaxNumberstring | nullvatNumberstring | nullnamestringrequiredaddressobjectrequiredShow child parameters
streetstring | nullnumberstring | nullpostalCodestring | nullcitystring | null
subsidiaryCodestring | nullsubsidiaryNamestring | nullcontactstring | nullemailstring | null
referencesarray of objectrequiredShow child parameters
typestringrequiredUJP ref-document-type codebook code.
numberstringrequireddatestring | null
paymentobjectrequiredShow child parameters
typeCodestringrequireddueDatestring | nulldueDaysinteger | nulltermsstring | nullnotestring | nullcurrencystringrequiredexchangeRatestring | nullexchangeRateDatestring | null
linesarray of objectrequiredShow child parameters
skustring | nulldescriptionstringrequiredunitstring | nullquantitystringrequiredDecimal string.
unitPricestringrequiredA decimal amount as a string, never a JSON number.
unitDiscountstringA decimal amount as a string, never a JSON number.
vatPercentstringrequiredDecimal string, e.g. "18", "5", "0".
taxIndicatorstringrequiredUJP tax-indicator codebook code.
domesticProductboolean | null
advanceobject | nullShow child parameters
amountstringA decimal amount as a string, never a JSON number.
datestring | nulldescriptionstring | null
expectedTotalsobject | nullOptional — if given and it doesn't match Merot's computed totals, the request fails with 422 totals_mismatch.
Show child parameters
netstringA decimal amount as a string, never a JSON number.
vatstringA decimal amount as a string, never a JSON number.
grossstringA decimal amount as a string, never a JSON number.
currencystring
Returns
- 202
Correction document created.
### POST /v1/einvoices/{id}/correction
Correct an e-invoice
Creates a full replacement document with `docStorno: 2` and a correction reason (codebook `C0x`).
```bash
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 '{}'
``` 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)stringrequiredX-Company-Id (header)stringRequired 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.
### GET /v1/einvoices/{id}/pdf
Download the UJP PDF rendering
```bash
curl -X GET "https://api.efaktura.merot.com/v1/einvoices/einv_123/pdf" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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()); application/pdf — binary/file response, no JSON body to preview.
Inbox
Incoming e-invoices and the accept/reject decision.
List incoming e-invoices
# GET /v1/inbox
Parameters
X-Company-Id (header)stringRequired when your key/token has access to more than one company.
status (query)enumpendingacceptedauto_acceptedrejecteddeadlineBefore (query)stringcursor (query)string
Returns
- 200
A page of inbox documents.
### GET /v1/inbox
List incoming e-invoices
```bash
curl -X GET "https://api.efaktura.merot.com/v1/inbox" \
-H "Authorization: Bearer YOUR_API_KEY"
```
**Example response**
```json
{
"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"
}
}
]
}
``` 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()); {
"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)stringrequiredX-Company-Id (header)stringRequired when your key/token has access to more than one company.
Returns
- 200
The inbox document.
- 404
No such resource for this company.
### GET /v1/inbox/{id}
Retrieve an incoming e-invoice
```bash
curl -X GET "https://api.efaktura.merot.com/v1/inbox/einv_123" \
-H "Authorization: Bearer YOUR_API_KEY"
```
**Example response**
```json
{
"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"
}
}
``` 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()); {
"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)stringrequiredX-Company-Id (header)stringRequired when your key/token has access to more than one company.
Idempotency-Key (header)stringrequiredRequired 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).
### POST /v1/inbox/{id}/accept
Accept an incoming e-invoice
Silence until the 10th of the month **after** the transaction date is also acceptance
(UJP auto-accepts it) — see [Document lifecycle](/efaktura/lifecycle). Accepting explicitly
needs no reason.
```bash
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 '{}'
``` 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)stringrequiredX-Company-Id (header)stringRequired when your key/token has access to more than one company.
Idempotency-Key (header)stringrequiredRequired on every POST except `/v1/oauth/token`. Reuse the same key to safely retry.
Request body
reasonCodestringrequiredUJP reject-reason codebook code (O-1…O-7).
commentstring | null
Returns
- 202
Decision recorded.
- 409
decision_deadline_passed
### POST /v1/inbox/{id}/reject
Reject an incoming e-invoice
```bash
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"
}'
``` 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)stringrequiredX-Company-Id (header)stringRequired when your key/token has access to more than one company.
Returns
- 200
The seller's original document JSON, unmodified.
### GET /v1/inbox/{id}/payload
Download the exact UJP JSON payload
```bash
curl -X GET "https://api.efaktura.merot.com/v1/inbox/einv_123/payload" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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)stringrequiredX-Company-Id (header)stringRequired when your key/token has access to more than one company.
Returns
- 200
The document's artefacts.
- 404
No such resource for this company.
### GET /v1/archive/einvoices/{id}
List the archived artefacts for a document
Accepts either an outbound or an inbound document id.
```bash
curl -X GET "https://api.efaktura.merot.com/v1/archive/einvoices/einv_123" \
-H "Authorization: Bearer YOUR_API_KEY"
```
**Example response**
```json
{
"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"
}
]
}
``` 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()); {
"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
environmentenumrequiredsandboxproductiondirectionenum | nulloutboundinboundissuedFromstringrequiredissuedTostringrequiredkindsarray of enum
Returns
- 202
Export queued.
### POST /v1/archive/exports
Request a bulk archive export
```bash
curl -X POST "https://api.efaktura.merot.com/v1/archive/exports" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
``` 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).
### GET /v1/archive/exports/{id}
Get an archive export
The ZIP contains a `manifest.json` listing every file's sha256, EUID and document number. Expires 7 days after it becomes ready.
```bash
curl -X GET "https://api.efaktura.merot.com/v1/archive/exports/einv_123" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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()); Webhooks
Event subscriptions, delivery log and replay.
Endpoints
- GET
/v1/webhook-endpoints - POST
/v1/webhook-endpoints - GET
/v1/webhook-endpoints/{id} - PATCH
/v1/webhook-endpoints/{id} - DELETE
/v1/webhook-endpoints/{id} - POST
/v1/webhook-endpoints/{id}/rotate-secret - POST
/v1/webhook-endpoints/{id}/test - GET
/v1/webhook-endpoints/{id}/deliveries - GET
/v1/events - GET
/v1/events/{id} - POST
/v1/events/{id}/replay
### GET /v1/webhook-endpoints List webhook endpoints ```bash curl -X GET "https://api.efaktura.merot.com/v1/webhook-endpoints" \ -H "Authorization: Bearer YOUR_API_KEY" ```
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
urlstringrequiredMust be https in production.
eventsarray of enumrequiredcompanyIdsarray of string | nulldescriptionstring | null
Returns
- 201
Endpoint created. The signing secret is shown once.
### POST /v1/webhook-endpoints
Create a webhook endpoint
```bash
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"
]
}'
```
**Example response**
```json
{
"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"
}
``` 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()); {
"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.
### GET /v1/webhook-endpoints/{id}
Retrieve a webhook endpoint
```bash
curl -X GET "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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
urlstringeventsarray of enumcompanyIdsarray of string | nulldescriptionstring | null
Returns
- 200
Updated webhook endpoint.
### PATCH /v1/webhook-endpoints/{id}
Update a webhook endpoint
```bash
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 '{}'
``` 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.
### DELETE /v1/webhook-endpoints/{id}
Disable a webhook endpoint
Sets the endpoint to `disabled_by_user`; it stops receiving new deliveries.
```bash
curl -X DELETE "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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.
### POST /v1/webhook-endpoints/{id}/rotate-secret
Rotate a webhook endpoint's signing secret
The old secret keeps signing deliveries for 24 hours alongside the new one (two `v1=` entries on `Merot-Signature`).
```bash
curl -X POST "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/rotate-secret" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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.
### POST /v1/webhook-endpoints/{id}/test
Send a test ping event
```bash
curl -X POST "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/test" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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)stringrequiredstate (query)enumpendingsucceededfailedabandonedcursor (query)string
Returns
- 200
A page of deliveries.
### GET /v1/webhook-endpoints/{id}/deliveries
List delivery attempts for an endpoint
```bash
curl -X GET "https://api.efaktura.merot.com/v1/webhook-endpoints/einv_123/deliveries" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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)enumeinvoice.validated_failedeinvoice.signature_requiredeinvoice.submittedeinvoice.acceptedeinvoice.auto_acceptedeinvoice.rejectedeinvoice.cancelled_by_stornoeinvoice.correctedeinvoice.failedinbox.receivedinbox.deadline_approachinginbox.auto_acceptedsigning_agent.offlinesigning_agent.onlinearchive.export_readycreatedFrom (query)stringcursor (query)string
Returns
- 200
A page of events.
### GET /v1/events List events Events are retained for 30 days. ```bash curl -X GET "https://api.efaktura.merot.com/v1/events" \ -H "Authorization: Bearer YOUR_API_KEY" ```
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()); ### GET /v1/events/{id}
Retrieve an event
```bash
curl -X GET "https://api.efaktura.merot.com/v1/events/einv_123" \
-H "Authorization: Bearer YOUR_API_KEY"
``` 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 | nullReplay to one endpoint only; omit to replay to all subscribed endpoints.
Returns
- 202
A new delivery was queued (
is_replay: true).
### POST /v1/events/{id}/replay
Replay an event
```bash
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 '{}'
``` 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()); Signing Agents
Merot Bridge (Mode A) and SDK signing workers (Mode B) — pairing and signing requests.
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
codestringrequiredkindenumrequiredbridgesdknamestringrequiredplatformenum | nullwindowsmacoslinuxserverversionstring | nullpublicKeyJwkobjectrequiredThe agent's Ed25519 device key (OKP).
Returns
- 200
Agent credentials — shown once.
### POST /v1/agents/pair
Pair a Merot Bridge or SDK signing worker
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.
```bash
curl -X POST "https://api.efaktura.merot.com/v1/agents/pair" \
-H "Content-Type: application/json" \
-d '{}'
``` 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
certificateDerstringrequiredBase64-encoded DER certificate.
companyIdstringrequired
Returns
- 201
Certificate registered and linked to the company.
### POST /v1/agents/{id}/certificates
Register a signing certificate for an agent
```bash
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 '{}'
``` 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)stringrequiredwait (query)integerDefault:
25
Returns
- 200
Pending signing requests for this agent.
### GET /v1/agents/{id}/signing-requests
Long-poll pending signing requests (WebSocket fallback)
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.
```bash
curl -X GET "https://api.efaktura.merot.com/v1/agents/einv_123/signing-requests" \
-H "Authorization: Agent AGENT_ID.AGENT_SECRET"
``` 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)enumpendingcompanyId (query)string
Returns
- 200
Pending signing requests.
### GET /v1/signing-requests List pending signing requests (Mode B inline signing) ```bash curl -X GET "https://api.efaktura.merot.com/v1/signing-requests" \ -H "Authorization: Bearer YOUR_API_KEY" ```
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.
### GET /v1/signing-requests/{id}
Retrieve a signing request
```bash
curl -X GET "https://api.efaktura.merot.com/v1/signing-requests/einv_123" \
-H "Authorization: Agent AGENT_ID.AGENT_SECRET"
``` 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
### POST /v1/signing-requests/{id}/claim
Claim a signing request
```bash
curl -X POST "https://api.efaktura.merot.com/v1/signing-requests/einv_123/claim" \
-H "Authorization: Agent AGENT_ID.AGENT_SECRET"
``` 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
jwsstringrequiredCompact 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.
### POST /v1/signing-requests/{id}/signature
Submit a 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.
```bash
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 '{}'
``` 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
reasonenumrequireduser_declinedpolicytoken_missingpin_lockedpayload_invalidmessagestring | null
Returns
- 200
Refusal recorded.
### POST /v1/signing-requests/{id}/refuse
Refuse a signing request
```bash
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 '{}'
``` 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)stringrequiredcompanyId (query)string
Returns
- 200
Usage for the period.
### GET /v1/usage
Monthly document usage
Production usage only — sandbox usage is shown separately with `environment=sandbox` and is never billable.
```bash
curl -X GET "https://api.efaktura.merot.com/v1/usage" \
-H "Authorization: Bearer YOUR_API_KEY"
```
**Example response**
```json
{
"period": "2026-10",
"plan": {
"code": "business",
"includedDocuments": 1000
},
"totals": {
"sent": 340,
"received": 128,
"billable": 468
},
"byCompany": [
{
"companyId": "cmp_01J9Z3K2N4R5T6V7W8X9Y0Z1",
"sent": 340,
"received": 128
}
]
}
``` 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()); {
"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
statusenumrequired030504rejectReasonCodestring | null
Returns
- 200
The e-invoice with its new simulated status.
### POST /v1/sandbox/einvoices/{id}/simulate
Simulate a status transition (sandbox simulator only)
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.
```bash
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 '{}'
``` 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 | nulllinesarray of objectShow child parameters
skustring | nulldescriptionstringrequiredunitstring | nullquantitystringrequiredDecimal string.
unitPricestringrequiredA decimal amount as a string, never a JSON number.
unitDiscountstringA decimal amount as a string, never a JSON number.
vatPercentstringrequiredDecimal string, e.g. "18", "5", "0".
taxIndicatorstringrequiredUJP tax-indicator codebook code.
domesticProductboolean | null
Returns
- 201
Simulated inbox document created.
### POST /v1/sandbox/inbox
Inject a simulated incoming e-invoice (sandbox simulator only)
```bash
curl -X POST "https://api.efaktura.merot.com/v1/sandbox/inbox" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
``` 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).
Endpoints
List Merot Bridge releases
# GET /v1/bridge/releases
Public and unauthenticated. Backs the downloads page and Bridge's own auto-updater.
Parameters
channel (query)enumstablebetaDefault:
"stable"
Returns
- 200
Releases on the requested channel.
### GET /v1/bridge/releases List Merot Bridge releases Public and unauthenticated. Backs the downloads page and Bridge's own auto-updater. ```bash curl -X GET "https://api.efaktura.merot.com/v1/bridge/releases" ```
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).
Endpoints
### GET /v1/health
Service and UJP reachability status
```bash
curl -X GET "https://api.efaktura.merot.com/v1/health"
```
**Example response**
```json
{
"status": "ok",
"version": "2026-09-26",
"ujp": {
"test": "up",
"production": "not_configured"
}
}
``` 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()); {
"status": "ok",
"version": "2026-09-26",
"ujp": {
"test": "up",
"production": "not_configured"
}
}