Skip to Content

Mobile top-up

Prepaid credit, postpaid bills and offers for Mobilis, Djezzy and Ooredoo.

Plans

GET /v3/mobile/plans lists what you can send. There are three kinds of plan per operator:

Plan codeWhat it doesNeeds
PREPAID_MOBILIS, PREPAID_DJEZZY, PREPAID_OOREDOOAdds credit to a prepaid line.amount between min_amount and max_amount
FACTURE_MOBILIS, FACTURE_DJEZZY, FACTURE_OOREDOOPays a postpaid bill.amount between min_amount and max_amount
INTERNATIONAL_MOBILISAdds Mobilis international credit. Mobilis only.amount between min_amount and max_amount
OFFER_MOBILIS, OFFER_DJEZZY, OFFER_OOREDOOActivates an operator offer or package.offer_id from GET /v3/mobile/offers

Plans with isEnabled: false cannot be sent right now. You can cache the plan list for a few minutes.

GET /v3/mobile/plans (excerpt)
{
  "dynamicPlans": [
    { "code": "PREPAID_DJEZZY", "name": "Djezzy prepaid credit", "operator": "Djezzy", "type": "topup", "isEnabled": true, "min_amount": 100, "max_amount": 50000 }
  ],
  "fixedPlans": [],
  "offerPlans": [
    { "code": "OFFER_DJEZZY", "name": "Djezzy offers and packages", "operator": "Djezzy", "type": "offer", "isEnabled": true, "requires": "offer_id" }
  ]
}

Phone numbers

MSSIDN is a 10-digit Algerian mobile number with the leading 0. No spaces and no +213. Send the plan of the number's operator.

PrefixOperatorPlans
05…Ooredoo*_OOREDOO
06…Mobilis*_MOBILIS
07…Djezzy*_DJEZZY
01…Ooredoo Enterprise (business lines)*_OOREDOO only; any other plan is refused with ERR_PHONE

Sending credit or a bill

curl -X POST "$API_URL/v3/mobile/send" \
  -H "X-Access-Token: $API_KEY" -H "Content-Type: application/json" \
  -d '{"plan_code":"PREPAID_MOBILIS","MSSIDN":"0600000009","amount":1000,"ref":"order-2001"}'

The answer comes back at once with topupId and topupRef. It means the top-up was accepted, not delivered. Read the result with check-id or check-ref.

Sending an offer

Offers depend on the number, so ask the operator first:

curl "$API_URL/v3/mobile/offers?operator=mobilis&MSSIDN=0600000009" -H "X-Access-Token: $API_KEY"
{
  "MSSIDN": "0600000009",
  "operator": "Mobilis",
  "plan_code": "OFFER_MOBILIS",
  "expires_at": "2026-11-15T11:00:00.000Z",
  "offers": [
    { "offer_id": "eyJ2IjoxLCJ1Ijoi…", "name": "Mix 500", "amount": 500, "debt_amount": 0, "total_amount": 500, "category": "regular" },
    { "offer_id": "eyJ2IjoxLCJ1Ijoi…", "name": "Internet 1 Go", "amount": 300, "debt_amount": 0, "total_amount": 300, "category": "internet" }
  ]
}

Then send the chosen offer_id with the matching OFFER_* plan:

curl -X POST "$API_URL/v3/mobile/send" \
  -H "X-Access-Token: $API_KEY" -H "Content-Type: application/json" \
  -d '{"plan_code":"OFFER_MOBILIS","MSSIDN":"0600000009","offer_id":"eyJ2IjoxLCJ1Ijoi…","ref":"order-2002"}'

An offer_id is signed, valid for 30 minutes, and only works for the same number and operator. The offers call asks the operator in real time and can take a few seconds.

Djezzy Tranquilo debt

Some Djezzy lines owe a Tranquilo debt. Activating an offer pays that debt too, so each offer shows:

  • amount: the offer price.
  • debt_amount: the debt paid with it (0 when there is none).
  • total_amount: what your balance pays, amount + debt_amount.

Show total_amount to your customer before they confirm. If your balance is below total_amount, the send is refused with INSUFFICIENT_BALANCE and nothing is charged.

