OpenAPI specification
The complete NuePay API contract.
{
"openapi": "3.0.3",
"info": {
"title": "NuePay Merchant API",
"version": "1.0.0",
"description": "UGX mobile money collections and disbursements. Each named key identifies one application. Never send a nickname for authentication. Secrets belong on your server. Quotes do not initiate payments. A different X-Request-Id response header identifies each HTTP attempt; data.request_id is the original payment idempotency UUID."
},
"servers": [
{
"url": "https://api.nuepay.net/v1",
"description": "NuePay API"
}
],
"security": [
{
"BearerAuth": []
}
],
"paths": {
"/collections": {
"post": {
"summary": "Collect mobile money into the wallet",
"operationId": "collections",
"description": "Returns process initially. Only success confirms payment. Identical retries return the same payment. Test keys use simulated funds and never move real money.",
"parameters": [
{
"name": "Idempotency-Key",
"in": "header",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Keep the same UUID when retrying the same payment."
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"amount",
"currency",
"phone"
],
"properties": {
"amount": {
"type": "string",
"pattern": "^\\d+(\\.\\d{1,2})?$",
"example": "500.00",
"description": "Wallet principal for collections; recipient amount for disbursements."
},
"currency": {
"type": "string",
"enum": [
"UGX"
]
},
"phone": {
"type": "string",
"example": "0772000000",
"description": "Uganda MTN or Airtel number; local or +256 format."
},
"merchant_reference": {
"type": "string",
"maxLength": 120,
"example": "order-123",
"description": "Your order reference; not used for idempotency."
},
"description": {
"type": "string",
"maxLength": 140,
"description": "Optional payment note."
}
}
}
}
}
},
"responses": {
"202": {
"description": "Accepted for processing.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaymentResponse"
}
}
},
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"200": {
"description": "Existing payment returned for an identical retry.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaymentResponse"
}
}
},
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"203": {
"description": "Invalid credentials.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"204": {
"description": "Access unavailable or operation paused.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"205": {
"description": "Resource not found in this application and environment.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"206": {
"description": "Idempotency conflict, insufficient funds, or payout setup required.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"207": {
"description": "Invalid input; inspect errors and code.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"208": {
"description": "Rate limit exceeded.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"209": {
"description": "Live provider unavailable; accepted payments can still be read or retried.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
}
}
}
},
"/disbursements": {
"post": {
"summary": "Send mobile money from the wallet",
"operationId": "disbursements",
"description": "Returns process initially. Only success confirms payment. Identical retries return the same payment. Test keys use simulated funds and never move real money.",
"parameters": [
{
"name": "Idempotency-Key",
"in": "header",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
},
"description": "Keep the same UUID when retrying the same payment."
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"amount",
"currency",
"phone"
],
"properties": {
"amount": {
"type": "string",
"pattern": "^\\d+(\\.\\d{1,2})?$",
"example": "500.00",
"description": "Wallet principal for collections; recipient amount for disbursements."
},
"currency": {
"type": "string",
"enum": [
"UGX"
]
},
"phone": {
"type": "string",
"example": "0772000000",
"description": "Uganda MTN or Airtel number; local or +256 format."
},
"merchant_reference": {
"type": "string",
"maxLength": 120,
"example": "order-123",
"description": "Your order reference; not used for idempotency."
},
"description": {
"type": "string",
"maxLength": 140,
"description": "Optional payment note."
}
}
}
}
}
},
"responses": {
"202": {
"description": "Accepted for processing.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaymentResponse"
}
}
},
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"200": {
"description": "Existing payment returned for an identical retry.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaymentResponse"
}
}
},
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"203": {
"description": "Invalid credentials.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"204": {
"description": "Access unavailable or operation paused.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"205": {
"description": "Resource not found in this application and environment.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"206": {
"description": "Idempotency conflict, insufficient funds, or payout setup required.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"207": {
"description": "Invalid input; inspect errors and code.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"208": {
"description": "Rate limit exceeded.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"209": {
"description": "Live provider unavailable; accepted payments can still be read or retried.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
}
}
}
},
"/quotes": {
"post": {
"summary": "Preview the fee and exact charge or debit without moving funds",
"operationId": "quote",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"type",
"amount",
"currency"
],
"properties": {
"type": {
"type": "string",
"enum": [
"collection",
"disbursement"
]
},
"amount": {
"type": "string",
"pattern": "^\\d+(\\.\\d{1,2})?$",
"example": "500.00",
"description": "Wallet principal for collections; recipient amount for disbursements."
},
"currency": {
"type": "string",
"enum": [
"UGX"
]
}
}
}
}
}
},
"responses": {
"200": {
"description": "Quote in UGX decimal strings. Collection total is rounded up to whole UGX. Quotes do not reserve funds or guarantee provider availability.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QuoteResponse"
}
}
},
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"201": {
"description": "Invalid credentials.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"202": {
"description": "Access unavailable or operation paused.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"203": {
"description": "Resource not found in this application and environment.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"204": {
"description": "Idempotency conflict, insufficient funds, or payout setup required.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"205": {
"description": "Invalid input; inspect errors and code.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"206": {
"description": "Rate limit exceeded.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"207": {
"description": "Live provider unavailable; accepted payments can still be read or retried.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
}
}
}
},
"/application": {
"get": {
"summary": "Identify the authenticated application and environment",
"operationId": "application",
"responses": {
"200": {
"description": "application_id, application_name, account_number, mode, livemode.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApplicationResponse"
}
}
},
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"201": {
"description": "Invalid credentials.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"202": {
"description": "Access unavailable or operation paused.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"203": {
"description": "Resource not found in this application and environment.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"204": {
"description": "Idempotency conflict, insufficient funds, or payout setup required.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"205": {
"description": "Invalid input; inspect errors and code.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"206": {
"description": "Rate limit exceeded.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"207": {
"description": "Live provider unavailable; accepted payments can still be read or retried.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
}
}
}
},
"/account/balance": {
"get": {
"summary": "Read the shared account balance in this environment",
"operationId": "balance",
"responses": {
"200": {
"description": "UGX available, pending and locked decimal strings. Test balances are isolated from real wallets.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BalanceResponse"
}
}
},
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"201": {
"description": "Invalid credentials.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"202": {
"description": "Access unavailable or operation paused.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"203": {
"description": "Resource not found in this application and environment.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"204": {
"description": "Idempotency conflict, insufficient funds, or payout setup required.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"205": {
"description": "Invalid input; inspect errors and code.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"206": {
"description": "Rate limit exceeded.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"207": {
"description": "Live provider unavailable; accepted payments can still be read or retried.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
}
}
}
},
"/transactions/{reference}": {
"get": {
"summary": "Read a payment created by this application in this environment",
"operationId": "transaction",
"parameters": [
{
"name": "reference",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Current local payment state.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaymentResponse"
}
}
},
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"201": {
"description": "Invalid credentials.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"202": {
"description": "Access unavailable or operation paused.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"203": {
"description": "Resource not found in this application and environment.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"204": {
"description": "Idempotency conflict, insufficient funds, or payout setup required.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"205": {
"description": "Invalid input; inspect errors and code.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"206": {
"description": "Rate limit exceeded.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"207": {
"description": "Live provider unavailable; accepted payments can still be read or retried.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
}
}
}
},
"/sandbox/transactions/{reference}/simulate": {
"post": {
"summary": "Simulate an outcome using a test key",
"operationId": "simulate",
"parameters": [
{
"name": "reference",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"description": "Live keys are rejected. Timeout stays process with awaiting_confirmation; it can subsequently succeed or fail. Repeating the same outcome does not repeat credits or refunds.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"outcome"
],
"properties": {
"outcome": {
"type": "string",
"enum": [
"success",
"failed",
"timeout"
]
}
}
}
}
}
},
"responses": {
"200": {
"description": "Simulated result.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaymentResponse"
}
}
},
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"201": {
"description": "Invalid credentials.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"202": {
"description": "Access unavailable or operation paused.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"203": {
"description": "Resource not found in this application and environment.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"204": {
"description": "Idempotency conflict, insufficient funds, or payout setup required.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"205": {
"description": "Invalid input; inspect errors and code.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"206": {
"description": "Rate limit exceeded.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
},
"207": {
"description": "Live provider unavailable; accepted payments can still be read or retried.",
"headers": {
"X-Request-Id": {
"description": "Identifier for this HTTP attempt.",
"schema": {
"type": "string",
"format": "uuid"
}
}
}
}
}
}
}
},
"components": {
"securitySchemes": {
"BearerAuth": {
"type": "http",
"scheme": "bearer",
"description": "np_live_ for real payments, np_test_ for sandbox."
}
},
"schemas": {
"PaymentResponse": {
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"reference": {
"type": "string",
"nullable": false
},
"project_id": {
"type": "string",
"nullable": false
},
"application_id": {
"type": "string",
"nullable": false
},
"application_name": {
"type": "string",
"nullable": true
},
"request_id": {
"type": "string",
"nullable": false
},
"idempotency_key": {
"type": "string",
"nullable": false
},
"merchant_reference": {
"type": "string",
"nullable": true
},
"status_reason": {
"type": "string",
"nullable": true
},
"amount": {
"type": "string",
"nullable": false
},
"fee": {
"type": "string",
"nullable": false
},
"gross_amount": {
"type": "string",
"nullable": false
},
"currency": {
"type": "string",
"nullable": false
},
"payer_charge": {
"type": "string",
"nullable": true
},
"wallet_credit": {
"type": "string",
"nullable": true
},
"recipient_amount": {
"type": "string",
"nullable": true
},
"wallet_debit": {
"type": "string",
"nullable": true
},
"created_at": {
"type": "string",
"nullable": false
},
"updated_at": {
"type": "string",
"nullable": false
},
"type": {
"type": "string",
"enum": [
"collection",
"disbursement"
]
},
"status": {
"type": "string",
"enum": [
"process",
"success",
"failed"
]
},
"status_label": {
"type": "string"
},
"mode": {
"type": "string",
"enum": [
"live",
"test"
]
},
"livemode": {
"type": "boolean"
},
"refunded": {
"type": "boolean"
},
"version": {
"type": "integer"
}
}
}
}
},
"QuoteResponse": {
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"nullable": false
},
"fee": {
"type": "string",
"nullable": false
},
"gross_amount": {
"type": "string",
"nullable": false
},
"currency": {
"type": "string",
"nullable": false
},
"payer_charge": {
"type": "string",
"nullable": true
},
"wallet_credit": {
"type": "string",
"nullable": true
},
"recipient_amount": {
"type": "string",
"nullable": true
},
"wallet_debit": {
"type": "string",
"nullable": true
},
"type": {
"type": "string",
"enum": [
"collection",
"disbursement"
]
},
"mode": {
"type": "string",
"enum": [
"live",
"test"
]
}
}
}
}
},
"ApplicationResponse": {
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"application_id": {
"type": "string",
"format": "uuid"
},
"application_name": {
"type": "string"
},
"account_number": {
"type": "string"
},
"mode": {
"type": "string",
"enum": [
"live",
"test"
]
},
"livemode": {
"type": "boolean"
}
}
}
}
},
"BalanceResponse": {
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"account_number": {
"type": "string"
},
"currency": {
"type": "string",
"enum": [
"UGX"
]
},
"available": {
"type": "string"
},
"pending": {
"type": "string"
},
"locked": {
"type": "string"
},
"mode": {
"type": "string",
"enum": [
"live",
"test"
]
},
"livemode": {
"type": "boolean"
}
}
}
}
},
"Error": {
"type": "object",
"required": [
"message",
"code",
"request_id"
],
"properties": {
"message": {
"type": "string"
},
"code": {
"type": "string"
},
"request_id": {
"type": "string",
"format": "uuid"
},
"errors": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}

