Create AccountSign In
REST API v1

MangoOTP Developer API

Automate one-time SMS activation through Partner APIs. Requests require X-API-Key and must follow IP allowlist, partner order number, rate-limit, and polling-frequency constraints.

Quickstart workflow

A typical integration moves from credentials to SMS delivery in four steps.

1

Create an API key

Create a mago_live_ key from the API Keys page after signing in. The raw key is displayed only once.

One account keeps one active partner key. Configure a fixed egress IP whitelist and webhook URL before production traffic.

2

Request a service-country price

List services first, list available countries for the service, then request the single platform price and stock estimate for that service-country pair.

The response contains only the platform quote and inventory data required by the client.

3

Create an activation order

Send service, country, sellPrice, and optional maxSellPrice with partnerOrderNo to avoid duplicate balance freezes during retries.

Without maxSellPrice, the current price must equal sellPrice; when supplied, the current price must not exceed that ceiling.

4

Poll order status

Query by order number to get the assigned phone number, SMS code, and lifecycle status.

Retry only after a definite failure, no-stock response, or rejected price.

shield

Authentication

All Partner API requests use X-API-Key. Only a SHA-256 hash is stored, and the TCP peer IP must match the non-empty whitelist. X-Forwarded-For is not trusted for this decision.

X-API-Key: mago_live_xxxxxxxxxxxxxxxx
bolt

Partner order number and price guard

POST /api/v1/activation/createOrder uses partnerOrderNo, required sellPrice, and optional maxSellPrice. Exact retries do not duplicate orders. The current Catalog price and sellability are checked before funds are frozen.

{"partnerOrderNo":"partner-order-20260707-001"}

Endpoint manual

Endpoint-by-endpoint documentation in the order partners usually integrate: URL, parameters, request sample, success response, and common errors.

Partner APIs

Independently X-API-Key-authenticated activation and MAIN balance APIs. API key management remains a signed-in User JWT concern and is not part of the public Partner API.

GET/api/v1/activation/getServices

List services

X-API-Key

Return every enabled activation service supported by the system without business query parameters.

ParameterInTypeRequiredDescription
X-API-KeyHeaderstringyesPartner API key. The caller IP must match the key whitelist.
X-Request-IdHeaderstringnoOptional Partner correlation ID using 1-64 safe characters.
Response fieldTypeRequiredDescription
codestringyesUnified business code and the sole machine-readable business decision contract. Success is always "0"; failures must be handled by error code.
messagestringyesAuxiliary log text only; never parse or branch on it. The backend maintains English and Simplified Chinese; other request locales receive English.
dataarrayyesarray on success; it may be null in an error response. See the data fields below.
data[]arrayyesAll enabled services in stable platform display order.
data[].serviceCodestringyesPlatform service code used for countries, quotes, and orders.
data[].serviceNamestringyesService display name.

Request sample

GET https://api.mangootp.com/api/v1/activation/getServices
X-API-Key: mago_live_xxx
Accept: application/json

Success response

{
  "code": "0",
  "message": "success",
  "data": [
    {
      "serviceCode": "telegram",
      "serviceName": "Telegram"
    }
  ]
}

Common errors

  • AUTH-E001: missing API key.
  • AUTH-E002: invalid, revoked, expired, or IP-mismatched API key.
GET/api/v1/activation/getCountries

List supported countries

X-API-Key

Return every enabled country supported by the system without business query parameters. Use getPrice for executable price and stock.

ParameterInTypeRequiredDescription
X-API-KeyHeaderstringyesPartner API key.
X-Request-IdHeaderstringnoOptional Partner correlation ID using 1-64 safe characters.
Response fieldTypeRequiredDescription
codestringyesUnified business code and the sole machine-readable business decision contract. Success is always "0"; failures must be handled by error code.
messagestringyesAuxiliary log text only; never parse or branch on it. The backend maintains English and Simplified Chinese; other request locales receive English.
dataarrayyesarray on success; it may be null in an error response. See the data fields below.
data[]arrayyesAll enabled countries supported by the system.
data[].countryCodestringyesISO country code used for quotes and orders.
data[].countryNamestringyesCountry display name for the current locale.
data[].flagEmojistring / nullnoCountry flag emoji.
data[].phonePrefixstring / nullnoCountry calling prefix.

Request sample

GET https://api.mangootp.com/api/v1/activation/getCountries
X-API-Key: mago_live_xxx
Accept: application/json

Success response

