Developer API

Automate vending from your own platform. Every endpoint answers with JSON in the same shape: { status, msg }, where status is success or fail.

Base URL

https://easydata.2fast.com.ng/api/

Authentication

The login endpoint is authorised with today's date as the bearer token, in dd-mm-yyyy format. Every other endpoint is authorised with the license key returned by login. A staff license key also works, provided that staff member has the matching permission enabled.

Authorization: Bearer 09-09-2026          # login only
Authorization: Bearer <your license key>   # data, airtime to cash
Content-Type: application/json
POSThttps://easydata.2fast.com.ng/api/loginAccount or staff login

Validates an account owner or staff member and returns the license key used by all other endpoints.

Request body

FieldTypeDescription
emailstringrequiredAccount or staff email address.
passwordstringrequiredAccount or staff password.
rolestringoptional"admin" for the account owner, "staff" for a staff member. Omit to try both.
POST https://easydata.2fast.com.ng/api/login
Authorization: Bearer 09-09-2026
Content-Type: application/json

{
  "email": "you@example.com",
  "password": "your-password",
  "role": "admin"
}

Success response

{
  "status": "success",
  "msg": "Login successful.",
  "license_key": "XXXX-XXXX-XXXX-XXXX",
  "role": "admin",
  "full_name": "Jane Doe",
  "email": "you@example.com",
  "software_version": "1.0.0"
}

Failure response

{ "status": "fail", "msg": "Incorrect password." }

Other failures: missing or expired authorization token, no account found with this email, account is suspended, no license key attached, or the staff member has no login permission.

POSThttps://easydata.2fast.com.ng/api/dataBuy data

Vends a data bundle to a recipient using your connected SIMs. Duplicate references are rejected and each reference is locked while it runs, so the same order can never be vended twice.

Request body

FieldTypeDescription
networkstringrequired"mtn", "airtel" or "glo".
phone_numberstringrequiredRecipient number. msisdn or recipient also accepted.
transrefstringrequiredYour unique transaction reference. request_id or reference also accepted.
plan_idstringrequiredBundle id from your plan list. Send variation_code instead if you use codes.
variation_codestringoptionalAlternative to plan_id when your plans are keyed by code.
POST https://easydata.2fast.com.ng/api/data
Authorization: Bearer <license key>
Content-Type: application/json

{
  "network": "mtn",
  "phone_number": "08031234567",
  "plan_id": "1GB-30DAYS",
  "transref": "TRX-100045"
}

Success response

{
  "status": "success",
  "msg": "1GB 30 days sent to 08031234567. Sender: 0803*****67. Balance: 12.50 GB"
}

The sender number and sender balance only appear in the message when those options are enabled in that network's SIM settings.

Failure response

{ "status": "fail", "msg": "Duplicate transaction. Reference TRX-100045 has already been processed." }

Other failures: unsupported or missing network, recipient phone number is required, transaction reference is required, plan_id or variation_code is required, no active sponsor SIM configured, or the message returned by the network itself.

POSThttps://easydata.2fast.com.ng/api/airtime-to-cashAirtime to cash

Converts airtime from a customer's SIM into cash, in three steps. MTN and Airtel are supported. Each step is a separate call to the same path.

Step 1 — request OTP

FieldTypeDescription
networkstringrequired"mtn" or "airtel".
stepstringrequiredSend "1".
phone_numberstringrequiredCustomer number the airtime will come from.
{ "network": "mtn", "step": "1", "phone_number": "08031234567" }

-> { "status": "success", "msg": "OTP sent." }

For Airtel the success reply also carries device_id and client_device_id, which you must send back in step 2.

Step 2 — verify OTP

FieldTypeDescription
stepstringrequiredSend "2".
otpstringrequiredCode the customer received.
device_idstringoptionalAirtel only — value returned in step 1.
client_device_idstringoptionalAirtel only — value returned in step 1.
{ "network": "mtn", "step": "2", "phone_number": "08031234567", "otp": "123456" }

-> {
     "status": "success",
     "msg": "OTP verified. Airtime balance: 5000",
     "balance": 5000,
     "record": { "id": "8f0c...", "network": "mtn", "msisdn": "08031234567" }
   }

