{
  "info": {
    "name": "Esnad API",
    "description": "# Esnad Phase 2 e-invoicing API\n\nCustomer-facing endpoints for integrators using **API key** auth.\n\n## Import\n1. Download both files (or the zip) from https://docs.esnadapi.com/docs/collection :\n   - `Esnad-API.collection.json`\n   - `Esnad-API.environment.json`\n2. Import into Postman, Insomnia, Bruno, Hoppscotch, or any client that supports Postman Collection v2.1.\n3. Select the **Esnad API** environment (if your tool uses environments).\n4. Set `apiKey` to your `zatca_test_…` (sandbox) or `zatca_live_…` (production) key.\n\n`baseUrl` is **https://api.esnadapi.com**. Import the environment file as well as the collection.\n\n## Flow\n1. Create company + API key in the Esnad dashboard (https://app.esnadapi.com).\n2. Create an EGS unit → poll status until `active` → submit invoices with `egs_unit_id`.\nMultiple companies (different VATs): add each company and its key in the dashboard, then use that key here.\nAPI keys, companies, webhooks UI, and billing are dashboard-only — not in this collection.\nSandbox OTP for ZATCA developer-portal is typically `123345` (use with `zatca_test_` keys).\n\nDocs: https://docs.esnadapi.com/docs/collection",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{apiKey}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.esnadapi.com"
    },
    {
      "key": "apiKey",
      "value": "zatca_test_REPLACE_ME"
    },
    {
      "key": "egs_unit_id",
      "value": ""
    },
    {
      "key": "invoice_id",
      "value": ""
    },
    {
      "key": "invoice_uuid",
      "value": ""
    },
    {
      "key": "idempotency_key",
      "value": "{{$guid}}"
    }
  ],
  "item": [
    {
      "name": "0. Auth",
      "description": "Verify API key credentials before EGS or invoice calls. Read-only — does not list or manage keys.",
      "item": [
        {
          "name": "Verify API key (auth context)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "User-Agent",
                "value": "MyApp/1.0",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/auth/context",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "auth",
                "context"
              ]
            },
            "description": "Returns tenant id, plan, environment (sandbox/production), and masked metadata for the authenticated API key. Use as a lightweight connectivity check."
          }
        }
      ]
    },
    {
      "name": "1. EGS units",
      "description": "Each EGS unit = one branch/POS with its own ZATCA CSID and PIH chain. Sandbox OTP for developer-portal is typically `123345`.",
      "item": [
        {
          "name": "Create EGS unit",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/egs",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "egs"
              ]
            },
            "description": "Creates unit and starts onboarding when `otp` is provided. Returns 202 with `egs_unit_id` and `poll_url`. Saves `egs_unit_id` to collection variables.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"unit_name\": \"Main Branch POS\",\n  \"invoice_type\": \"both\",\n  \"phase\": 2,\n  \"environment\": \"sandbox\",\n  \"otp\": \"123345\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 201 || pm.response.code === 202) {",
                  "  const j = pm.response.json();",
                  "  if (j.egs_unit_id) {",
                  "    pm.collectionVariables.set('egs_unit_id', j.egs_unit_id);",
                  "    if (pm.environment && pm.environment.name) pm.environment.set('egs_unit_id', j.egs_unit_id);",
                  "    console.log('Saved egs_unit_id:', j.egs_unit_id);",
                  "  }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Get EGS status",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/egs/{{egs_unit_id}}/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "egs",
                "{{egs_unit_id}}",
                "status"
              ]
            },
            "description": "Poll until `onboarding_status` is `active` before issuing invoices."
          }
        },
        {
          "name": "Request production CSID",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/egs/{{egs_unit_id}}/request-production",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "egs",
                "{{egs_unit_id}}",
                "request-production"
              ]
            },
            "description": "Phase 2 production only. Use a real Fatoora OTP with a `zatca_live_` key.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"otp\": \"123456\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Renew certificate",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/egs/{{egs_unit_id}}/renew",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "egs",
                "{{egs_unit_id}}",
                "renew"
              ]
            },
            "description": "Async renew (202). Requires fresh OTP from Fatoora.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"otp\": \"123456\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "List EGS units (status)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/compliance/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "compliance",
                "status"
              ],
              "query": [
                {
                  "key": "environment",
                  "value": "sandbox",
                  "description": "sandbox | production",
                  "disabled": false
                }
              ]
            },
            "description": "Optional: returns usage and `egs_units[]` for your tenant (there is no GET /v1/egs list). ZATCA compliance runs automatically during onboarding."
          }
        }
      ]
    },
    {
      "name": "2. Invoices",
      "description": "`egs_unit_id` is **required** on every create. Unit must be active and match the API key environment.",
      "item": [
        {
          "name": "Create simplified (B2C)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotency_key}}",
                "type": "text",
                "description": "Optional; safe retries with same body"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices/simplified",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices",
                "simplified"
              ]
            },
            "description": "Signs, persists, reports to ZATCA. HTTP 200 when reported inline; HTTP 202 when queued. Returns QR + pdf_url.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"egs_unit_id\": \"{{egs_unit_id}}\",\n  \"invoice_number\": \"INV-{{$timestamp}}\",\n  \"invoice_date\": \"2026-07-23\",\n  \"invoice_time\": \"14:30:00\",\n  \"seller\": {\n    \"name\": \"Al Noor Trading Co.\",\n    \"name_ar\": \"شركة النور التجارية\",\n    \"vat_number\": \"310122393500003\",\n    \"address\": {\n      \"street\": \"King Fahd Road\",\n      \"city\": \"Riyadh\",\n      \"postal_code\": \"12271\",\n      \"country\": \"SA\"\n    }\n  },\n  \"line_items\": [\n    {\n      \"description\": \"Cappuccino\",\n      \"description_ar\": \"كابتشينو\",\n      \"quantity\": 2,\n      \"unit_price\": 18,\n      \"vat_category\": \"S\"\n    }\n  ],\n  \"currency\": \"SAR\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 || pm.response.code === 202) {",
                  "  const j = pm.response.json();",
                  "  if (j.invoice_id) {",
                  "    pm.collectionVariables.set('invoice_id', j.invoice_id);",
                  "    if (pm.environment && pm.environment.name) pm.environment.set('invoice_id', j.invoice_id);",
                  "  }",
                  "  if (j.uuid) {",
                  "    pm.collectionVariables.set('invoice_uuid', j.uuid);",
                  "    if (pm.environment && pm.environment.name) pm.environment.set('invoice_uuid', j.uuid);",
                  "  }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Create standard (B2B)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotency_key}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices/standard",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices",
                "standard"
              ]
            },
            "description": "Signs, persists, requests ZATCA clearance. HTTP 200 when cleared inline; HTTP 202 when queued. Buyer is required.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"egs_unit_id\": \"{{egs_unit_id}}\",\n  \"invoice_number\": \"STD-{{$timestamp}}\",\n  \"invoice_date\": \"2026-07-23\",\n  \"invoice_time\": \"14:30:00\",\n  \"seller\": {\n    \"name\": \"Al Noor Trading Co.\",\n    \"name_ar\": \"شركة النور التجارية\",\n    \"vat_number\": \"310122393500003\",\n    \"address\": {\n      \"street\": \"King Fahd Road\",\n      \"city\": \"Riyadh\",\n      \"postal_code\": \"12271\",\n      \"country\": \"SA\"\n    }\n  },\n  \"buyer\": {\n    \"name\": \"Gulf Solutions LLC\",\n    \"name_ar\": \"شركة الخليج للحلول\",\n    \"vat_number\": \"310987654300003\",\n    \"address\": {\n      \"street\": \"Prince Mohammed Bin Abdulaziz Road\",\n      \"city\": \"Jeddah\",\n      \"postal_code\": \"23435\",\n      \"country\": \"SA\"\n    }\n  },\n  \"line_items\": [\n    {\n      \"description\": \"Software License\",\n      \"quantity\": 1,\n      \"unit_price\": 5000,\n      \"vat_category\": \"S\"\n    }\n  ],\n  \"currency\": \"SAR\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 || pm.response.code === 202) {",
                  "  const j = pm.response.json();",
                  "  if (j.invoice_id) {",
                  "    pm.collectionVariables.set('invoice_id', j.invoice_id);",
                  "    if (pm.environment && pm.environment.name) pm.environment.set('invoice_id', j.invoice_id);",
                  "  }",
                  "  if (j.uuid) {",
                  "    pm.collectionVariables.set('invoice_uuid', j.uuid);",
                  "    if (pm.environment && pm.environment.name) pm.environment.set('invoice_uuid', j.uuid);",
                  "  }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Create credit note",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotency_key}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices/credit-note",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices",
                "credit-note"
              ]
            },
            "description": "References original invoice. Same hybrid submit as create: HTTP 200 when reported/cleared inline; HTTP 202 when queued.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"egs_unit_id\": \"{{egs_unit_id}}\",\n  \"invoice_number\": \"CN-{{$timestamp}}\",\n  \"invoice_date\": \"2026-07-23\",\n  \"invoice_time\": \"15:00:00\",\n  \"original_invoice_uuid\": \"{{invoice_uuid}}\",\n  \"reason\": \"Goods returned\",\n  \"seller\": {\n    \"name\": \"Al Noor Trading Co.\",\n    \"name_ar\": \"شركة النور التجارية\",\n    \"vat_number\": \"310122393500003\",\n    \"address\": {\n      \"street\": \"King Fahd Road\",\n      \"city\": \"Riyadh\",\n      \"postal_code\": \"12271\",\n      \"country\": \"SA\"\n    }\n  },\n  \"line_items\": [\n    {\n      \"description\": \"Returned item\",\n      \"quantity\": 1,\n      \"unit_price\": 18,\n      \"vat_category\": \"S\"\n    }\n  ],\n  \"currency\": \"SAR\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 || pm.response.code === 202) {",
                  "  const j = pm.response.json();",
                  "  if (j.invoice_id) {",
                  "    pm.collectionVariables.set('invoice_id', j.invoice_id);",
                  "    if (pm.environment && pm.environment.name) pm.environment.set('invoice_id', j.invoice_id);",
                  "  }",
                  "  if (j.uuid) {",
                  "    pm.collectionVariables.set('invoice_uuid', j.uuid);",
                  "    if (pm.environment && pm.environment.name) pm.environment.set('invoice_uuid', j.uuid);",
                  "  }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Create debit note",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotency_key}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices/debit-note",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices",
                "debit-note"
              ]
            },
            "description": "Same body as credit note. Hybrid submit: HTTP 200 when reported/cleared inline; HTTP 202 when queued.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"egs_unit_id\": \"{{egs_unit_id}}\",\n  \"invoice_number\": \"DN-{{$timestamp}}\",\n  \"invoice_date\": \"2026-07-23\",\n  \"invoice_time\": \"15:00:00\",\n  \"original_invoice_uuid\": \"{{invoice_uuid}}\",\n  \"reason\": \"Additional charges\",\n  \"seller\": {\n    \"name\": \"Al Noor Trading Co.\",\n    \"name_ar\": \"شركة النور التجارية\",\n    \"vat_number\": \"310122393500003\",\n    \"address\": {\n      \"street\": \"King Fahd Road\",\n      \"city\": \"Riyadh\",\n      \"postal_code\": \"12271\",\n      \"country\": \"SA\"\n    }\n  },\n  \"buyer\": {\n    \"name\": \"Gulf Solutions LLC\",\n    \"name_ar\": \"شركة الخليج للحلول\",\n    \"vat_number\": \"310987654300003\",\n    \"address\": {\n      \"street\": \"Prince Mohammed Bin Abdulaziz Road\",\n      \"city\": \"Jeddah\",\n      \"postal_code\": \"23435\",\n      \"country\": \"SA\"\n    }\n  },\n  \"line_items\": [\n    {\n      \"description\": \"Extra service\",\n      \"quantity\": 1,\n      \"unit_price\": 100,\n      \"vat_category\": \"S\"\n    }\n  ],\n  \"currency\": \"SAR\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 || pm.response.code === 202) {",
                  "  const j = pm.response.json();",
                  "  if (j.invoice_id) {",
                  "    pm.collectionVariables.set('invoice_id', j.invoice_id);",
                  "    if (pm.environment && pm.environment.name) pm.environment.set('invoice_id', j.invoice_id);",
                  "  }",
                  "  if (j.uuid) {",
                  "    pm.collectionVariables.set('invoice_uuid', j.uuid);",
                  "    if (pm.environment && pm.environment.name) pm.environment.set('invoice_uuid', j.uuid);",
                  "  }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "List invoices",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "20"
                },
                {
                  "key": "egs_unit_id",
                  "value": "{{egs_unit_id}}",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "reported",
                  "disabled": true
                },
                {
                  "key": "environment",
                  "value": "sandbox",
                  "disabled": true
                },
                {
                  "key": "cursor",
                  "value": "",
                  "disabled": true
                }
              ]
            },
            "description": ""
          }
        },
        {
          "name": "Get invoice",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices/{{invoice_id}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices",
                "{{invoice_id}}"
              ]
            },
            "description": "Detail + timeline + download URLs. When status is queued or failed, includes retry_count, next_retry_at, and last_error."
          }
        },
        {
          "name": "Download signed XML",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices/{{invoice_id}}/xml",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices",
                "{{invoice_id}}",
                "xml"
              ]
            },
            "description": "Returns application/xml."
          }
        },
        {
          "name": "Download PDF",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices/{{invoice_id}}/pdf",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices",
                "{{invoice_id}}",
                "pdf"
              ]
            },
            "description": "Returns application/pdf."
          }
        }
      ]
    },
    {
      "name": "3. Reference",
      "item": [
        {
          "name": "Discount / allowance reason codes",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/reference/discount-reasons",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "reference",
                "discount-reasons"
              ]
            },
            "description": ""
          }
        }
      ]
    }
  ]
}