{
  "code": "0",
  "message": "success",
  "data": [
    {
      "countryCode": "US",
      "countryName": "United States",
      "flagEmoji": "🇺🇸",
      "phonePrefix": "+1"
    }
  ]
}

Common errors

  • AUTH-E001: missing API key.
  • AUTH-E002: invalid, revoked, expired, or IP-mismatched API key.
GET/api/v1/activation/getPrice

Get service-country price

X-API-Key

Return the current platform sell price and integer inventory estimate for one service-country pair. No quote token is issued.

ParameterInTypeRequiredDescription
X-API-KeyHeaderstringyesPartner API key.
X-Request-IdHeaderstringnoOptional Partner correlation ID: 1-64 letters, digits, dots, underscores, colons, or hyphens. It is audited but never replaces X-Trace-Id.
serviceQuerystringyesPlatform service code.
countryQuerystringyesISO country code, such as US or GB.
Response fieldTypeRequiredDescription
codestringyesUnified business code and the sole machine-readable business decision contract. Success is always "0"; failures must be handled by error code.
messagestringyesAuxiliary log text only; never parse or branch on it. The backend maintains English and Simplified Chinese; other request locales receive English.
dataobjectyesobject on success; it may be null in an error response. See the data fields below.
data.servicestringyesRequested service code.
data.countrystringyesRequested country code.
data.sellPricedecimal numberyesPlatform unit sell price from the current Catalog row.
data.currencystringyesThe API currently returns USD as the price currency code.
data.availableCountintegeryesCurrent aggregate Catalog inventory estimate. It is not reserved for the caller.

Request sample

GET https://api.mangootp.com/api/v1/activation/getPrice?service=telegram&country=US
X-API-Key: mago_live_xxx
Accept: application/json

Success response

{
  "code": "0",
  "message": "success",
  "data": {
    "service": "telegram",
    "country": "US",
    "sellPrice": 1.050000,
    "currency": "USD",
    "availableCount": 42
  }
}

Common errors

  • OTP-E006: no stock for this service/country.
  • COMMON-E002: service or country format is invalid.
  • AUTH-E002: API key rejected.
POST/api/v1/activation/createOrder

Create activation order

X-API-Key

Create an activation order and freeze the current Catalog sell price. Without maxSellPrice the current price must equal sellPrice; with a ceiling it must not exceed that value.

ParameterInTypeRequiredDescription
X-API-KeyHeaderstringyesPartner API key.
X-Request-IdHeaderstringnoOptional Partner correlation ID: 1-64 letters, digits, dots, underscores, colons, or hyphens. It is audited but never replaces X-Trace-Id.
partnerOrderNoBodystringyesPartner order number generated by your system. It must be unique under the same Partner account and activation business type, and stable for retries of the same request.
serviceBodystringyesPlatform service code.
countryBodystringyesISO country code.
sellPriceBodydecimal numberyesPlatform sell price most recently observed by the partner. Positive with at most six decimals.
maxSellPriceBodydecimal numbernoOptional accepted price ceiling. It must be at least sellPrice. When omitted, no price change is accepted.
Response fieldTypeRequiredDescription
codestringyesUnified business code and the sole machine-readable business decision contract. Success is always "0"; failures must be handled by error code.
messagestringyesAuxiliary log text only; never parse or branch on it. The backend maintains English and Simplified Chinese; other request locales receive English.
dataobjectyesobject on success; it may be null in an error response. See the data fields below.
data.orderNostringyesMangoOTP activation order number.
data.partnerOrderNostringyesPartner order number.
data.statusstringyesCurrent activation order status.
data.phonestring / nullnoAssigned number. Null before allocation.
data.smsCodestring / nullnoOTP extracted by the platform. Null before SMS delivery.
data.payAmountdecimal numberyesAmount payable by the user, frozen and finally settled for the order.
data.currencystringyesOrder currency, currently always USD.

Request sample

POST https://api.mangootp.com/api/v1/activation/createOrder
X-API-Key: mago_live_xxx
Accept: application/json
Content-Type: application/json

{
  "partnerOrderNo": "partner-order-20260707-001",
  "service": "telegram",
  "country": "US",
  "sellPrice": 1.05,
  "maxSellPrice": 1.10
}

Success response

{
  "code": "0",
  "message": "success",
  "data": {
    "orderNo": "AO202607070000000001",
    "partnerOrderNo": "partner-order-20260707-001",
    "status": "PENDING",
    "phone": null,
    "smsCode": null,
    "payAmount": 1.050000,
    "currency": "USD"
  }
}