Step 3 — convert

FieldTypeDescription
stepstringrequiredSend "3".
record_idstringrequiredid from the step 2 record. id or quick_share_id also accepted.
amountnumberrequiredAirtime amount to convert.
pinstringrequiredCustomer transfer PIN.
transrefstringrequiredYour unique transaction reference.
{
  "network": "mtn",
  "step": "3",
  "record_id": "8f0c...",
  "amount": 2000,
  "pin": "1234",
  "transref": "A2C-90021"
}

-> { "status": "success", "msg": "NGN 2,000 airtime received from 08031234567." }

Failure response

{ "status": "fail", "msg": "This transaction reference has already been processed." }

Other failures: unsupported network, record id / amount / PIN are required, SIM record not found, Glo airtime to cash is not available yet, or the message returned by the network.

POSThttps://easydata.2fast.com.ng/api/add-simConnect a SIM

Connects an MTN, Airtel or Glo SIM to your account. MTN and Airtel run in two steps (request OTP, then verify). Glo connects in one call with the SIM PIN. After a successful reply the SIM's balance is fetched and saved in the background.

Request body

FieldTypeDescription
networkstringrequired"mtn", "airtel" or "glo". t2 is not available yet.
phone_numberstringrequiredSIM number. msisdn or phone also accepted.
stepstringoptional"request_otp" (default) or "verify_otp". Sending otp implies verify_otp.
otpstringoptionalRequired on the verify step for MTN and Airtel.
device_idstringoptionalAirtel verify step only — value returned in step 1.
client_device_idstringoptionalAirtel verify step only — value returned in step 1.
pinstringoptionalRequired for Glo (SIM PIN). Optional and stored for MTN / Airtel.
typestringoptionalYour own label for the SIM, e.g. gifting or SME.
prioritynumberoptionalLower numbers are used first when vending.
// step 1
{ "network": "mtn", "phone_number": "08031234567" }
-> { "status": "success", "msg": "OTP sent.",
     "data": { "phone_number": "08031234567", "next_step": "verify_otp" } }

// step 1 (airtel) also returns the ids needed in step 2
-> { "status": "success", "msg": "OTP sent.",
     "data": { "phone_number": "08161234567", "device_id": "...",
               "client_device_id": "...", "next_step": "verify_otp" } }

// step 2
{ "network": "mtn", "phone_number": "08031234567", "step": "verify_otp", "otp": "123456" }
-> { "status": "success", "msg": "MTN SIM connected successfully.",
     "data": { "phone_number": "08031234567" } }

// glo (single call)
{ "network": "glo", "phone_number": "08051234567", "pin": "1234" }
-> { "status": "success", "msg": "Glo SIM connected successfully." }

Failure response

{ "status": "fail", "msg": "This MTN number already exists on your account." }

Other failures: invalid network, a valid phone_number is required, OTP is required, device_id and client_device_id are required, PIN is required for Glo, no permission to add that network, or the exact message returned by the network.

GET / POSThttps://easydata.2fast.com.ng/api/category?network=mtn&page=1Data plans

Lists your saved data plans for one network, 20 per page. When you have no plan yet, live plans are pulled from the network and saved automatically. POST with action update to edit a plan or set its sponsor SIMs.

Request

FieldTypeDescription
networkstringrequired"mtn", "airtel" or "glo". Query string or body.
pagenumberoptionalPage number, default 1. 20 plans per page; a page past the last one returns the last page.
actionstringoptionalPOST only. Send "update" to save a plan.
idstringoptionalPlan id being updated.
volumestringoptionalPlan size, e.g. 1GB.
validitystringoptionalHow long the bundle lasts.
typestringoptionalGIFTING, CORPORATE GIFTING, SME or DIRECT.
descriptionstringoptionalPlan description shown to you.
provider_namestringoptionalWhich provider sells this plan.
provider_idstringoptionalProvider's own plan id.
provider_pricenumberoptionalCost price from the provider.
gatewaystring[]optionalSIM ids allowed to vend this plan, in order.
payment_methodstringoptionalMTN only — Airtime, Pulse, SCAPv2 or Wallet.
need_loan_checkerbooleanoptionalMTN only — check for airtime loan before vending.
check_loan_statusbooleanoptionalMTN only — confirm loan status on the SIM.

