openapi: 3.0.1 info: title: Account Topup Aggregator description: This API facilitates the management of CustomerAccount capabilitites. It provides a generic API any client or back-end can call to request a Topup function that allows a reseller to refill/credit a subscriber airtime account from the reseller’s account license: name: MADAPI url: https://developers.mtn.com/ version: "1.0" servers: - url: https://api.mtn.com/ description: Generated server url paths: /accounts/{recipientPhoneNumber}/topUp: post: tags: - account-top-up-controller summary: Provides the ability to request a TopUp on a specified balanceType description: "This operation enables clients and integrated back-end systems\ \ to initiate a secure and auditable top up on a subscriber account by specifying\ \ the 'recipientPhoneNumber' and a valid request payload, including the requested\ \ monetary amount, currency, and associated metadata required for processing.\ \ It ensures that the account balance adjustment is validated, recorded, and\ \ returned with a canonical response structure for consistent downstream handling." operationId: topUp parameters: - name: recipientPhoneNumber in: path required: true schema: type: string - name: transactionId in: header required: false schema: type: string default: "" - name: x-country-code in: header required: true schema: type: string - name: x-channel-id in: header required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/BalanceTopUpRequest' required: true responses: "200": description: Success content: application/json: schema: $ref: '#/components/schemas/APIResponse' "400": description: Bad Request content: application/json: schema: $ref: '#/components/schemas/BadRequestErrorResponse' "401": description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedErrorResponse' "500": description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ServerErrorResponse' components: schemas: APIError: type: object properties: statusMessage: type: string supportMessage: type: string transactionId: type: string timestamp: type: string path: type: string method: type: string statusCode: type: string downstreamStatusCode: type: integer format: int32 sequenceNo: type: string APIResponse: type: object properties: statusCode: type: string statusMessage: type: string supportMessage: type: string transactionId: type: string data: type: object customerId: type: string error: $ref: '#/components/schemas/APIError' timeStamp: type: string path: type: string method: type: string sequenceNo: type: string httpStatus: type: string enum: - 100 CONTINUE - 101 SWITCHING_PROTOCOLS - 102 PROCESSING - 103 EARLY_HINTS - 103 CHECKPOINT - 200 OK - 201 CREATED - 202 ACCEPTED - 203 NON_AUTHORITATIVE_INFORMATION - 204 NO_CONTENT - 205 RESET_CONTENT - 206 PARTIAL_CONTENT - 207 MULTI_STATUS - 208 ALREADY_REPORTED - 226 IM_USED - 300 MULTIPLE_CHOICES - 301 MOVED_PERMANENTLY - 302 FOUND - 302 MOVED_TEMPORARILY - 303 SEE_OTHER - 304 NOT_MODIFIED - 305 USE_PROXY - 307 TEMPORARY_REDIRECT - 308 PERMANENT_REDIRECT - 400 BAD_REQUEST - 401 UNAUTHORIZED - 402 PAYMENT_REQUIRED - 403 FORBIDDEN - 404 NOT_FOUND - 405 METHOD_NOT_ALLOWED - 406 NOT_ACCEPTABLE - 407 PROXY_AUTHENTICATION_REQUIRED - 408 REQUEST_TIMEOUT - 409 CONFLICT - 410 GONE - 411 LENGTH_REQUIRED - 412 PRECONDITION_FAILED - 413 PAYLOAD_TOO_LARGE - 413 REQUEST_ENTITY_TOO_LARGE - 414 URI_TOO_LONG - 414 REQUEST_URI_TOO_LONG - 415 UNSUPPORTED_MEDIA_TYPE - 416 REQUESTED_RANGE_NOT_SATISFIABLE - 417 EXPECTATION_FAILED - 418 I_AM_A_TEAPOT - 419 INSUFFICIENT_SPACE_ON_RESOURCE - 420 METHOD_FAILURE - 421 DESTINATION_LOCKED - 422 UNPROCESSABLE_ENTITY - 423 LOCKED - 424 FAILED_DEPENDENCY - 425 TOO_EARLY - 426 UPGRADE_REQUIRED - 428 PRECONDITION_REQUIRED - 429 TOO_MANY_REQUESTS - 431 REQUEST_HEADER_FIELDS_TOO_LARGE - 451 UNAVAILABLE_FOR_LEGAL_REASONS - 500 INTERNAL_SERVER_ERROR - 501 NOT_IMPLEMENTED - 502 BAD_GATEWAY - 503 SERVICE_UNAVAILABLE - 504 GATEWAY_TIMEOUT - 505 HTTP_VERSION_NOT_SUPPORTED - 506 VARIANT_ALSO_NEGOTIATES - 507 INSUFFICIENT_STORAGE - 508 LOOP_DETECTED - 509 BANDWIDTH_LIMIT_EXCEEDED - 510 NOT_EXTENDED - 511 NETWORK_AUTHENTICATION_REQUIRED _links: $ref: '#/components/schemas/Links' Links: type: object additionalProperties: $ref: '#/components/schemas/Link' Amount: type: object properties: type: type: string value: type: string unit: type: string BalanceTopUpRequest: type: object properties: currency: type: string clientReference: type: string balanceType: type: string senderAccountId: type: string amount: $ref: '#/components/schemas/Amount' BadRequestErrorResponse: type: object properties: statusCode: type: string example: "5000" statusMessage: type: string example: INVALID_INPUT_PARAMETERS supportMessage: type: string example: The input parameters provided are invalid. httpStatus;: type: object example: code: 400 series: CLIENT_ERROR reason: Bad Request timestamp: type: string example: 2025-08-05T20:57:21Z UnauthorizedErrorResponse: type: object properties: statusCode: type: string example: "4000" statusMessage: type: string example: Unauthorized supportMessage: type: string example: The supplied authentication is invalid. httpStatus;: type: object example: code: 401 series: CLIENT_ERROR reason: Unauthorized timestamp: type: string example: 2025-08-05T20:57:21Z ServerErrorResponse: type: object properties: statusCode: type: string example: "3001" statusMessage: type: string example: INTERNAL_SERVER_ERROR supportMessage: type: string example: An internal server error occurred and processing could not be completed. httpStatus;: type: object example: code: 500 series: SERVER_ERROR reason: Internal Server Error timestamp: type: string example: 2025-08-05T20:57:21Z Link: type: object properties: href: type: string hreflang: type: string title: type: string type: type: string deprecation: type: string profile: type: string name: type: string templated: type: boolean