Common errors

  • ACC-E004: insufficient available balance.
  • ORD-E004: sellPrice or maxSellPrice does not satisfy the current price rule.
  • OTP-E006: the current Catalog has no available inventory.
  • COMMON-E003: sell-price format or precision is invalid.
GET/api/v1/activation/getOrders

List activation orders

X-API-Key

Paginate activation orders owned by the API key user. Useful for partner-side history sync and status reconciliation.

ParameterInTypeRequiredDescription
X-API-KeyHeaderstringyesPartner API key.
X-Request-IdHeaderstringnoOptional Partner correlation ID: 1-64 letters, digits, dots, underscores, colons, or hyphens. It is audited but never replaces X-Trace-Id.
pageQuerynumbernoPage number. Default 1.
sizeQuerynumbernoPage size. Default 20, capped by the platform.
Response fieldTypeRequiredDescription
codestringyesUnified business code and the sole machine-readable business decision contract. Success is always "0"; failures must be handled by error code.
messagestringyesAuxiliary log text only; never parse or branch on it. The backend maintains English and Simplified Chinese; other request locales receive English.
dataobjectyesobject on success; it may be null in an error response. See the data fields below.
data.totalnumberyesTotal number of matching orders.
data.records[]arrayyesOrders in the current page.
data.records[].orderNostringyesMangoOTP activation order number.
data.records[].partnerOrderNostringyesPartner order number.
data.records[].statusstringyesCurrent activation order status.
data.records[].serviceCodestringyesService code.
data.records[].countryCodestringyesISO country code.
data.records[].phonestring / nullnoAssigned number. Null before allocation.
data.records[].smsCodestring / nullnoOTP extracted by the platform. Null before SMS delivery.
data.records[].payAmountdecimal numberyesAmount payable by the user, frozen and finally settled for the order.
data.records[].refundAmountdecimal numberyesAmount already refunded to the user.
data.records[].createdAtdatetime stringyesOrder creation timestamp.
data.records[].completedAtdatetime string / nullnoCompletion timestamp. Null before completion.

Request sample

GET https://api.mangootp.com/api/v1/activation/getOrders?page=1&size=20
X-API-Key: mago_live_xxx
Accept: application/json

Success response

{
  "code": "0",
  "message": "success",
  "data": {
    "total": 1,
    "records": [
      {
        "orderNo": "AO202607070000000001",
        "partnerOrderNo": "partner-order-20260707-001",
        "status": "ACTIVE",
        "serviceCode": "telegram",
        "countryCode": "US",
        "phone": "+12025550123",
        "smsCode": null,
        "payAmount": 1.050000,
        "refundAmount": 0.000000,
        "createdAt": "2026-06-22T18:07:22",
        "completedAt": null
      }
    ]
  }
}

Common errors

  • AUTH-E002: API key rejected.
  • COMMON-E003: page or size is out of range.
GET/api/v1/activation/getOrder?orderNo={orderNo}

Get activation order detail

X-API-Key

Read the current status, phone number, and SMS code for one activation order. Check business code and data.status, not HTTP status alone.

ParameterInTypeRequiredDescription
X-API-KeyHeaderstringyesPartner API key.
X-Request-IdHeaderstringnoOptional Partner correlation ID: 1-64 letters, digits, dots, underscores, colons, or hyphens. It is audited but never replaces X-Trace-Id.
orderNoQuerystringyesMangoOTP activation order number.
Response fieldTypeRequiredDescription
codestringyesUnified business code and the sole machine-readable business decision contract. Success is always "0"; failures must be handled by error code.
messagestringyesAuxiliary log text only; never parse or branch on it. The backend maintains English and Simplified Chinese; other request locales receive English.
dataobjectyesobject on success; it may be null in an error response. See the data fields below.
data.orderNostringyesMangoOTP activation order number.
data.partnerOrderNostringyesPartner order number.
data.statusstringyesCurrent activation order status.
data.phonestring / nullnoAssigned number. Null before allocation.
data.smsCodestring / nullnoOTP extracted by the platform. Null before SMS delivery.
data.payAmountdecimal numberyesAmount payable by the user, frozen and finally settled for the order.
data.currencystringyesOrder currency, currently always USD.

Request sample

GET https://api.mangootp.com/api/v1/activation/getOrder?orderNo=AO202607070000000001
X-API-Key: mago_live_xxx
Accept: application/json

Success response

