Authentication

API keys, scopes, and security best practices

How It Works

The MOR API uses API keys for authentication. Include your key in the Authorization header of every request.

cURL
# Include your API key in the Authorization header
curl -X POST https://api.mor.gov.et/v1/receipts \
-H "Authorization: Bearer mor_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"merchant_tin": "0012345678",
"device_id": "dev_456abc",
"items": [{"description": "Coffee", "quantity": 1, "unit_price": "80.00", "vat_rate": 15}],
"payment_method": "CASH"
}'
Python SDK
from mor_sdk import MorClient
# Initialize with your API key
client = MorClient(api_key="mor_live_xxxxxxxxxxxxxxxxxxxx")
# The SDK handles the Authorization header automatically
receipt = client.receipts.create(
merchant_tin="0012345678",
device_id="dev_456abc",
items=[{"description": "Coffee", "quantity": 1, "unit_price": "80.00", "vat_rate": 15}],
payment_method="CASH",
)

Environments

EnvironmentKey PrefixNotes
Sandboxmor_test_Free. No real fiscal codes. Rate limited to 60 req/min.
Productionmor_live_Requires TIN verification. Generates real fiscal codes. Subject to your plan rate limits.

API Scopes

Each API key is scoped to specific permissions. Request only the scopes your application needs (principle of least privilege).

receipts:read

View fiscal receipts and transaction history.

GET /v1/receiptsGET /v1/receipts/{id}
receipts:write

Issue new fiscal receipts and void existing ones.

POST /v1/receiptsPOST /v1/receipts/{id}/void
devices:read

View Virtual Fiscal Device information and reports.

GET /v1/devicesGET /v1/devices/{id}GET /v1/devices/{id}/reports/x
devices:manage

Register, activate, suspend, and revoke VFDs. Generate Z-Reports.

POST /v1/devicesPOST /v1/devices/{id}/activatePOST /v1/devices/{id}/suspendPOST /v1/devices/{id}/revokePOST /v1/devices/{id}/reports/z
analytics:read

Access API usage analytics and reports.

GET /v1/api-keys/{id}/analytics
webhooks:manage

Create, update, and delete webhook subscriptions.

GET /v1/webhooksPOST /v1/webhooksDELETE /v1/webhooks/{id}

Security Best Practices

Never expose keys in client-side code

API keys are server-side only. Never include them in browser JavaScript, mobile apps, or public repositories.

Use environment variables

Store keys in environment variables (e.g., MOR_API_KEY), never hardcoded in source files.

Rotate keys regularly

Rotate production keys every 90 days. Use the dashboard to generate a new key before revoking the old one.

Use separate keys per environment

Never use a production key (mor_live_) in development. Create separate sandbox keys (mor_test_) for testing.

Set expiration dates

Configure key expiration (30, 60, 90, or 180 days) to limit the blast radius of a compromised key.

Minimize scopes

A POS terminal only needs receipts:write and devices:read — it does not need webhooks:manage or analytics:read.

Example: POS System Key Configuration

A typical POS system needs these scopes:

receipts:write

Issue receipts at checkout

receipts:read

Look up past receipts

devices:read

Check device status

devices:manage

Generate daily Z-Reports