Statuses

StatusMeaningFinalCharged
PENDINGAccepted and queued.NoNo
HANDLINGBeing sent to the operator.NoNo
DEBT_PENDINGThe line has an unpaid debt. Waiting for your decision: see Line debt.No, act on itNo
COMPLETEDDelivered.YesYes
REFUNDEDFailed. refund_message says why.YesNo
UNKNOWN_ERRORThe operator did not confirm the result. Our team checks it.Yes, for pollingMaybe

Your balance is checked when you send, and charged only when the top-up is delivered. balance_amount shows what was taken from your balance.

UNKNOWN_ERROR is not a failure

Do not refund your customer on UNKNOWN_ERROR. The credit may have arrived. Our team settles these to COMPLETED or REFUNDED, usually within a few hours. Re-check them from a background job, for example every hour.

Line debt (SABBAQLI)

Some lines owe the operator an unpaid advance (SABBAQLI). Before topping them up, the operator asks whether to pay that debt. This mostly happens on Ooredoo lines. The top-up then stops as DEBT_PENDING:

GET /v3/mobile/check-ref/order-2001
{
  "_id": "F00012345",
  "ref": "order-2001",
  "status": "DEBT_PENDING",
  "plan_code": "PREPAID_OOREDOO",
  "MSSIDN": "0500000004",
  "topup_amount": 500,
  "balance_amount": 0,
  "debt_amount": 100,
  "debt_message": "Le client dispose d'un emprunt non-remboursé de 100 DA de service SABBAQLI. Voulez-vous le payer ?",
  "debt_options": [
    { "choice": "PAY_ALL", "amount": 600, "available": true },
    { "choice": "PAY_OPERATION_ONLY", "amount": 500, "available": true },
    { "choice": "PAY_DEBT_ONLY", "amount": 100, "available": true },
    { "choice": "CANCEL", "amount": 0, "available": true }
  ],
  "debt_expires_at": "2026-11-15T11:00:00.000Z"
}

Stop polling, ask your customer (or apply your own rule), and answer:

curl -X POST "$API_URL/v3/mobile/resolve-debt" \
  -H "X-Access-Token: $API_KEY" -H "Content-Type: application/json" \
  -d '{"ref":"order-2001","choice":"PAY_ALL"}'
ChoiceWhat happensYour balance pays
PAY_ALLThe top-up is sent and the debt is paid.top-up + debt
PAY_OPERATION_ONLYThe top-up is sent; the debt stays on the line.top-up
PAY_DEBT_ONLYOnly the debt is paid (a top-up equal to the debt).debt
CANCELNothing is sent. The top-up ends REFUNDED.nothing

debt_options[].amount is the exact price of each choice, and available: false marks a choice you can't use (for example when the operator did not say how much is owed). The answer returns the top-up, now PENDING. Keep polling it as usual until it is final.

  • Unanswered: a DEBT_PENDING top-up is cancelled at debt_expires_at (30 minutes) and ends REFUNDED. Nothing is charged.
  • Never pause: send "on_debt": "CANCEL" with the top-up and a debt question cancels it at once (REFUNDED). The default is "WAIT".
  • Answering twice, or answering a top-up that is not DEBT_PENDING, returns 409 NOT_DEBT_PENDING.

Example result

GET /v3/mobile/check-ref/order-2001
{
  "success": true,
  "data": {
    "_id": "F00012345",
    "ref": "order-2001",
    "status": "COMPLETED",
    "plan_code": "PREPAID_MOBILIS",
    "MSSIDN": "0600000009",
    "topup_amount": 1000,
    "balance_amount": 1000,
    "created_at": "2026-11-15T10:30:00.000Z"
  },
  "meta": { "timestamp": "2026-11-15T10:30:12.000Z" },
  "requestId": "req_8fK2mQx7Lp0aZ3nV1cWb"
}

Listing top-ups

GET /v3/mobile/list?page=1&pageSize=20 returns top-ups sent with your API keys, newest first. Filter a period with from and to (ISO 8601, both together).

On this page