{
  "code": "0",
  "message": "success",
  "data": {
    "orderNo": "AO202607070000000001",
    "partnerOrderNo": "partner-order-20260707-001",
    "status": "SUCCESS",
    "phone": "+12025550123",
    "smsCode": "834921",
    "payAmount": 1.050000,
    "currency": "USD"
  }
}

Common errors

  • ORD-E001: order does not exist or does not belong to the API key user.
  • COMMON-E002: orderNo format is invalid.
POST/api/v1/activation/cancelOrder?orderNo={orderNo}

Cancel activation order

X-API-Key

Cancel an order while it is still cancellable. In-flight, SMS-received, or terminal orders are not canceled again.

ParameterInTypeRequiredDescription
X-API-KeyHeaderstringyesPartner API key.
X-Request-IdHeaderstringnoOptional Partner correlation ID: 1-64 letters, digits, dots, underscores, colons, or hyphens. It is audited but never replaces X-Trace-Id.
orderNoQuerystringyesMangoOTP activation order number.
Response fieldTypeRequiredDescription
codestringyesUnified business code and the sole machine-readable business decision contract. Success is always "0"; failures must be handled by error code.
messagestringyesAuxiliary log text only; never parse or branch on it. The backend maintains English and Simplified Chinese; other request locales receive English.
dataobjectyesobject on success; it may be null in an error response. See the data fields below.
data.orderNostringyesMangoOTP activation order number.
data.partnerOrderNostringyesPartner order number.
data.statusstringyesCurrent activation order status.
data.phonestring / nullnoAssigned number. Null before allocation.
data.smsCodestring / nullnoOTP extracted by the platform. Null before SMS delivery.
data.payAmountdecimal numberyesAmount payable by the user, frozen and finally settled for the order.
data.currencystringyesOrder currency, currently always USD.

Request sample

POST https://api.mangootp.com/api/v1/activation/cancelOrder?orderNo=AO202607070000000001
X-API-Key: mago_live_xxx
Accept: application/json

Success response

{
  "code": "0",
  "message": "success",
  "data": {
    "orderNo": "AO202607070000000001",
    "partnerOrderNo": "partner-order-20260707-001",
    "status": "CANCELLED",
    "phone": null,
    "smsCode": null,
    "payAmount": 1.050000,
    "currency": "USD"
  }
}

Common errors

  • ORD-E003 / ORD-E005: current status does not allow cancellation.
  • ORD-E001: order does not exist or does not belong to the API key user.
GET/api/v1/account/getBalance

Get account balance

X-API-Key

Return the MAIN available balance for the API key owner. The endpoint accepts no email or user identifier, never returns commission accounts, and exposes no money write operation.

ParameterInTypeRequiredDescription
X-API-KeyHeaderstringyesPartner API key with the fixed account:read scope.
X-Request-IdHeaderstringnoOptional Partner correlation ID using the same format as the other Partner APIs.
Response fieldTypeRequiredDescription
codestringyesUnified business code and the sole machine-readable business decision contract. Success is always "0"; failures must be handled by error code.
messagestringyesAuxiliary log text only; never parse or branch on it. The backend maintains English and Simplified Chinese; other request locales receive English.
dataobjectyesobject on success; it may be null in an error response. See the data fields below.
data.accountTypestringyesAlways MAIN.
data.currencystringyesMAIN account currency, currently USD.
data.availableBalancedecimal numberyesCurrent MAIN available balance.

Request sample

GET https://api.mangootp.com/api/v1/account/getBalance
X-API-Key: mago_live_xxx
Accept: application/json

Success response

{
  "code": "0",
  "message": "success",
  "data": {
    "accountType": "MAIN",
    "currency": "USD",
    "availableBalance": 97.410000
  }
}

Common errors

  • AUTH-E002: API key is invalid, revoked, expired, or outside its IP whitelist.
  • ACC-E001: MAIN account does not exist.

Webhook events

Webhooks notify partner systems only when an activation order receives an SMS. Configure the callback URL from the API Keys page.

activation.sms_received

Activation SMS received

Sent after MangoOTP receives an activation SMS and extracts the OTP. The create-order response already returns the phone number, so activation number allocation is not sent as a separate webhook.

{
  "eventId": "evt_AO202607070000000001_activation_sms_received",
  "eventType": "activation.sms_received",
  "status": "SUCCESS",
  "orderNo": "AO202607070000000001",
  "occurredAt": "2026-06-22T18:09:01Z",
  "data": {
    "orderNo": "AO202607070000000001",
    "service": "telegram",
    "country": "US",
    "phone": "+12025550123",
    "payAmount": 1.050000,
    "smsCode": "834921",
    "smsText": "Telegram code: 834921"
  }
}
verified_user

