Skip to main content
This guide walks you through installing the required library, building the signing helper, logging in to obtain a session token, keeping that token fresh, and making authenticated API calls — all in Python.

Installation

Install the requests library if you do not already have it:
All other modules used in this guide (hashlib, urllib.parse, json, threading) are part of the Python standard library.

The signing library (bpm_lib.py)

Create a file called bpm_lib.py with the following content. The rest of your code will import from this file.
bpm_lib.py
Here is what each part does:
  • sign_key — your secret key, used as a suffix before hashing. Keep this value private.
  • creat_sign(value) — takes a list of "key=value" strings, sorts them, concatenates them, appends the secret key, percent-encodes the full string with urllib.parse.quote, and returns the uppercase MD5 hex digest.
  • log_in(phonenumber, password) — builds the signed parameter list, calls the login endpoint, parses the JSON response, and returns the token on success.
Never include sign_key in client-side code, public repositories, or logs. Treat it like a password.

Logging in

Import bpm_lib and call log_in with your credentials:
main.py
A successful login returns a non-empty token string. Pass this token to every subsequent API call.

Token refresh

Tokens are valid for 2 hours from the time of issue. The official demo schedules a refresh after 324,000 seconds — roughly 90 minutes — using threading.Timer, giving a 30-minute buffer before expiry.
token-refresh.py
Store token in a location accessible to all request functions, and always read the current value rather than caching it in a local variable across long-running operations.
The 324,000-second interval in the official demo script is intentional — it is approximately 90 minutes, not 2 hours. Using a value slightly shorter than the actual expiry prevents your token from becoming invalid mid-request.

Making authenticated API calls

After login, include both token and sign on every request. Build the parameter list the same way log_in does — format each parameter as "key=value", exclude sign, pass the list to creat_sign, then append sign to the request. The example below calls GET /api_esim/getSkus to retrieve available eSIM packages:
get-skus.py
Add any additional parameters to both params_list (for signing) and the params dict (for the request), keeping the two in sync.
Replace 'YOUR_PHONE_NUMBER' and 'YOUR_PASSWORD' with your actual MIOeSIM account credentials before running the code.