Success response

{
  "status": "success",
  "msg": "",
  "data": {
    "network": "mtn",
    "label": "MTN",
    "role": "Admin",
    "can_edit": true,
    "providers": ["My Mtn"],
    "plan_types": ["GIFTING", "CORPORATE GIFTING", "SME", "DIRECT"],
    "payment_methods": ["Airtime", "Pulse", "SCAPv2", "Wallet"],
    "totals": { "plans": 128, "gateway_sims": 4 },
    "pagination": { "page": 1, "pages": 7, "per_page": 20, "total": 128 },
    "sims": [{ "id": "8f0c...", "msisdn": "08031234567" }],
    "plans": [{
      "id": "1a2b...",
      "volume": "1GB", "validity": "30 days", "type": "GIFTING",
      "description": "Data - 1GB Monthly",
      "plan_id": "48210377", "variation_code": "K7T2M9QPXA4821",
      "provider_id": "1001", "provider_name": "My Mtn", "provider_price": 490,
      "gateway": { "sims": ["8f0c..."], "numbers": ["08031234567"] },
      "payment_method": "Airtime",
      "need_loan_checker": false,
      "check_loan_status": false
    }]
  }
}

Failure response

{ "status": "fail", "msg": "Connect an MTN SIM first so we can load live MTN plans.", "data": null }
GET / POSThttps://easydata.2fast.com.ng/api/dashboardToday's summary

Returns today's totals for your account: per-service counts, success rate, total GB of data sold and the last 10 transactions. The day runs on Lagos time. No request body is needed.

Success response

{
  "status": "success",
  "msg": "Dashboard loaded.",
  "data": {
    "viewer": { "name": "Jane Doe", "role": "admin" },
    "date": { "label": "Thursday, 10 September 2026",
              "start": "2026-09-09T23:00:00.000Z",
              "end": "2026-09-10T23:00:00.000Z",
              "timezone": "Africa/Lagos" },
    "success_rate": 96,
    "services": [
      { "key": "data", "title": "Data (GB sold)", "total": 120, "success": 116, "failed": 4, "pending": 0 },
      { "key": "a2c", "title": "Airtime To Cash", "total": 8, "success": 8, "failed": 0, "pending": 0 },
      { "key": "airtime", "title": "Airtime", "total": 0, "success": 0, "failed": 0, "pending": 0 }
    ],
    "all": { "total": 128, "success": 124 },
    "data_volume": { "total_gb": 214.5, "label": "214.50 GB" },
    "recent": [{
      "transref": "TRX-100045", "msisdn": "08031234567",
      "volume": "1GB", "validity": "30 days", "provider_name": "My Mtn",
      "service": "data", "status": "success", "status_label": "Successful",
      "created_at": "2026-09-10T12:41:08.204Z", "time_label": "13:41"
    }]
  }
}

Failure response

{ "status": "fail", "msg": "You do not have permission to view the dashboard.", "data": null }
POSThttps://easydata.2fast.com.ng/api/create-staffsCreate a staff member

Account owners only. Creates a staff member and returns the license key that staff will use on every other endpoint.

Request body

FieldTypeDescription
full_namestringrequiredStaff full name. name also accepted.
emailstringrequiredStaff email, used to sign in. Must be unique on your account.
passwordstringrequiredAt least 4 characters.
phone_numberstringoptionalStaff phone number. phone also accepted.
rolestringoptionalJob title. Defaults to "Staff".
permissionsobjectoptionalPermission keys set to true or false. You can also send them one by one as perm_can_login: true.
POST https://easydata.2fast.com.ng/api/create-staffs
Authorization: Bearer <owner license key>

{
  "full_name": "Musa Bello",
  "email": "musa@example.com",
  "phone_number": "08031234567",
  "password": "secret123",
  "role": "Vendor",
  "permissions": { "can_login": true, "can_view_dashboard": true, "can_vend_mtn_data": true }
}

Success response

