{
  "info": {
    "_postman_id": "a96efea4-b419-438b-8cfb-6413741cb3ef",
    "name": "Merot e-Faktura API",
    "description": "Generated from the Merot e-Faktura public OpenAPI (version 2026-10-01). Start with the \"Get started\" folder, and set apiKey (an mfk_test_ sandbox key) in the Merot sandbox environment.\n\nEvery write carries an Idempotency-Key that the collection generates for you. Money is always a decimal string, never a JSON number.\n\nGuide: https://developer.merot.com/efaktura/postman",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{apiKey}}",
        "type": "string"
      }
    ]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Idempotency-Key: a fresh UUID v4 for every write, kept for retries.",
          "// The request declares the header only when the API requires it (every write",
          "// except POST /v1/oauth/token), so token requests are left alone.",
          "// A retry is re-sending the same request with the same body after a network",
          "// error, timeout, 429 or 5xx: it reuses the key, so the server treats it as a",
          "// replay. A changed body, or a request that got a final answer, gets a new key.",
          "if (pm.request.headers.has('Idempotency-Key')) {",
          "  const body = pm.request.body && pm.request.body.raw ? pm.variables.replaceIn(pm.request.body.raw) : '';",
          "  const fingerprint = [pm.request.method, pm.variables.replaceIn(pm.request.url.toString()), body].join(' ');",
          "  let key = pm.collectionVariables.get('idempotencyKey');",
          "  if (!key || pm.collectionVariables.get('idempotencyFingerprint') !== fingerprint) {",
          "    key = pm.variables.replaceIn('{{$guid}}');",
          "    pm.collectionVariables.set('idempotencyKey', key);",
          "    pm.collectionVariables.set('idempotencyFingerprint', fingerprint);",
          "  }",
          "}",
          "",
          "// X-Company-Id is optional for single-company keys: drop it while companyId is empty.",
          "if (!pm.variables.get('companyId')) pm.request.headers.remove('X-Company-Id');",
          "",
          "// Vendors: with no apiKey set, fall back to the token from 'Get an access token'.",
          "if (!pm.variables.get('apiKey') && pm.variables.get('accessToken')) {",
          "  pm.request.headers.upsert({ key: 'Authorization', value: 'Bearer ' + pm.variables.get('accessToken') });",
          "}"
        ]
      }
    },
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// A final answer ends the retry window for the current Idempotency-Key.",
          "// 429 and 5xx keep it, so re-sending the same request is a safe replay.",
          "if (pm.request.headers.has('Idempotency-Key') && pm.response.code < 500 && pm.response.code !== 429) {",
          "  pm.collectionVariables.unset('idempotencyKey');",
          "  pm.collectionVariables.unset('idempotencyFingerprint');",
          "}"
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.efaktura.merot.com"
    },
    {
      "key": "merotVersion",
      "value": "2026-10-01"
    }
  ],
  "item": [
    {
      "name": "Get started",
      "description": "The Full setup guide as a runnable sequence, top to bottom. Set apiKey in the environment first. Each step stores the id it returns (companyId, signerId, certificateId, einvoiceId), so the next step needs no copy and paste. Steps 4 and 5 need a certificate bound in Merot Bridge, and step 6 waits for the signing confirmation in Bridge.",
      "item": [
        {
          "name": "1. Create a company",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/companies",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "companies"
              ]
            },
            "description": "Onboard a client company by tax number; name/address come from the UJP registry, never the request; scope `companies:write`\n\nResponses:\n- 201: Created, status pending_mandate\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)\n- 503: ujp_unavailable",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"taxNumber\": \"4043022533490\",\n  \"externalRef\": \"customer-42\",\n  \"signingMode\": \"bridge\",\n  \"representative\": {\n    \"name\": \"Ана Петровска\",\n    \"email\": \"ana.petrovska@example.mk\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('company created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                  "if (pm.response.code === 200 || pm.response.code === 201) pm.environment.set('companyId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "2. Create a signer",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signers"
              ]
            },
            "description": "Register a natural-person signer identity (fullName + EUJP-ID) for this tenant; scope `companies:write`\n\nResponses:\n- 201: Created\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"fullName\": \"Ана Петровска\",\n  \"eujpId\": \"AP123456\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('signer created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                  "if (pm.response.code === 200 || pm.response.code === 201) pm.environment.set('signerId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "3. Link the signer to the company",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/company-signers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "company-signers"
              ]
            },
            "description": "Link an existing signer identity to a company, optionally as its default signer; scope `companies:write`\n\nResponses:\n- 201: Linked\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"signerId\": \"{{signerId}}\",\n  \"isDefault\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "4. Find the certificate bound by Bridge",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signers/:id/certificates",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signers",
                ":id",
                "certificates"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{signerId}}"
                }
              ]
            },
            "description": "A signer's certificates (pending/active/revoked/retired), newest first; scope `companies:read`\n\nResponses:\n- 200: Certificates\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('certificates listed', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const list = pm.response.json().items || [];",
                  "  const pending = list.find((c) => c.status !== 'active') || list[0];",
                  "  if (pending) pm.environment.set('certificateId', pending.id);",
                  "  else console.log('No certificate yet: pair and bind one in Merot Bridge first.');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "5. Activate the certificate",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signer-certificates/:id/activate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signer-certificates",
                ":id",
                "activate"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{certificateId}}"
                }
              ]
            },
            "description": "Trust a pending Bridge/SDK certificate to sign for real (pending → active); scope `companies:write`\n\nResponses:\n- 200: Activated\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "6. Issue a test invoice",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices"
              ]
            },
            "description": "Issue an outbound e-invoice; the company (X-Company-Id) is always the seller; scope `einvoices:write`\n\nResponses:\n- 200: Idempotent replay of an identical clientReference\n- 202: Queued\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)\n- 503: ujp_unavailable",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"clientReference\": \"inv-2026-000481\",\n  \"documentType\": \"100\",\n  \"number\": \"000481\",\n  \"issueDate\": \"2026-10-08\",\n  \"turnoverDate\": \"2026-10-08\",\n  \"deliveryDate\": null,\n  \"periodStart\": null,\n  \"periodEnd\": null,\n  \"notes\": null,\n  \"header\": null,\n  \"footer\": null,\n  \"buyer\": {\n    \"country\": \"MK\",\n    \"taxNumber\": \"4043022533490\",\n    \"foreignTaxNumber\": null,\n    \"vatNumber\": \"МК4043022533490\",\n    \"name\": \"МЕРОТ ДООЕЛ Скопје\",\n    \"address\": {\n      \"street\": \"ЈУЖНОМОРАВСКИ БРИГАДИ 4\",\n      \"number\": \"7б/-\",\n      \"postalCode\": \"1000\",\n      \"city\": \"СКОПЈЕ-Г. БАБА\"\n    },\n    \"subsidiaryCode\": null,\n    \"subsidiaryName\": null,\n    \"contact\": null,\n    \"email\": null\n  },\n  \"receiver\": null,\n  \"references\": [],\n  \"payment\": {\n    \"typeCode\": \"P12\",\n    \"dueDate\": \"2026-11-07\",\n    \"dueDays\": 30,\n    \"terms\": null,\n    \"note\": null,\n    \"currency\": \"MKD\",\n    \"exchangeRate\": null,\n    \"exchangeRateDate\": null\n  },\n  \"lines\": [\n    {\n      \"sku\": null,\n      \"description\": \"Консултантски услуги — септември 2026\",\n      \"unit\": \"услуга\",\n      \"quantity\": \"1\",\n      \"unitPrice\": \"10000.00\",\n      \"unitDiscount\": \"0\",\n      \"vatPercent\": \"18\",\n      \"taxIndicator\": \"DDV-A\",\n      \"domesticProduct\": null\n    }\n  ],\n  \"expectedTotals\": {\n    \"net\": \"10000.00\",\n    \"vat\": \"1800.00\",\n    \"gross\": \"11800.00\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('invoice accepted', () => pm.expect(pm.response.code).to.be.oneOf([200, 202]));",
                  "if (pm.response.code === 200 || pm.response.code === 202) pm.environment.set('einvoiceId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "7. Get the invoice status",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ]
            },
            "description": "One outbound e-invoice; scope `einvoices:read`\n\nResponses:\n- 200: E-invoice\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "8. List the inbox",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/inbox",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "inbox"
              ],
              "query": [
                {
                  "key": "cursor",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "pending",
                  "disabled": true
                },
                {
                  "key": "deadlineBefore",
                  "value": "2026-09-24",
                  "disabled": true
                }
              ]
            },
            "description": "Received e-invoices by decision deadline (cursor-paginated); scope `inbox:read`\n\nResponses:\n- 200: Page\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 429: rate_limited (Retry-After header carries the seconds)"
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.environment.get('inboxId')) {",
                  "  const b = pm.response.json(); const row = (b.data || b.items || [])[0];",
                  "  if (row) { pm.environment.set('inboxId', row.id); console.log('inboxId = ' + row.id); }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Vendors: get an OAuth access token",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/oauth/token",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "oauth",
                "token"
              ]
            },
            "description": "Client-credentials grant (RFC 6749 §4.4) — resolves to the same principal as an API key\n\nResponses:\n- 200: Access token, valid 15 minutes, no refresh token\n- 400: invalid_request / invalid_scope\n- 401: invalid_client",
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "client_credentials"
                },
                {
                  "key": "client_id",
                  "value": "{{clientId}}"
                },
                {
                  "key": "client_secret",
                  "value": "{{clientSecret}}"
                },
                {
                  "key": "scope",
                  "value": "companies:read einvoices:write",
                  "disabled": true
                }
              ]
            },
            "auth": {
              "type": "noauth"
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('token issued', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const body = pm.response.json();",
                  "  pm.environment.set('accessToken', body.access_token);",
                  "  console.log('accessToken stored; valid for ' + body.expires_in + ' seconds');",
                  "}"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "OAuth",
      "description": "Client-credentials tokens for vendors integrating on behalf of many client companies.",
      "item": [
        {
          "name": "Get an access token",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/oauth/token",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "oauth",
                "token"
              ]
            },
            "description": "Client-credentials grant (RFC 6749 §4.4) — resolves to the same principal as an API key\n\nResponses:\n- 200: Access token, valid 15 minutes, no refresh token\n- 400: invalid_request / invalid_scope\n- 401: invalid_client",
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "client_credentials"
                },
                {
                  "key": "client_id",
                  "value": "{{clientId}}"
                },
                {
                  "key": "client_secret",
                  "value": "{{clientSecret}}"
                },
                {
                  "key": "scope",
                  "value": "companies:read einvoices:write",
                  "disabled": true
                }
              ]
            },
            "auth": {
              "type": "noauth"
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('token issued', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const body = pm.response.json();",
                  "  pm.environment.set('accessToken', body.access_token);",
                  "  console.log('accessToken stored; valid for ' + body.expires_in + ' seconds');",
                  "}"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Companies",
      "description": "Client companies onboarded under your account.",
      "item": [
        {
          "name": "List companies",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/companies",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "companies"
              ],
              "query": [
                {
                  "key": "cursor",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                }
              ]
            },
            "description": "Client companies onboarded under this account (cursor-paginated); scope `companies:read`\n\nResponses:\n- 200: Page\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 429: rate_limited (Retry-After header carries the seconds)"
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('companies listed', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200 && !pm.environment.get('companyId')) {",
                  "  const first = (pm.response.json().data || [])[0];",
                  "  if (first) pm.environment.set('companyId', first.id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Create a company",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/companies",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "companies"
              ]
            },
            "description": "Onboard a client company by tax number; name/address come from the UJP registry, never the request; scope `companies:write`\n\nResponses:\n- 201: Created, status pending_mandate\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)\n- 503: ujp_unavailable",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"taxNumber\": \"4043022533490\",\n  \"externalRef\": \"customer-42\",\n  \"signingMode\": \"bridge\",\n  \"representative\": {\n    \"name\": \"Ана Петровска\",\n    \"email\": \"ana.petrovska@example.mk\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('company created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                  "if (pm.response.code === 200 || pm.response.code === 201) pm.environment.set('companyId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Retrieve a company",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/companies/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "companies",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{companyId}}"
                }
              ]
            },
            "description": "One client company; scope `companies:read`\n\nResponses:\n- 200: Company\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Update a company",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/companies/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "companies",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{companyId}}"
                }
              ]
            },
            "description": "Update externalRef / signingMode; scope `companies:write`\n\nResponses:\n- 200: Updated\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"externalRef\": \"customer-42\",\n  \"signingMode\": \"bridge\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Send the mandate e-mail (a new one-time link, valid 7 days, replacing older ones) to the representative of a company still pending_mandate",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/companies/:id/mandate/resend",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "companies",
                ":id",
                "mandate",
                "resend"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{companyId}}"
                }
              ]
            },
            "description": "Send the mandate e-mail (a new one-time link, valid 7 days, replacing older ones) to the representative of a company still pending_mandate; at most one per minute and five per hour; scope `companies:write`\n\nResponses:\n- 202: Mandate e-mail queued\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        }
      ]
    },
    {
      "name": "Signers and certificates",
      "description": "Signer identities (EUJP-ID), their link to companies, and certificate activation.",
      "item": [
        {
          "name": "Create a signer",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signers"
              ]
            },
            "description": "Register a natural-person signer identity (fullName + EUJP-ID) for this tenant; scope `companies:write`\n\nResponses:\n- 201: Created\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"fullName\": \"Ана Петровска\",\n  \"eujpId\": \"AP123456\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('signer created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                  "if (pm.response.code === 200 || pm.response.code === 201) pm.environment.set('signerId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "List a signer's certificates",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signers/:id/certificates",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signers",
                ":id",
                "certificates"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{signerId}}"
                }
              ]
            },
            "description": "A signer's certificates (pending/active/revoked/retired), newest first; scope `companies:read`\n\nResponses:\n- 200: Certificates\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('certificates listed', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const list = pm.response.json().items || [];",
                  "  const pending = list.find((c) => c.status !== 'active') || list[0];",
                  "  if (pending) pm.environment.set('certificateId', pending.id);",
                  "  else console.log('No certificate yet: pair and bind one in Merot Bridge first.');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Link a signer to a company",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/company-signers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "company-signers"
              ]
            },
            "description": "Link an existing signer identity to a company, optionally as its default signer; scope `companies:write`\n\nResponses:\n- 201: Linked\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"signerId\": \"{{signerId}}\",\n  \"isDefault\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Activate a certificate",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signer-certificates/:id/activate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signer-certificates",
                ":id",
                "activate"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{certificateId}}"
                }
              ]
            },
            "description": "Trust a pending Bridge/SDK certificate to sign for real (pending → active); scope `companies:write`\n\nResponses:\n- 200: Activated\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        }
      ]
    },
    {
      "name": "E-invoices",
      "description": "Issue, validate, track, storno and correct outbound e-invoices.",
      "item": [
        {
          "name": "List e-invoices",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices"
              ],
              "query": [
                {
                  "key": "cursor",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "validating",
                  "disabled": true
                },
                {
                  "key": "documentType",
                  "value": "123",
                  "disabled": true
                },
                {
                  "key": "issuedFrom",
                  "value": "2026-10-05",
                  "disabled": true
                },
                {
                  "key": "issuedTo",
                  "value": "2026-10-05",
                  "disabled": true
                },
                {
                  "key": "clientReference",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "euid",
                  "value": "string",
                  "disabled": true
                }
              ]
            },
            "description": "Outbound e-invoices, cursor-paginated; scope `einvoices:read`\n\nResponses:\n- 200: Page\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 429: rate_limited (Retry-After header carries the seconds)"
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.environment.get('einvoiceId')) {",
                  "  const b = pm.response.json(); const row = (b.data || b.items || [])[0];",
                  "  if (row) { pm.environment.set('einvoiceId', row.id); console.log('einvoiceId = ' + row.id); }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Issue an e-invoice",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices"
              ]
            },
            "description": "Issue an outbound e-invoice; the company (X-Company-Id) is always the seller; scope `einvoices:write`\n\nResponses:\n- 200: Idempotent replay of an identical clientReference\n- 202: Queued\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)\n- 503: ujp_unavailable",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"clientReference\": \"inv-2026-000481\",\n  \"documentType\": \"100\",\n  \"number\": \"000481\",\n  \"issueDate\": \"2026-10-08\",\n  \"turnoverDate\": \"2026-10-08\",\n  \"deliveryDate\": null,\n  \"periodStart\": null,\n  \"periodEnd\": null,\n  \"notes\": null,\n  \"header\": null,\n  \"footer\": null,\n  \"buyer\": {\n    \"country\": \"MK\",\n    \"taxNumber\": \"4043022533490\",\n    \"foreignTaxNumber\": null,\n    \"vatNumber\": \"МК4043022533490\",\n    \"name\": \"МЕРОТ ДООЕЛ Скопје\",\n    \"address\": {\n      \"street\": \"ЈУЖНОМОРАВСКИ БРИГАДИ 4\",\n      \"number\": \"7б/-\",\n      \"postalCode\": \"1000\",\n      \"city\": \"СКОПЈЕ-Г. БАБА\"\n    },\n    \"subsidiaryCode\": null,\n    \"subsidiaryName\": null,\n    \"contact\": null,\n    \"email\": null\n  },\n  \"receiver\": null,\n  \"references\": [],\n  \"payment\": {\n    \"typeCode\": \"P12\",\n    \"dueDate\": \"2026-11-07\",\n    \"dueDays\": 30,\n    \"terms\": null,\n    \"note\": null,\n    \"currency\": \"MKD\",\n    \"exchangeRate\": null,\n    \"exchangeRateDate\": null\n  },\n  \"lines\": [\n    {\n      \"sku\": null,\n      \"description\": \"Консултантски услуги — септември 2026\",\n      \"unit\": \"услуга\",\n      \"quantity\": \"1\",\n      \"unitPrice\": \"10000.00\",\n      \"unitDiscount\": \"0\",\n      \"vatPercent\": \"18\",\n      \"taxIndicator\": \"DDV-A\",\n      \"domesticProduct\": null\n    }\n  ],\n  \"expectedTotals\": {\n    \"net\": \"10000.00\",\n    \"vat\": \"1800.00\",\n    \"gross\": \"11800.00\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('invoice accepted', () => pm.expect(pm.response.code).to.be.oneOf([200, 202]));",
                  "if (pm.response.code === 200 || pm.response.code === 202) pm.environment.set('einvoiceId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Validate an e-invoice (no submission)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices/validate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices",
                "validate"
              ]
            },
            "description": "Dry-run build + codebook validation of an e-invoice body (no filing, no UJP call); scope `einvoices:write`\n\nResponses:\n- 200: Valid\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"clientReference\": \"inv-2026-000481\",\n  \"documentType\": \"100\",\n  \"number\": \"000481\",\n  \"issueDate\": \"2026-10-08\",\n  \"turnoverDate\": \"2026-10-08\",\n  \"deliveryDate\": null,\n  \"periodStart\": null,\n  \"periodEnd\": null,\n  \"notes\": null,\n  \"header\": null,\n  \"footer\": null,\n  \"buyer\": {\n    \"country\": \"MK\",\n    \"taxNumber\": \"4043022533490\",\n    \"foreignTaxNumber\": null,\n    \"vatNumber\": \"МК4043022533490\",\n    \"name\": \"МЕРОТ ДООЕЛ Скопје\",\n    \"address\": {\n      \"street\": \"ЈУЖНОМОРАВСКИ БРИГАДИ 4\",\n      \"number\": \"7б/-\",\n      \"postalCode\": \"1000\",\n      \"city\": \"СКОПЈЕ-Г. БАБА\"\n    },\n    \"subsidiaryCode\": null,\n    \"subsidiaryName\": null,\n    \"contact\": null,\n    \"email\": null\n  },\n  \"receiver\": null,\n  \"references\": [],\n  \"payment\": {\n    \"typeCode\": \"P12\",\n    \"dueDate\": \"2026-11-07\",\n    \"dueDays\": 30,\n    \"terms\": null,\n    \"note\": null,\n    \"currency\": \"MKD\",\n    \"exchangeRate\": null,\n    \"exchangeRateDate\": null\n  },\n  \"lines\": [\n    {\n      \"sku\": null,\n      \"description\": \"Консултантски услуги — септември 2026\",\n      \"unit\": \"услуга\",\n      \"quantity\": \"1\",\n      \"unitPrice\": \"10000.00\",\n      \"unitDiscount\": \"0\",\n      \"vatPercent\": \"18\",\n      \"taxIndicator\": \"DDV-A\",\n      \"domesticProduct\": null\n    }\n  ],\n  \"expectedTotals\": {\n    \"net\": \"10000.00\",\n    \"vat\": \"1800.00\",\n    \"gross\": \"11800.00\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Retrieve an e-invoice (status)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ]
            },
            "description": "One outbound e-invoice; scope `einvoices:read`\n\nResponses:\n- 200: E-invoice\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Status history",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices/:id/status-history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices",
                ":id",
                "status-history"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ]
            },
            "description": "Every recorded UJP status change of this e-invoice, oldest first; scope `einvoices:read`\n\nResponses:\n- 200: History\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Every error UJP (or the path to UJP) gave for this e-invoice, newest first, cursor-paginated",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices/:id/errors",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices",
                ":id",
                "errors"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ],
              "query": [
                {
                  "key": "cursor",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                }
              ]
            },
            "description": "Every error UJP (or the path to UJP) gave for this e-invoice, newest first, cursor-paginated; the latest is `lastError` on the e-invoice; scope `einvoices:read`\n\nResponses:\n- 200: Page\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Refresh status from UJP",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Set automatically by the collection's pre-request script."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices/:id/refresh-status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices",
                ":id",
                "refresh-status"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ]
            },
            "description": "Poll UJP now for this e-invoice's current status (needs a live signing agent for remote custody); scope `einvoices:write`\n\nResponses:\n- 200: Refreshed\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)\n- 503: ujp_unavailable"
          }
        },
        {
          "name": "Storno an e-invoice",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices/:id/storno",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices",
                ":id",
                "storno"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ]
            },
            "description": "Storno an e-invoice delivered/accepted/auto-accepted at UJP (negative mirror, void reason, ST reference); scope `einvoices:write`\n\nResponses:\n- 200: Idempotent replay\n- 202: Queued\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)\n- 503: ujp_unavailable",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"clientReference\": \"storno-2026-000481\",\n  \"number\": \"000482\",\n  \"issueDate\": \"2026-10-09\",\n  \"reasonCode\": \"S-1\",\n  \"comment\": null\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Correct an e-invoice",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices/:id/correction",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices",
                ":id",
                "correction"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ]
            },
            "description": "Correct a validated e-invoice with a full replacement (correction reason, ST reference); scope `einvoices:write`\n\nResponses:\n- 200: Idempotent replay\n- 202: Queued\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)\n- 503: ujp_unavailable",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reasonCode\": \"C01\",\n  \"comment\": \"Corrected unit price\",\n  \"replacement\": {\n    \"clientReference\": \"inv-2026-000481-c1\",\n    \"documentType\": \"100\",\n    \"number\": \"000483\",\n    \"issueDate\": \"2026-10-08\",\n    \"turnoverDate\": \"2026-10-08\",\n    \"deliveryDate\": null,\n    \"periodStart\": null,\n    \"periodEnd\": null,\n    \"notes\": null,\n    \"header\": null,\n    \"footer\": null,\n    \"buyer\": {\n      \"country\": \"MK\",\n      \"taxNumber\": \"4043022533490\",\n      \"foreignTaxNumber\": null,\n      \"vatNumber\": \"МК4043022533490\",\n      \"name\": \"МЕРОТ ДООЕЛ Скопје\",\n      \"address\": {\n        \"street\": \"ЈУЖНОМОРАВСКИ БРИГАДИ 4\",\n        \"number\": \"7б/-\",\n        \"postalCode\": \"1000\",\n        \"city\": \"СКОПЈЕ-Г. БАБА\"\n      },\n      \"subsidiaryCode\": null,\n      \"subsidiaryName\": null,\n      \"contact\": null,\n      \"email\": null\n    },\n    \"receiver\": null,\n    \"references\": [],\n    \"payment\": {\n      \"typeCode\": \"P12\",\n      \"dueDate\": \"2026-11-07\",\n      \"dueDays\": 30,\n      \"terms\": null,\n      \"note\": null,\n      \"currency\": \"MKD\",\n      \"exchangeRate\": null,\n      \"exchangeRateDate\": null\n    },\n    \"lines\": [\n      {\n        \"sku\": null,\n        \"description\": \"Консултантски услуги — септември 2026\",\n        \"unit\": \"услуга\",\n        \"quantity\": \"1\",\n        \"unitPrice\": \"9000.00\",\n        \"unitDiscount\": \"0\",\n        \"vatPercent\": \"18\",\n        \"taxIndicator\": \"DDV-A\",\n        \"domesticProduct\": null\n      }\n    ],\n    \"expectedTotals\": {\n      \"net\": \"9000.00\",\n      \"vat\": \"1620.00\",\n      \"gross\": \"10620.00\"\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Download the PDF",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/einvoices/:id/pdf",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "einvoices",
                ":id",
                "pdf"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ]
            },
            "description": "The UJP-rendered PDF from the archive (409 pdf_not_ready before the document settles); scope `einvoices:read`\n\nResponses:\n- 200: PDF bytes\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        }
      ]
    },
    {
      "name": "Inbox",
      "description": "Inbound e-invoices addressed to your companies.",
      "item": [
        {
          "name": "List inbox documents",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/inbox",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "inbox"
              ],
              "query": [
                {
                  "key": "cursor",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "pending",
                  "disabled": true
                },
                {
                  "key": "deadlineBefore",
                  "value": "2026-09-24",
                  "disabled": true
                }
              ]
            },
            "description": "Received e-invoices by decision deadline (cursor-paginated); scope `inbox:read`\n\nResponses:\n- 200: Page\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 429: rate_limited (Retry-After header carries the seconds)"
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.environment.get('inboxId')) {",
                  "  const b = pm.response.json(); const row = (b.data || b.items || [])[0];",
                  "  if (row) { pm.environment.set('inboxId', row.id); console.log('inboxId = ' + row.id); }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Retrieve an inbox document",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/inbox/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "inbox",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{inboxId}}"
                }
              ]
            },
            "description": "One received e-invoice, with its decision state and deadline; scope `inbox:read`\n\nResponses:\n- 200: Document\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Retrieve an inbox payload",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/inbox/:id/payload",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "inbox",
                ":id",
                "payload"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{inboxId}}"
                }
              ]
            },
            "description": "The exact UJP JSON payload of the received e-invoice, byte for byte; scope `inbox:read`\n\nResponses:\n- 200: Payload\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Accept an inbox document",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/inbox/:id/accept",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "inbox",
                ":id",
                "accept"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{inboxId}}"
                }
              ]
            },
            "description": "Accept a received e-invoice (draft чл. 11); refused past the decision deadline; scope `inbox:write`\n\nResponses:\n- 202: Decision queued\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"comment\": null\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Reject an inbox document",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/inbox/:id/reject",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "inbox",
                ":id",
                "reject"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{inboxId}}"
                }
              ]
            },
            "description": "Reject a received e-invoice with a reject_reasons codebook code (O-1…O-7); refused past the decision deadline; scope `inbox:write`\n\nResponses:\n- 202: Decision queued\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reasonCode\": \"O-2\",\n  \"comment\": \"Wrong amount\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    },
    {
      "name": "Webhooks and events",
      "description": "Webhook endpoints, delivery history, and the event log with replay.",
      "item": [
        {
          "name": "List webhook endpoints",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/webhook-endpoints",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "webhook-endpoints"
              ],
              "query": [
                {
                  "key": "cursor",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                }
              ]
            },
            "description": "Webhook endpoints of this environment (cursor-paginated); scope `webhooks:manage`\n\nResponses:\n- 200: Page\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 429: rate_limited (Retry-After header carries the seconds)"
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.environment.get('webhookEndpointId')) {",
                  "  const b = pm.response.json(); const row = (b.data || b.items || [])[0];",
                  "  if (row) { pm.environment.set('webhookEndpointId', row.id); console.log('webhookEndpointId = ' + row.id); }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Create a webhook endpoint",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/webhook-endpoints",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "webhook-endpoints"
              ]
            },
            "description": "Register a webhook endpoint (https only, SSRF-checked); the signing secret is returned once; scope `webhooks:manage`\n\nResponses:\n- 201: Created; `secret` is shown only here\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"url\": \"https://example.com/merot/webhooks\",\n  \"events\": [\n    \"einvoice.accepted\",\n    \"einvoice.rejected\"\n  ],\n  \"companyIds\": [\n    \"{{companyId}}\"\n  ],\n  \"description\": \"Production listener\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if ([200,201].includes(pm.response.code)) {",
                  "  const id = pm.response.json().id;",
                  "  if (id) { pm.environment.set('webhookEndpointId', id); console.log('webhookEndpointId = ' + id); }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Retrieve a webhook endpoint",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/webhook-endpoints/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "webhook-endpoints",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}"
                }
              ]
            },
            "description": "One webhook endpoint; scope `webhooks:manage`\n\nResponses:\n- 200: Endpoint\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Update a webhook endpoint",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/webhook-endpoints/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "webhook-endpoints",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}"
                }
              ]
            },
            "description": "Change url / events / companies / description, or re-enable a disabled endpoint; scope `webhooks:manage`\n\nResponses:\n- 200: Updated\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"events\": [\n    \"einvoice.accepted\",\n    \"einvoice.rejected\",\n    \"inbox.received\"\n  ],\n  \"description\": \"Production listener (accepted, rejected, inbox)\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Rotate the signing secret",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/webhook-endpoints/:id/rotate-secret",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "webhook-endpoints",
                ":id",
                "rotate-secret"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}"
                }
              ]
            },
            "description": "Issue a new signing secret; the previous one keeps signing (two `v1=` entries) for 24 h; scope `webhooks:manage`\n\nResponses:\n- 200: New secret, shown once\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Send a test event",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/webhook-endpoints/:id/test",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "webhook-endpoints",
                ":id",
                "test"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}"
                }
              ]
            },
            "description": "Send a `ping` event to the endpoint once (no retries) and return the delivery; scope `webhooks:manage`\n\nResponses:\n- 200: The ping delivery\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "List deliveries",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/webhook-endpoints/:id/deliveries",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "webhook-endpoints",
                ":id",
                "deliveries"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}"
                }
              ],
              "query": [
                {
                  "key": "cursor",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                },
                {
                  "key": "state",
                  "value": "pending",
                  "disabled": true
                }
              ]
            },
            "description": "Delivery log of one endpoint, one row per attempt (newest first); scope `webhooks:manage`\n\nResponses:\n- 200: Page\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "List events",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/events",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "events"
              ],
              "query": [
                {
                  "key": "cursor",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                },
                {
                  "key": "type",
                  "value": "einvoice.validated_failed",
                  "disabled": true
                },
                {
                  "key": "createdFrom",
                  "value": "2026-10-08T09:30:00Z",
                  "disabled": true
                }
              ]
            },
            "description": "Events of the last 30 days for the companies this key may reach (newest first); scope `webhooks:manage`\n\nResponses:\n- 200: Page\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)"
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.environment.get('eventId')) {",
                  "  const b = pm.response.json(); const row = (b.data || b.items || [])[0];",
                  "  if (row) { pm.environment.set('eventId', row.id); console.log('eventId = ' + row.id); }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Retrieve an event",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/events/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "events",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{eventId}}"
                }
              ]
            },
            "description": "One event (30 days); scope `webhooks:manage`\n\nResponses:\n- 200: Event\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Replay an event",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/events/:id/replay",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "events",
                ":id",
                "replay"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{eventId}}"
                }
              ]
            },
            "description": "Deliver an event again (new delivery, same event id, `isReplay`); scope `webhooks:manage`\n\nResponses:\n- 202: Queued\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"endpointId\": \"00000000-0000-4000-8000-000000000000\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Delete a webhook endpoint",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Set automatically by the collection's pre-request script."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/webhook-endpoints/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "webhook-endpoints",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{webhookEndpointId}}"
                }
              ]
            },
            "description": "Disable and hide a webhook endpoint (its delivery log is kept 30 days); scope `webhooks:manage`\n\nResponses:\n- 204: Deleted\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        }
      ]
    },
    {
      "name": "Archive",
      "description": "The 10-year archive: per-document artefacts and bulk exports.",
      "item": [
        {
          "name": "Archive artefacts of an e-invoice",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/archive/einvoices/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "archive",
                "einvoices",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ]
            },
            "description": "Archived artefacts (JSON/JWS/PDF) of one e-document, inbound or outbound; scope `archive:read`\n\nResponses:\n- 200: Artefacts (possibly empty before the archive step ran)\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Create an archive export",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/archive/exports",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "archive",
                "exports"
              ]
            },
            "description": "Queue a bulk export ZIP of archived artefacts over a date range; scope `archive:read`\n\nResponses:\n- 202: Queued\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 409: idempotency_conflict or company_already_linked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"environment\": \"sandbox\",\n  \"direction\": \"outbound\",\n  \"issuedFrom\": \"2026-10-01\",\n  \"issuedTo\": \"2026-10-31\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if ([200,201,202].includes(pm.response.code)) {",
                  "  const id = pm.response.json().id;",
                  "  if (id) { pm.environment.set('exportId', id); console.log('exportId = ' + id); }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Retrieve an archive export",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "X-Company-Id",
                "value": "{{companyId}}",
                "description": "Required when the key/token can reach more than one company."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/archive/exports/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "archive",
                "exports",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{exportId}}"
                }
              ]
            },
            "description": "Status of a queued export; `url` is set (15-min presigned) once `state` is `ready`; scope `archive:read`\n\nResponses:\n- 200: Export\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        }
      ]
    },
    {
      "name": "Sandbox",
      "description": "Sandbox-only helpers: simulate a UJP outcome, deliver an inbound test invoice.",
      "item": [
        {
          "name": "Simulate a UJP outcome",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/sandbox/einvoices/:id/simulate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "sandbox",
                "einvoices",
                ":id",
                "simulate"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{einvoiceId}}"
                }
              ]
            },
            "description": "Simulator only: advance a sandbox document status (sandbox keys; company backend must be simulator)\n\nResponses:\n- 200: OK\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"03\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Deliver a test inbox document",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required on every write except /oauth/token; a replay with a different body is refused with 409. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/sandbox/inbox",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "sandbox",
                "inbox"
              ]
            },
            "description": "Simulator only: deliver a synthetic inbox document (sandbox keys)\n\nResponses:\n- 201: Simulated inbox item\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"companyId\": \"{{companyId}}\",\n  \"fromTaxNumber\": \"4043022533490\",\n  \"lines\": []\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if ([200,201,202].includes(pm.response.code)) {",
                  "  const id = pm.response.json().id;",
                  "  if (id) { pm.environment.set('inboxId', id); console.log('inboxId = ' + id); }",
                  "}"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Bridge and signing",
      "description": "Endpoints used by Merot Bridge and by Mode B signers. Most integrations never call these directly. Requests authenticated as an agent (`Authorization: Agent …`) also need `Merot-Agent-Signature`, an Ed25519 signature with the agent's own key that Postman cannot compute: set `agentSignature` per request from your agent, or use the SDK.",
      "item": [
        {
          "name": "Pair a Bridge agent",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/agents/pair",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "agents",
                "pair"
              ]
            },
            "description": "Consume a pairing code (from the console) and issue an agent credential — shown once, no bearer, rate-limited 5/min/IP\n\nResponses:\n- 201: Paired\n- 401: unauthenticated or key_revoked\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"code\": \"{{pairingCode}}\",\n  \"kind\": \"sdk\",\n  \"name\": \"Signing service\",\n  \"platform\": \"server\",\n  \"version\": \"1.0.0\",\n  \"publicKeyJwk\": {\n    \"kty\": \"OKP\",\n    \"crv\": \"Ed25519\",\n    \"x\": \"{{agentPublicKeyX}}\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "auth": {
              "type": "noauth"
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 || pm.response.code === 201) {",
                  "  const b = pm.response.json();",
                  "  pm.environment.set('agentId', b.agentId || b.id);",
                  "  if (b.agentSecret || b.secret) pm.environment.set('agentSecret', b.agentSecret || b.secret);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Register an agent certificate",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Authorization",
                "value": "Agent {{agentId}}.{{agentSecret}}",
                "description": "`Agent <agentId>.<agentSecret>` — issued once by POST /v1/agents/pair."
              },
              {
                "key": "Merot-Agent-Signature",
                "value": "{{agentSignature}}",
                "description": "t=<unix seconds>,sig=<base64url Ed25519 signature over \"t.METHOD.path.sha256hex(body)\"> with the agent's device key; ±60 s. Postman cannot compute Ed25519 — sign outside Postman or use the SDK."
              },
              {
                "key": "Merot-Agent-Signature",
                "value": "",
                "description": "Ed25519 over `t.method.path.sha256(body)` with the agent device key, ±60s.",
                "disabled": false
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/agents/:id/certificates",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "agents",
                ":id",
                "certificates"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{agentId}}"
                }
              ]
            },
            "description": "Register/link a bridge or sdk custody certificate for one of the agent’s paired companies\n\nResponses:\n- 201: Registered\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 422: validation_failed",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"certificateDer\": \"{{certificateDerBase64}}\",\n  \"companyId\": \"{{companyId}}\",\n  \"proof\": \"{{certificateProof}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "auth": {
              "type": "noauth"
            }
          }
        },
        {
          "name": "Long-poll for signing requests",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Authorization",
                "value": "Agent {{agentId}}.{{agentSecret}}",
                "description": "`Agent <agentId>.<agentSecret>` — issued once by POST /v1/agents/pair."
              },
              {
                "key": "Merot-Agent-Signature",
                "value": "{{agentSignature}}",
                "description": "t=<unix seconds>,sig=<base64url Ed25519 signature over \"t.METHOD.path.sha256hex(body)\"> with the agent's device key; ±60 s. Postman cannot compute Ed25519 — sign outside Postman or use the SDK."
              },
              {
                "key": "Merot-Agent-Signature",
                "value": "",
                "description": "Ed25519 over `t.method.path.sha256(body)` with the agent device key, ±60s.",
                "disabled": false
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/agents/:id/signing-requests",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "agents",
                ":id",
                "signing-requests"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{agentId}}"
                }
              ],
              "query": [
                {
                  "key": "wait",
                  "value": "1",
                  "disabled": true
                }
              ]
            },
            "description": "Long-poll fallback of the WS stream: pending signing requests for this agent’s certificates (wait 1-30s)\n\nResponses:\n- 200: Pending requests (possibly empty)\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)",
            "auth": {
              "type": "noauth"
            }
          }
        },
        {
          "name": "Claim a signing request",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Authorization",
                "value": "Agent {{agentId}}.{{agentSecret}}",
                "description": "`Agent <agentId>.<agentSecret>` — issued once by POST /v1/agents/pair."
              },
              {
                "key": "Merot-Agent-Signature",
                "value": "{{agentSignature}}",
                "description": "t=<unix seconds>,sig=<base64url Ed25519 signature over \"t.METHOD.path.sha256hex(body)\"> with the agent's device key; ±60 s. Postman cannot compute Ed25519 — sign outside Postman or use the SDK."
              },
              {
                "key": "Merot-Agent-Signature",
                "value": "",
                "description": "Ed25519 over `t.method.path.sha256(body)` with the agent device key, ±60s.",
                "disabled": false
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signing-requests/:id/claim",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signing-requests",
                ":id",
                "claim"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{signingRequestId}}"
                }
              ]
            },
            "description": "Claim a pending signing request (idempotent per agent; 409 if another agent already claimed it)\n\nResponses:\n- 200: Claimed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked",
            "auth": {
              "type": "noauth"
            }
          }
        },
        {
          "name": "List signing requests",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signing-requests",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signing-requests"
              ],
              "query": [
                {
                  "key": "cursor",
                  "value": "string",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                },
                {
                  "key": "state",
                  "value": "pending",
                  "disabled": true
                },
                {
                  "key": "companyId",
                  "value": "00000000-0000-4000-8000-000000000000",
                  "disabled": true
                }
              ]
            },
            "description": "Mode B inline signing: signing requests for the key’s `sdk`-custody certificates (default `state=pending`), oldest first, cursor-paginated; scope `signing:agent` (API key only)\n\nResponses:\n- 200: Signing requests (possibly empty)\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 429: rate_limited (Retry-After header carries the seconds)"
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 && !pm.environment.get('signingRequestId')) {",
                  "  const b = pm.response.json(); const row = (b.data || b.items || [])[0];",
                  "  if (row) { pm.environment.set('signingRequestId', row.id); console.log('signingRequestId = ' + row.id); }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Submit a signature",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Authorization",
                "value": "Bearer {{apiKey}}",
                "description": "Agent credential (`Agent <agentId>.<agentSecret>`) or an API key (`Bearer mfk_...`, scope `signing:agent`; OAuth tokens are refused)."
              },
              {
                "key": "Merot-Agent-Signature",
                "value": "",
                "description": "Required for the agent credential only: Ed25519 over `t.method.path.sha256(body)` with the agent device key, ±60s.",
                "disabled": true
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotencyKey}}",
                "description": "Required for the API-key credential (400 `idempotency_key_required` otherwise); a replay with the same key and body returns the first response. Set automatically by the collection's pre-request script."
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signing-requests/:id/signature",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signing-requests",
                ":id",
                "signature"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{signingRequestId}}"
                }
              ]
            },
            "description": "Submit the compact JWS for a signing request: an agent submits a request it claimed; an API key (scope `signing:agent`) submits straight for a pending `sdk`-custody request (Mode B inline)\n\nResponses:\n- 200: Signed (an identical resubmission by the API key is also 200)\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 409: idempotency_conflict or company_already_linked\n- 410: Error\n- 422: validation_failed\n- 429: rate_limited (Retry-After header carries the seconds)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"jws\": \"{{signedJws}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "auth": {
              "type": "noauth"
            }
          }
        },
        {
          "name": "Refuse a signing request",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              },
              {
                "key": "Authorization",
                "value": "Agent {{agentId}}.{{agentSecret}}",
                "description": "`Agent <agentId>.<agentSecret>` — issued once by POST /v1/agents/pair."
              },
              {
                "key": "Merot-Agent-Signature",
                "value": "{{agentSignature}}",
                "description": "t=<unix seconds>,sig=<base64url Ed25519 signature over \"t.METHOD.path.sha256hex(body)\"> with the agent's device key; ±60 s. Postman cannot compute Ed25519 — sign outside Postman or use the SDK."
              },
              {
                "key": "Merot-Agent-Signature",
                "value": "",
                "description": "Ed25519 over `t.method.path.sha256(body)` with the agent device key, ±60s.",
                "disabled": false
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/signing-requests/:id/refuse",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "signing-requests",
                ":id",
                "refuse"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{signingRequestId}}"
                }
              ]
            },
            "description": "Refuse a claimed signing request (user_declined, policy, token_missing, pin_locked, payload_invalid)\n\nResponses:\n- 200: Refused\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 404: not_found\n- 410: Error",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reason\": \"user_declined\",\n  \"message\": \"Declined by the operator\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "auth": {
              "type": "noauth"
            }
          }
        },
        {
          "name": "List Merot Bridge releases",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/bridge/releases",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "bridge",
                "releases"
              ],
              "query": [
                {
                  "key": "channel",
                  "value": "stable",
                  "disabled": true
                }
              ]
            },
            "description": "Published Merot Bridge releases (installer downloads, version history); cacheable\n\nResponses:\n- 200: Releases\n- 422: validation_failed",
            "auth": {
              "type": "noauth"
            }
          }
        }
      ]
    },
    {
      "name": "Usage and health",
      "description": "Service health and account usage.",
      "item": [
        {
          "name": "Usage",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/usage",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "usage"
              ],
              "query": [
                {
                  "key": "period",
                  "value": "2026-10",
                  "disabled": false
                },
                {
                  "key": "companyId",
                  "value": "00000000-0000-4000-8000-000000000000",
                  "disabled": true
                },
                {
                  "key": "environment",
                  "value": "sandbox",
                  "disabled": false
                }
              ]
            },
            "description": "Document usage for a calendar month (production billable; sandbox shown separately)\n\nResponses:\n- 200: Usage report\n- 400: company_required, idempotency_key_required, or validation_failed\n- 401: unauthenticated or key_revoked\n- 403: insufficient_scope, company_not_allowed, environment_mismatch, production_not_enabled or mandate_required (the client company has not accepted the mandate yet)\n- 429: rate_limited (Retry-After header carries the seconds)"
          }
        },
        {
          "name": "Health",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Merot-Version",
                "value": "{{merotVersion}}",
                "description": "Pinned API version."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/health",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "health"
              ]
            },
            "description": "Service health and cached UJP reachability (no credential; the UJP probe result is cached for at least 30 s)\n\nResponses:\n- 200: Healthy\n- 503: Degraded (database unreachable)",
            "auth": {
              "type": "noauth"
            }
          }
        }
      ]
    }
  ]
}
