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.
# Include your API key in the Authorization headercurl -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" }'from mor_sdk import MorClient
# Initialize with your API keyclient = MorClient(api_key="mor_live_xxxxxxxxxxxxxxxxxxxx")
# The SDK handles the Authorization header automaticallyreceipt = 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
| Environment | Key Prefix | Notes |
|---|---|---|
| Sandbox | mor_test_ | Free. No real fiscal codes. Rate limited to 60 req/min. |
| Production | mor_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:readView fiscal receipts and transaction history.
GET /v1/receiptsGET /v1/receipts/{id}receipts:writeIssue new fiscal receipts and void existing ones.
POST /v1/receiptsPOST /v1/receipts/{id}/voiddevices:readView Virtual Fiscal Device information and reports.
GET /v1/devicesGET /v1/devices/{id}GET /v1/devices/{id}/reports/xdevices:manageRegister, 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/zanalytics:readAccess API usage analytics and reports.
GET /v1/api-keys/{id}/analyticswebhooks:manageCreate, 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:writeIssue receipts at checkout
receipts:readLook up past receipts
devices:readCheck device status
devices:manageGenerate daily Z-Reports