{
  "status": "success",
  "msg": "Musa Bello can now sign in with musa@example.com.",
  "data": {
    "staff": {
      "id": "3c9a...", "user_id": "...", "full_name": "Musa Bello",
      "email": "musa@example.com", "phone_number": "08031234567",
      "role": "Vendor", "status": "active",
      "license_key": "9f2c8d1a4b6e0f37...",
      "staff_permission": { "can_login": true, "can_view_dashboard": true, "...": false },
      "created_at": "2026-09-10T12:41:08.204Z"
    },
    "permission_keys": ["can_login", "can_view_dashboard", "..."]
  }
}

Permission keys: can_login, can_view_dashboard, can_view_profile, can_edit_profile, can_view_ip_whitelist, can_manage_ip_whitelist, can_add_mtn_sim, can_add_airtel_sim, can_add_glo_sim, can_add_t2_sim, can_vend_mtn_data, can_vend_airtel_data, can_vend_glo_data, can_vend_t2_data, can_vend_vitel_data, can_convert_mtn_airtime_to_cash, can_convert_airtel_airtime_to_cash, can_convert_glo_airtime_to_cash. Any key you leave out is saved as false.

Failure response

{ "status": "fail", "msg": "musa@example.com already belongs to one of your staffs.", "data": null }
POSThttps://easydata.2fast.com.ng/api/create-groupCreate a datashare group

Creates a group that datashare SIMs are placed into. Group names are unique per account.

Request body

FieldTypeDescription
namestringrequiredGroup name, 60 characters or less. group_name also accepted.
typestringoptionalYour own label for the group.
prioritynumberoptionalLower numbers are used first.
policyobjectoptionalSharing rules for the group. A JSON string is also accepted.
policy_statusstringoptional"active" or "inactive". Defaults to active when a policy is sent.
statusstringoptional"active" (default) or "disabled".
{ "name": "Lagos gifting", "type": "gifting", "priority": 1, "status": "active" }

-> {
     "status": "success",
     "msg": "\"Lagos gifting\" is ready. You can now move SIMs into it.",
     "data": { "group": {
       "id": "6b21...", "name": "Lagos gifting", "type": "gifting",
       "priority": 1, "policy": null, "policy_status": "inactive",
       "status": "active", "added_by": "Admin",
       "created_at": "2026-09-10T12:41:08.204Z"
     } }
   }

Failure response

{ "status": "fail", "msg": "A group named \"Lagos gifting\" already exists.", "data": null }
POSThttps://easydata.2fast.com.ng/api/data-share-add-simConnect a datashare SIM

Connects an MTN SIM straight into a datashare group, in two steps. After the success reply the balance and data bundles are read and saved in the background.

Request body

FieldTypeDescription
phone_numberstringrequiredMTN SIM number. msisdn or phone also accepted.
group_idstringrequiredGroup the SIM belongs to. Must be one of your groups.
stepstringoptional"request_otp" (default) or "verify_otp". Sending otp implies verify_otp.
otpstringrequiredRequired on the verify step.
is_masterbooleanoptionalMake this the master SIM of the group; the previous master is cleared.
typestringoptionalYour own label. Defaults to "mtn".
prioritynumberoptionalLower numbers share first.
// step 1
{ "phone_number": "08031234567", "group_id": "6b21..." }
-> { "status": "success", "msg": "OTP sent.",
     "data": { "phone_number": "08031234567", "group_id": "6b21...", "next_step": "verify_otp" } }

// step 2
{ "phone_number": "08031234567", "group_id": "6b21...", "otp": "123456", "is_master": true }
-> { "status": "success", "msg": "MTN SIM connected to the datashare group successfully.",
     "data": { "phone_number": "08031234567", "group_id": "6b21..." } }

Failure response

{ "status": "fail", "msg": "This number is already connected to your datashare system.", "data": null }

Other failures: a valid phone_number is required, a group_id is required, that group does not belong to your account, OTP is required, no permission to connect datashare SIMs, or the message MTN returned.

GET / POSThttps://easydata.2fast.com.ng/api/data-share-settingsDatashare settings

Reads and saves the rules the datashare system runs on. The first GET creates your settings with sensible defaults. POST only the fields you want to change.