Webhook signature and retries

  • Configuration: signed-in users configure one webhook URL for the active API key from the API Keys page. Webhooks and API requests share the same key ownership.
  • Signature: every delivery includes X-Webhook-Signature: sha256=<hex>. First SHA-256 the active API key into its 64-character lowercase hexadecimal text, then use the UTF-8 bytes of that text as the HMAC-SHA256 key and sign the exact raw HTTP JSON body bytes. No separate webhook signing secret is created.
  • Headers: X-Webhook-Event carries the event type, X-Webhook-Delivery-Id remains stable for all notifications of one event, X-Webhook-Attempt carries the notification number, and X-Webhook-Timestamp carries the Unix timestamp in seconds. These auxiliary headers are not signed.
  • Notification policy: MangoOTP notifies at most 5 times. The first is immediate; unacknowledged notifications are followed after 1, 3, 5, and 15 minutes, at event-relative minutes 0, 1, 4, 9, and 24. The result becomes FAIL after the fifth unacknowledged notification, and manual notification never exceeds the limit.
  • Acknowledgement: notification stops only for HTTP 2xx with a response body whose trimmed content is exactly SUCCESS. Verify the signature first and store idempotently by eventId. Webhooks do not replace order query APIs.
Webhook fieldTypeRequiredDescription
eventTypestringyesBusiness event type, same as X-Webhook-Event, such as activation.sms_received.
eventIdstringyesUnique event ID. Receivers should store by this field idempotently.
statusstringconditionalOrder status after the event. Present for order events.
orderNostringconditionalTop-level business order number for order events, useful for receiver logs and alert routing.
occurredAtdatetime stringyesEvent timestamp in ISO-8601 format.
data.orderNostringyesMangoOTP activation order number with the AO prefix.
data.servicestringnoService code. It may be absent in failure events.
data.countrystringnoCountry code. It may be absent in failure events.
data.phonestringconditionalAssigned activation phone number. The create-order response already returns it, and the SMS webhook includes it again.
data.smsCodestringconditionalOTP extracted from the SMS delivery event.
data.smsTextstringnoSMS body or preview for display or troubleshooting.
data.payAmountdecimal numbernoUser payment amount in activation SMS-received events.

Lifecycle and polling

Do not rely on HTTP status alone. Read business code and order status; terminal states are irreversible.

PENDING

Order created and provisioning, or awaiting a conclusive result. It cannot be canceled.

ACTIVE

Phone number assigned and SMS is pending. Poll order detail for smsCode.

SUCCESS

OTP received and the order is complete. Terminal state.

TIMEOUT / FAILED / CANCELLED / BANNED

Terminal refunded or stopped states, differentiated by status name.

Error handling

Business failures return unified codes. Clients should route retries, country changes, top-ups, or manual handling by code.

CodeMeaningRecommended action
COMMON-E001 / E002 / E003Missing, invalid, or out-of-range parameter.Validate required fields, length, money precision, and code format.
AUTH-E001 / AUTH-E002Authentication missing or invalid.Check X-API-Key, revocation, expiry, and IP whitelist.
ACC-E004Insufficient available balance.Top up, confirm the available balance has updated, and retry.
OTP-E006 / SMS-E003No inventory is available for this selection.Try another country/service or retry later.
ORD-E001 / ORD-E003 / ORD-E005Order not found or current status does not allow the operation.Refresh order status before deciding next steps.
ORD-E004Submitted sell price or accepted price ceiling validation failed.Get the current price and submit a new sellPrice; include maxSellPrice only when price drift is acceptable.
SMS-E001 / SMS-E004Number service temporarily unavailable.Query by business order number first. Retry later only after a definite failure; contact support if the result remains unknown.
speed

Rate limits and polling frequency

  • API-key rate limit: rateLimitQps can be configured when the key is created. The default is 5 QPS; the current maximum is shown on the API-key creation page in the USER portal.
  • Platform window limit: if no specific rule matches, GET defaults to 300 requests/minute and non-GET defaults to 30 requests/minute. Limit hits return HTTP 429 and COMMON-E429.
  • Headers: rate-limited responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. Clients should back off by these headers.
  • Price lookup returns the current Catalog price and inventory estimate without an expiry; order creation always reloads current price and sellability.
  • Activation polling: poll the same order every 5-10 seconds. Polling faster during ACTIVE does not speed up delivery and increases rate-limit risk.