{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"5e6673d7-0a01-4c5c-8978-c9ec295509ab","name":"Nellobyte REST API v1","description":" \n\nIntegrate airtime, mobile data, cable TV, electricity, betting wallet funding,  \nrecharge-card e-PINs, data e-PINs, Smile, WAEC and JAMB into your application.\n\n**Base URL:** `https://api.nellobytesystems.com/v1`\n\nThis collection documents the REST routes. Send JSON for POST requests and headers  \nfor authentication. These URLs do not use the legacy `.asp?UserID=...&APIKey=...`  \nrequest format. Purchases and order lookups use the current-status contract below.\n\n## Try the sandbox in Postman\n\nTest 30 API operations with ₦100,000 in sandbox funds. The sandbox base URL is `https://sandbox-api.nellobytesystems.com/v1`.\n\n1. Open [sandbox signup](https://sandbox-api.nellobytesystems.com/signup/), enter your email address, and select **Create account**. Follow the link in your email to open your dashboard. Returning users can select **Sign in**.\n2. Save your `sandboxUser` and `sandboxBearer` from the dashboard. [Download the sandbox collection](https://sandbox-api.nellobytesystems.com/signup/postman) and import it into Postman.\n3. In the sandbox collection’s **Variables** tab, enter both values locally and leave their shared values empty.\n4. Open **Start here → Wallet balance** and send `GET /v1/wallet`. A new account shows a balance of ₦100,000. Sandbox purchases use these test funds.\n\n[Browse the sandbox API documentation](https://documenter.getpostman.com/view/11035265/2sBYHaMbeY) for the full list of requests and examples.\n\n## Start here\n\n1. Import this collection and the accompanying environment into Postman.\n    \n2. Select the **Nellobyte REST v1 - Local credentials** environment.\n    \n3. Set `memberId` and `apiKey` to your member ID and that member's **standard API key**  \n    in local variable values. Keep shared values empty. Never publish your credentials.\n    \n4. Send **Health** and then **Wallet balance**. A wallet response has `status: WALLET_SUCCESS`, `id`, `balance`, `currency` and an ISO date.\n    \n5. Load the relevant catalogue, select a valid code and fill the destination variables.  \n    Verify the customer first where a verification endpoint exists.\n    \n6. For an intentional purchase, assign a new `requestId` and send that one order request.  \n    Save its response and query its status using the same request ID or returned order ID.\n    \n\nThe base URL is a production service. Purchase requests can debit a funded wallet.  \nDo not run the whole collection against a funded account. The collection contains no  \nautomatic request chaining, purchase retries or scripts that transmit requests.\n\n## Authentication\n\nEvery business endpoint requires both headers:\n\n``` http\nAuthorization: Bearer {{apiKey}}\nX-User-ID: {{memberId}}\nAccept: application/json\n\n ```\n\nPostman's collection-level Bearer Token authorization supplies `Authorization`.  \nEach business request includes `X-User-ID`. **Health** uses no authentication.  \nDo not supply `UserID` or `APIKey` in the URL or JSON body. Use the member's standard  \nAPI key, not an app key or a provider/robot key. Existing account and IP access rules  \ncontinue to apply. Keep API keys on a trusted server rather than a public web page.\n\n## Request format\n\nPOST requests require `Content-Type: application/json` and a flat JSON object.  \nOnly documented fields are accepted; nested objects, arrays, null values, duplicate  \nfields and unknown fields are rejected. POST query-string parameters are rejected.  \nGET requests use query parameters where listed and must not have a body.  \nThe maximum POST body is 65,536 bytes and each field value is limited to 8,192 characters.\n\nUse strings for identifiers, phone numbers and codes to preserve leading zeroes.  \nSupply monetary inputs in naira without currency signs or grouping commas.  \nResponse amounts may be strings and may contain grouping commas. Date strings retain  \nthe existing endpoint's format; they are not guaranteed to be ISO 8601 or UTC.\n\n## Product codes and prices\n\nFetch current catalogues instead of hard-coding plan names, prices or limits.  \nFor mobile data, use the selected network `ID` and plan `PRODUCT_CODE`. `DATA_TYPE`  \nis `SME` or `DIRECT`; do not infer the delivery type from words in the plan name.  \nThe same mobile-data catalogue supplies the plan identity for data e-PIN generation.  \nSmile uses its own package catalogue.\n\n## Orders and uncertain outcomes\n\n`RequestID` is required for every purchase: 1-64 letters, digits, underscores or hyphens.  \nCreate one ID for one intended purchase and retain it with the returned order ID.  \nDo not change the ID or automatically submit another purchase after a timeout or 503.  \nFirst query **Orders - by request ID**. If the result is still unavailable, retain the  \nreference for investigation rather than assuming no debit occurred.\n\nREST response contract (20261102-3)\n\nSuccessful business responses use HTTP 200. Always inspect the JSON status: a saved  \npurchase may still be ORDER_RECEIVED, ORDER_PENDING or ORDER_PROCESSING. Only a  \nsaved completion returns ORDER_COMPLETED. Purchase and order lookups use the same  \noperational status reader; no provider purchase is retried by response formatting.\n\nWallet: status=WALLET_SUCCESS, id, phoneno, balance, currency=NGN, date.  \nVerification: status=VERIFIED, valid=true, customer_name, validation_reference.  \nAn optional customer name/reference can be empty when the provider explicitly  \nconfirms that no validation reference is required. Verification does not vend.\n\nErrors use a non-200 HTTP status and JSON status/message:  \n400 malformed request; 401 missing or invalid credentials; 403 blocked account,  \nIP restriction, HTTPS or KYC requirement; 404 owned order not found;  \n405 unsupported method; 413 oversized body; 415 unsupported content type;  \n422 invalid input, business rejection, or VERIFICATION_REJECTED with valid=false;  \n429 rate limit with Retry-After: 1; 502 malformed provider response;  \n503 dependency or saved-state unavailable; 504 provider verification timeout.  \nAn outage is not reported as an invalid customer. Raw provider error bodies and  \ncredentials are not returned. Clients should retain RequestID before sending.\n\nIf a purchase was attempted but its result cannot be confirmed, the error retains  \nrequestid, outcome=UNKNOWN, orderid when available, and next_action. An unavailable  \npost-purchase status read returns ORDER_STATUS_UNAVAILABLE with saved=true when  \nthe save was confirmed. Query the same reference before another purchase. Never  \nautomatically submit a purchase again because a response is 5xx or a lookup is 404.  \nORDER_NOT_FOUND describes an unsuccessful order lookup; it is not proof that no purchase occurred. PIN detail availability is separate from status.\n\nWallet and current-order money fields are decimal strings with two decimal places  \nand no grouping commas. Dates are ISO 8601 with the database server's UTC offset,  \nfor example 2026-11-02T12:00:00+01:00. Catalogue schemas and prices are unchanged.  \nCable TV uses the submitted MobileNumber; betting uses submitted PhoneNo when  \npresent, otherwise the authenticated member's phone. These phone fields accept  \nlocal 0-prefixed and +234/234 formats. Accepted Memo is passed to purchase storage.\n\nLimits are shared across each category per source IP, per IIS worker: 30 purchase  \nrequests/second, 10 verification requests/second, 60 authenticated-route GET  \nrequests/second. Invalid credentials also consume the category limit. Health,  \nOPTIONS, documentation and private helper calls are excluded. Counters are bounded  \nin memory and reset on application recycle; this is not a distributed account  \nquota. A full counter bucket also returns 429 until the next second.\n\nThe response header X-Rest-Contract: 20261102-3 identifies this deployment.  \nExisting REST route names, request fields, standard key authentication, delivery mapping and commission are retained. New REST-only SQL objects protect  \nRequestID reuse and capture wallet snapshots. Shared legacy definitions are unchanged.  \nThis response contract applies only to api.nellobytesystems.com/v1.\n\nThere is no working cancellation route in this REST release. `/orders/cancel`  \nreturns HTTP 501 `CANCELLATION_NOT_AVAILABLE` and is deliberately not a runnable request here.\n\n## HTTP request errors\n\n| HTTP | Example status | Action |\n| --- | --- | --- |\n| 400 | `INVALID_JSON`, `UNKNOWN_PARAMETER`, `DUPLICATE_PARAMETER`, `USE_JSON_BODY_ONLY`, `GET_BODY_NOT_ALLOWED` | Correct the request format. |\n| 401 | `MISSING_CREDENTIALS`, `INVALID_CREDENTIALS`, `MISSING_USER_ID` | Check the authentication headers. |\n| 403 | `HTTPS_REQUIRED`, account/IP/KYC restriction | Use HTTPS and review the member restriction. |\n| 404 | `ROUTE_NOT_FOUND` | Check the path. |\n| 405 | `METHOD_NOT_ALLOWED` | Use the documented HTTP method. |\n| 413 | `REQUEST_TOO_LARGE` | Reduce the body size. |\n| 415 | `JSON_CONTENT_TYPE_REQUIRED` | Send application/json. |\n| 422 | `MISSING_`, `INVALID_REQUEST_ID` | Supply a valid required value. |\n| 503 | Service or outcome unavailable | Query an uncertain purchase before considering another order. |\n\n## Examples\n\nAll saved responses marked **Illustrative** are synthetic, source-derived format examples.  \nThey are not live transaction results or current price quotations. Catalogue examples  \nshow only a subset of entries. PINs, tokens, IDs and customer details are placeholders.  \nRefresh the real catalogue with your account before an intentional purchase.\n\nREST purchase protection (contract 20261102-3)\n\nAll ten purchase routes retain a durable request receipt keyed by the authenticated  \nmember and RequestID. Keep the same route and field values for an identical retry.  \nJSON property order and property-name casing do not affect identity. Missing and  \nempty optional fields are equivalent; different supplied field values (including  \nnumeric spellings, Memo and callback URL) are conservatively treated as a conflict.  \nThe database stores a SHA-256 fingerprint, not the raw request or API key.\n\nAn identical saved request returns its CURRENT operational order status without  \nanother purchase. Idempotent-Replayed: true identifies a replay. Changed details  \nor another product with the same member/RequestID return HTTP 409 REQUEST_ID_CONFLICT.  \nA request still processing, interrupted, or with uncertain save outcome returns  \nHTTP 409 REQUEST_OUTCOME_PENDING_REVIEW. Query GET /orders using RequestID or  \ncontact support; do not replace the RequestID to work around that response.  \nRequests rejected before purchase SQL retain their rejection. Corrected purchases  \nuse a new RequestID only once the previous rejection is definite.\n\nNew successful purchase/RequestID responses include wallet_before and wallet_after,  \ndecimal strings describing the saved request's wallet snapshots. They are captured  \ninside the purchase transaction and exposed only after commit, including batches.  \nThey describe the original purchase, not the customer's current wallet after later  \nactivity or a refund. GET /wallet remains the current wallet observation.  \nFor an older airtime request adopted by its existing replay mechanism, unavailable  \nhistorical wallet snapshots are empty rather than invented.\n\nReceipt and source-item writes commit with the debit/order. If the order fails,  \nthose writes roll back while the initial pending claim is retained for review.  \nThere is no automatic claim expiry or repeat purchase after an ambiguous failure.  \nAn old receipt cannot be reused just because its operational record is no longer available:  \nthe receipt persists, and unavailable current status returns 503 with saved=true.  \nRetained display details cannot authorize financial operations.\n\nThese protections cover REST requests first submitted after deployment. Prior  \nunconfirmed requests and legacy endpoints are not backfilled into this ledger.  \nDo not re-submit a pre-deployment uncertain request; reconcile its saved payment.  \nExisting pricing, cashback, delivery mapping and legacy endpoints stay unchanged.\n\nFor an older order, use GET /orders?OrderID=YOUR_ORDER_ID. The same response fields and status names apply. Current saved order details take precedence; when the order is no longer in the active retention window, its retained transaction details can be displayed. This is an individual order view, not a batch reconstruction. RequestID and BatchNo lookups, purchase results and request replay protection keep their existing operational rules. A database error returns ORDER_STATUS_UNAVAILABLE; it is not treated as a missing order. Viewing a receipt never authorizes a refund, redo or wallet movement.\n\n### Request reference\n\nResponses generated by the REST runtime include an X-Request-Reference header. Give this reference to support when investigating a request. It identifies an HTTP attempt; continue using RequestID for purchase idempotency. Static files, IIS-generated responses and failures before the runtime starts may not include this header.","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"11035265","team":22360855,"collectionId":"5e6673d7-0a01-4c5c-8978-c9ec295509ab","publishedId":"2sBYHaNGXy","public":true,"publicUrl":"https://documenter-api.postman.tech/view/11035265/2sBYHaNGXy","privateUrl":"https://go.postman.co/documentation/11035265-5e6673d7-0a01-4c5c-8978-c9ec295509ab","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"documentationLayout":"classic-double-column","customisation":{"metaTags":[{"name":"description","value":""},{"name":"title","value":""}],"appearance":{"default":"light","themes":[{"name":"dark","logo":null,"colors":{"top-bar":"212121","right-sidebar":"303030","highlight":"FF6C37"}},{"name":"light","logo":null,"colors":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"}}]}},"version":"8.12.12","publishDate":"2026-11-11T19:27:27.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{"title":"","description":""},"logos":{"logoLight":null,"logoDark":null}},"statusCode":200},"environments":[],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://postman-image-service.postman.com/api/cloudinary-proxy/postman/image/upload/t_team_logo_pubdoc/v1/team/a3af179b1e7c7a427c16545528654675f1217649e67c421dccdb0440d53b515f","favicon":""},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"}],"canonicalUrl":"https://documenter.gw.postman.com/view/metadata/2sBYHaNGXy"}