Fields

FieldTypeDescription
enable_failoverbooleanoptionalRetry a failed share on the next available SIM.
max_retrynumberoptionalHow many SIMs to try before giving up.
daily_limitnumberoptionalMaximum share requests per SIM each day.
monthly_limitnumberoptionalMaximum share requests per SIM each month.
max_daily_gbnumberoptionalMaximum GB a single SIM can share per day.
max_monthly_gbnumberoptionalMaximum GB a single SIM can share per month.
reset_monthly_statsbooleanoptionalClear monthly counters at the start of each month.
request_failedbooleanoptionalSend a notice whenever a share request fails.
daily_limit_reachedbooleanoptionalSend a notice when a SIM hits its daily limit.
monthly_limit_reachedbooleanoptionalSend a notice when a SIM hits its monthly limit.
no_active_databooleanoptionalSend a notice when no SIM has data left to share.
send_sender_numberbooleanoptionalInclude the sponsor SIM number in the receiver's SMS.
mask_sender_numberbooleanoptionalHide part of the sponsor number when it is sent.
send_sender_balancebooleanoptionalInclude the sponsor SIM balance in the receiver's SMS.
statusstringoptional"active" or "disabled".
POST { "max_retry": 5, "daily_limit": 80, "status": "active" }

-> {
     "status": "success",
     "msg": "Datashare settings saved.",
     "data": {
       "can_edit": true,
       "settings": {
         "id": "...", "user_id": "...",
         "enable_failover": true, "max_retry": 5,
         "daily_limit": 80, "monthly_limit": 1000,
         "max_daily_gb": 20, "max_monthly_gb": 400,
         "reset_monthly_stats": true, "request_failed": true,
         "daily_limit_reached": true, "monthly_limit_reached": true,
         "no_active_data": true, "send_sender_number": false,
         "mask_sender_number": true, "send_sender_balance": false,
         "status": "active",
         "created_at": "...", "updated_at": "..."
       },
       "fields": {
         "toggles": [{ "key": "enable_failover", "label": "Enable failover", "purpose": "..." }],
         "numbers": [{ "key": "max_retry", "label": "Max retry", "purpose": "...", "integer": true }],
         "status": { "key": "status", "label": "Datashare status", "options": ["active", "disabled"] }
       }
     }
   }

GET replies the same shape with the message "Datashare settings loaded.". Sending no known field replies "Nothing to update.".

Failure response

{ "status": "fail", "msg": "You do not have permission to update datashare settings.", "data": null }
GEThttps://easydata.2fast.com.ng/api/data-share-systemDatashare overview

One call that returns every datashare group with its totals, worked out inside the database so the reply stays small. No request body.

Success response

{
  "status": "success",
  "msg": "Datashare system loaded.",
  "data": {
    "total_groups": 2,
    "groups": [{
      "id": "6b21...", "name": "Lagos gifting", "type": "gifting",
      "priority": 1, "status": "active",
      "total_sims": 12, "active_sims": 11,
      "total_data_mb": 184320, "today_gb": 42.5, "today_count": 96
    }]
  }
}

The overview also carries your account totals and settings alongside the groups list.

Failure response

{ "status": "fail", "msg": "You are not allowed to view the Datashare system.", "data": null }
POSThttps://easydata.2fast.com.ng/api/get-sim-balanceRefresh a SIM balance

Reads the live airtime and data balance of one connected SIM and saves it. MTN signs in again with the stored key, Airtel and Glo reuse their session and Glo refreshes it when it has expired.

Request body

FieldTypeDescription
sim_idstringrequiredId of the SIM to refresh. id also accepted.
networkstringoptional"mtn", "airtel" or "glo" (sim1 / sim2 / sim3 also work). Leave it out and all three are searched.
{ "sim_id": "8f0c...", "network": "mtn" }

-> {
     "status": "success",
     "msg": "MTN balance refreshed.",
     "data": {
       "network": "mtn", "sim_id": "8f0c...",
       "airtime": 5420.75, "data": 12800, "data_label": "12.50 GB",
       "balance": { "airtime": 5420.75, "data": 12800,
                    "data_label": "12.50 GB",
                    "refreshed_at": "2026-09-10T12:41:08.204Z" }
     }
   }

Data is returned in MB; data_label is the same figure written out.

Failure response

{ "status": "fail", "msg": "SIM not found on this account.", "data": null }

Other failures: sim_id is required, no permission to refresh that network's SIM balance, balance was fetched but could not be saved, or the message returned by the network.

GET / POSThttps://easydata.2fast.com.ng/api/quick-share-settingAirtime to cash receiving numbers

Manages the numbers that receive converted airtime, per network. GET returns every network you may manage; POST adds, edits or removes a receiving number, resets today's total, or turns a network on and off. Both always reply with the full, freshly loaded list.

Request body (POST)

FieldTypeDescription
actionstringrequired"add_gateway", "save_gateway", "remove_gateway", "reset_today", "status" or "refresh".
networkstringrequired"mtn", "airtel" or "glo". Not needed for refresh.
sim_idstringrequiredThe connected SIM that receives the airtime. gateway_id or id also accepted. Not needed for status.
max_requestnumberoptionalHighest single amount this line may accept. Required when adding.
sender_balancebooleanoptionalInclude the sending SIM's new balance in the customer's reply.
today_total_amount_receivednumberoptionalOverride today's received total on save_gateway.
statusstringoptionalWith action status — "active" or "inactive" for the whole network.
{ "action": "add_gateway", "network": "mtn", "sim_id": "8f0c...",
  "max_request": 50000, "sender_balance": true }

-> {
     "status": "success",
     "msg": "08031234567 added as a receiving number.",
     "data": {
       "role": "Admin", "can_edit": true,
       "totals": { "gateways": 3, "today_total_amount_received": 128500,
                   "networks_enabled": 2, "networks": 3 },
       "hints": { "max_request": "...", "today_total": "...", "sender_balance": "...",
                  "status": "...", "gateway": "..." },
       "networks": [{
         "network": "mtn", "label": "MTN",
         "status": "active", "enabled": true,
         "today_total_amount_received": 98500,
         "gateways": [{ "sim_id": "8f0c...", "msisdn": "08031234567",
                        "max_request": 50000,
                        "today_total_amount_received": 98500,
                        "sender_balance": true }],
         "available_sims": [{ "id": "1a2b...", "msisdn": "08039876543" }],
         "connected_sims": [{ "id": "8f0c...", "msisdn": "08031234567" }]
       }]
     }
   }

Failure response

{ "status": "fail", "msg": "That number is already a receiving gateway.", "data": null }

Other failures: choose MTN, Airtel or Glo, no permission to manage that network's gateways, choose the receiving number first, max request must be greater than zero, or unknown action.

GET / POSThttps://easydata.2fast.com.ng/api/vending-policy?group_id=6b21...Vending policy

Reads and saves the sharing policy of one datashare group or one datashare SIM. Send exactly one of group_id or sim_id, in the query string or in the body. A target with no saved policy replies with the default plan list.

Request

FieldTypeDescription
group_idstringrequiredGroup whose policy you want. Send this or sim_id, never both.
sim_idstringrequiredDatashare SIM whose policy you want. Send this or group_id, never both.
policyarrayoptionalPOST only. The full plan list to save.
policy[].volumestringrequired100MB, 200MB, 500MB, 1GB, 2GB, 3GB or 5GB.
policy[].validitystringrequired7Days, 14Days or 30Days.
policy[].howManyTimesnumberrequiredHow many times that plan may be shared. 0 blocks it.
GET https://easydata.2fast.com.ng/api/vending-policy?group_id=6b21...

-> {
     "status": "success",
     "msg": "Vending policy loaded.",
     "data": {
       "target": { "type": "group", "id": "6b21...", "label": "Lagos gifting" },
       "can_edit": true,
       "plans": [{ "volume": "1GB", "validity": "30Days", "howManyTimes": 1 }],
       "validities": ["7Days", "14Days", "30Days"],
       "volumes": ["100MB", "200MB", "500MB", "1GB", "2GB", "3GB", "5GB"]
     }
   }

POST { "group_id": "6b21...",
       "policy": [{ "volume": "1GB", "validity": "30Days", "howManyTimes": 3 }] }

-> { "status": "success", "msg": "Policy updated successfully.",
     "data": { "target": { "type": "group", "id": "6b21..." },
               "can_edit": true, "plans": [ ... ],
               "validities": [ ... ], "volumes": [ ... ] } }

Saving a group policy also switches that group's policy status to active. Any plan you leave out keeps its default of one share.

Failure response

{ "status": "fail", "msg": "Pass exactly one group_id or sim_id.", "data": null }

Other failures: unauthorized, selected record not found, no permission to update this policy, policy must be a plan list, or one or more policy values are invalid.

POSThttps://easydata.2fast.com.ng/api/update-staffsUpdate or delete a staff member

Account owners only. Send only the fields you want to change. Permissions you leave out keep their current value.

Request body

FieldTypeDescription
idstringrequiredStaff id. staff_id also accepted.
actionstringoptionalSend "delete" to remove the staff member.
full_namestringoptionalStaff full name. name also accepted.
emailstringoptionalMust be a valid address and unique on your account.
phone_numberstringoptionalStaff phone number. phone also accepted.
passwordstringoptionalNew password, at least 4 characters.
rolestringoptionalJob title.
statusstringoptional"active", "disabled" or "suspended". "inactive" is saved as disabled.
permissionsobjectoptionalPermission keys to change. You can also send them one by one as perm_can_login: true.
POST https://easydata.2fast.com.ng/api/update-staffs
Authorization: Bearer <owner license key>

{
  "id": "3c9a...",
  "role": "Senior Vendor",
  "status": "active",
  "permissions": { "can_vend_airtel_data": true }
}

-> { "status": "success", "msg": "Staff updated successfully.",
     "data": { "id": "3c9a...", "updated": { "role": "Senior Vendor", "status": "active",
               "staff_permission": { "can_login": true, "...": false } } } }

// delete
{ "action": "delete", "id": "3c9a..." }
-> { "status": "success", "msg": "Staff deleted.", "data": { "id": "3c9a...", "action": "delete" } }

Sending nothing to change replies "No changes were supplied." with updated: false.

Failure response

{ "status": "fail", "msg": "That staff does not belong to your account.", "data": null }

Other failures: missing license key, only the account owner can update staffs, no staff was selected, please provide a valid email address, that email already belongs to another staff, password must be at least 4 characters, or status must be active or disabled.

POSThttps://easydata.2fast.com.ng/api/update-groupUpdate or delete a datashare group

Updates one of your datashare groups, or deletes it. Deleting a group leaves its SIMs in place and simply ungroups them. This endpoint answers with a small HTML result card rather than JSON.

Request body

FieldTypeDescription
group_idstringrequiredGroup to change. id also accepted.
actionstringoptionalSend "delete" to remove the group.
namestringoptionalNew group name. Must not match another of your groups.
typestringoptionalYour own label. Send an empty value to clear it.
prioritynumberoptionalLower numbers are used first. Empty clears it.
policyobjectoptionalSharing rules. A JSON string is also accepted; empty clears it.
policy_statusstringoptional"active" or "inactive".
statusstringoptional"active" or "disabled".
POST https://easydata.2fast.com.ng/api/update-group
Authorization: Bearer <license key>

{ "group_id": "6b21...", "name": "Lagos gifting", "priority": 2, "status": "active" }

-> HTML: "Group updated — Your changes have been saved."

// delete
{ "group_id": "6b21...", "action": "delete" }
-> HTML: "Group deleted — The group was removed and its SIMs are now ungrouped."

Failure response

HTML: "Duplicate group — Another group is already named \"Lagos gifting\"."

Other failures: unauthorized, no group was selected, that group does not belong to your account, priority must be a number, the policy you supplied is not valid JSON, status must be active or disabled, or you do not have permission to update datashare groups. Sending no field replies "Nothing to update.".

Notes

  • All requests are POST with a JSON body and always return HTTP 200 — read the status field.
  • Reuse of a transaction reference is always rejected, so retries are safe.
  • Keep your license key private; anyone holding it can vend from your SIMs.