mobileproxy.app

API

Dokumentacja API

Kompletna dokumentacja REST API mobileproxy.app, endpoint po endpoincie. Każda ścieżka, pole i przykład odzwierciedla tutaj aktualny dokument OpenAPI, na którym zbudowane jest API. Bazowy adres URL to https://mobileproxy.app/api/v1.

Uwierzytelnianie i adres bazowy

Każdy endpoint znajduje się pod https://mobileproxy.app/api/v1 i wymaga tokenu bearer. Utwórz go w panelu w sekcji Dla programistów → Tokeny API lub przez POST /tokens, będąc zalogowanym. Sekret jest pokazywany tylko raz — zapisz go. Wysyłaj go przy każdym żądaniu:

Authorization: Bearer mpx_live_…

Tokeny zaczynające się od mpx_live_ to tokeny Twojego konta. Endpointy /device/* są wywoływane przez samą aplikację Android i uwierzytelniają się tokenem urządzenia przypisanym do konkretnego telefonu (mpxdev_…), wydawanym podczas parowania — zwykle nigdy ich nie wywołujesz.

Wypróbuj na żywo
Interaktywna konsola pozwala wkleić token i wywołać każdy endpoint z poziomu przeglądarki, wraz z treścią żądań i rzeczywistymi odpowiedziami. Surowa specyfikacja znajduje się pod adresem /api/v1/openapi.json.

Błędy mają postać JSON z komunikatem dla człowieka i kodem maszynowym:

{ "error": "No such device.", "code": "not_found" }
PoleTypOpis
401unauthorizedBrakujący, nieprawidłowy lub unieważniony token.
403forbiddenToken prawidłowy, ale bez uprawnień.
404not_foundZasób nie istnieje na tym koncie.
502control_plane_unavailableBrama / warstwa sterowania chwilowo nieosiągalna — ponów próbę.

Konto

GET /me — kim jestem? Zwraca konto oraz bieżącą liczbę subskrypcji i tokenów API.

curl https://mobileproxy.app/api/v1/me \
     -H "Authorization: Bearer mpx_live_…"

# → { "id": "u_8c31f0", "email": "you@example.com",
#     "created_at": "2026-06-28T14:02:11.000Z",
#     "subscriptions": 3, "api_tokens": 2,
#     "plan": "beta", "balance": "0.00" }

Subskrypcje

Subskrypcja (id sub_…) to trwały slot, który posiadasz: jej przyjazna nazwa (name), ustawienia i proxy zachowują się nawet przy zmianie telefonu pod nią. Jej device to telefon, który ją aktualnie napędza (lub null, gdy niesparowana), i jest wymienny — wymiana zachowuje każdy endpoint proxy.

Wylistuj subskrypcje — każda z jej sparowanym urządzeniem połączonym z bieżącym statusem bramy (online = tunel proxy działa):

curl https://mobileproxy.app/api/v1/subscriptions \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscriptions": [ {
#     "id": "sub_760c1fc8ddab", "name": "Paris SFR",
#     "status": "active", "wifi_split": true, "created_at": "…",
#     "device": { "id": "phone_ac862619408e", "model": "Galaxy S8",
#                 "hardware_id": "352091081234567", "hardware_type": "imei",
#                 "status": "online", "exit_ip": "77.136.66.63",
#                 "carrier": "SFR", "last_seen": "…", "paired_at": "…" } } ] }

Utwórz subskrypcję (niesparowaną), a następnie sparuj lub wymień telefon. POST /subscriptions/{id}/pair zwraca PIN ważny ok. 3 minuty; wpisany w aplikacji Android wiąże telefon. Na slocie, który ma już urządzenie, jest to wymiana (mode: "swap") — stary telefon zostaje wycofany, a każde proxy zachowuje swój host:port i poświadczenia:

curl -X POST https://mobileproxy.app/api/v1/subscriptions \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" -d '{ "name": "Paris SFR" }'
# → { "id": "sub_760c1fc8ddab", "status": "unpaired", "device": null, … }

# Pair (or swap) a phone into it
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/pair \
     -H "Authorization: Bearer mpx_live_…"
# → { "subscription_id": "sub_760c1fc8ddab", "mode": "new",
#     "pairing": { "pin": "483-119-702", "expires_at": "…" }, … }

Pobierz, zaktualizuj lub anuluj pojedynczą subskrypcję. POST zmienia nazwę, dowolny opis description (maks. 200 znaków, null go czyści), preferencję wifi_split (kolejkowaną do sparowanego telefonu, stosowaną przy jego kolejnym odpytaniu ~25 s) lub shared_speed_kbps — sposób podziału prędkości urządzenia między jego proxy. -1 (zalecane) dzieli ją automatycznie: warstwa sterowania mierzy rzeczywistą prędkość urządzenia na podstawie bieżącej przepustowości (rebalans ~3 s), proxy zajęte w tym samym czasie zbiegają się do równych udziałów, a proxy działające samotnie otrzymuje pełną prędkość. Wartość > 0 dzieli w ten sam sposób ten stały łączny limit urządzenia. Wartości speed_limit_kbps dla poszczególnych proxy są zachowywane, ale nie egzekwowane, gdy któreś z tych ustawień jest włączone; 0 wyłącza współdzielenie. DELETE likwiduje urządzenie i proxy, zwalnia porty bramy oraz usuwa historię slotu — nieodwracalnie:

# Fetch one subscription
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID \
     -H "Authorization: Bearer mpx_live_…"

# Rename / describe / set Wi-Fi split / share the device's speed equally (auto)
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "name": "Paris SFR", "description": "Client X — farm slot 2", "wifi_split": true, "shared_speed_kbps": -1 }'

# Cancel (irreversible)
curl -X DELETE https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID \
     -H "Authorization: Bearer mpx_live_…"
# → { "deleted": true, "id": "sub_760c1fc8ddab" }

Proxy

Proxy to jeden endpoint jednoprotokołowy (SOCKS5 lub HTTP) na urządzeniu, z własnym uwierzytelnianiem, białą listą źródłowych IP, limitem prędkości i regułami domen. To, ile ich urządzenie może obsłużyć jednocześnie, wynika z uprawnień planu (10 w Standard, 20 w Pro) — twórz po jednym na klienta lub narzędzie i unieważniaj dowolne bez ruszania pozostałych. Utworzenie ponad limit planu zwraca 409 proxy_limit_reached.

Proxy na urządzeniu współdzielą jego IP
Każde proxy na urządzeniu wychodzi przez ten sam IP operatora i rotuje razem — utworzenie drugiego proxy daje drugie poświadczenie i politykę, a nie drugi IP. Aby uzyskać inny IP, sparuj kolejny telefon.

Utwórz proxy — generuje nową nazwę użytkownika i hasło; hasło jest zwracane jawnie tylko raz, tutaj. Wybierz protocol (socks5 lub http) i opcjonalnie przekaż traffic_limit_bytes, aby od razu nadać mu twardy limit ruchu:

curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "protocol": "socks5", "traffic_limit_bytes": 5368709120 }'

# → { "id": "acc_5f734b9270e8", "subscription_id": "sub_760c1fc8ddab",
#     "protocol": "socks5",
#     "host": "173.249.36.102", "host_v6": "2a02:c207:2319:6018::1",
#     "port": 30000,
#     "username": "u04c770", "password": "k7Qp2mXe9wZ4",
#     "endpoint": "socks5://u04c770:k7Qp2mXe9wZ4@173.249.36.102:30000",
#     "endpoint_ipv6": "socks5://u04c770:k7Qp2mXe9wZ4@[2a02:c207:2319:6018::1]:30000",
#     "ip_whitelist": [], "speed_limit_kbps": 0,
#     "domain_mode": "none", "domain_rules": [],
#     "status": "active", "traffic_limit_bytes": 5368709120, "bytes_used": 0,
#     "over_limit": false, "created_at": "…" }
Każdy port proxy jest dual-stack (IPv4 + IPv6)
Łącz się przez dowolną rodzinę — endpoint to URI IPv4, endpoint_ipv6 to ten sam port przez IPv6 (literał v6 jest w nawiasach kwadratowych, zgodnie ze składnią URL). Biała lista źródłowych IP przyjmuje adresy i zakresy CIDR IPv4 oraz IPv6, a cele również mogą być w IPv6: SOCKS5 CONNECT do literału IPv6 lub domeny z samym rekordem AAAA wychodzi przez IPv6 operatora telefonu, o ile SIM go ma.

Edytuj politykę proxy — tryb uwierzytelniania, białą listę IP, limit prędkości i reguły domen, stosowane na żywo w bramie (protocol jest stały — zamiast tego usuń i utwórz ponownie):

curl -X PATCH \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID \
  -H "Authorization: Bearer mpx_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "speed_limit_kbps": 2000,
        "domain_mode": "whitelist", "domain_rules": ["api.example.com"] }'

Wylistuj proxy — na jednym urządzeniu lub wszystkie proxy w całym koncie:

# One device
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies \
     -H "Authorization: Bearer mpx_live_…"

# Account-wide
curl https://mobileproxy.app/api/v1/proxies \
     -H "Authorization: Bearer mpx_live_…"
# → { "proxies": [ { …Proxy… }, … ] }

Działające proxy z ich wyjściowymi IP — listing dla całego konta zawiera bieżące exit_ip każdego proxy, aktualny status urządzenia oraz werdykt working (urządzenie online, brak blokady rozliczeniowej ani ręcznej, bez przekroczonego limitu ruchu; not_working_reason mówi, dlaczego nie). Filtruj przez ?working=true, a dodaj ?unique_ip=true, aby zachować jedno proxy na każdy odrębny wyjściowy IP — dwie karty SIM za tym samym NAT-em operatora są też oznaczane przez duplicate_ip:

# Working proxies only, one per distinct exit IP — a paste-ready pool
curl "https://mobileproxy.app/api/v1/proxies?working=true&unique_ip=true" \
     -H "Authorization: Bearer mpx_live_…"
# → { "proxies": [ {
#       "endpoint": "socks5://user:pass@173.249.36.102:30012",
#       "exit_ip": "77.136.66.44", "device_status": "online",
#       "working": true, "not_working_reason": null,
#       "duplicate_ip": false, … }, … ] }

Unieważnij proxy — natychmiast zatrzymuje ten jeden nasłuch; każde inne proxy na urządzeniu działa dalej:

curl -X DELETE \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID \
  -H "Authorization: Bearer mpx_live_…"
# → { "deleted": true, "id": "acc_5f734b9270e8" }

Limity zużycia i wygasanie dla poszczególnych proxy

Nadaj dowolnemu proxy limit zużycia — idealne, gdy odsprzedajesz dostęp i rozliczasz każdego klienta według przydziału danych. Ustaw go lub zmień w dowolnym momencie (0 go czyści): przy tworzeniu, przez PATCH lub za pomocą dedykowanego endpointu poniżej. Gdy bytes_used osiągnie limit, proxy zostaje zablokowane: zachowuje swój port i poświadczenia, ale odrzuca każde żądanie, a over_limit przyjmuje wartość true. Podnieś limit powyżej zużytej ilości — albo go wyczyść — a proxy wznowi działanie natychmiast, ten sam endpoint, bez ponownej konfiguracji. Listowanie proxy zwraca też dla każdego traffic_limit_bytes, bieżące bytes_used oraz over_limit.

curl -X POST \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/limit \
  -H "Authorization: Bearer mpx_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "traffic_limit_bytes": 10737418240 }'   # 10 GB — or 0 to remove
# → { "proxy_id": "acc_5f734b9270e8", "subscription_id": "sub_760c1fc8ddab",
#     "traffic_limit_bytes": 10737418240, "over_limit": false }

Wygasanie w czasie — nadaj proxy moment expires_at (ISO 8601, w przyszłości) przy tworzeniu lub przez PATCH; null czyści oczekujące wygaśnięcie. W tym momencie proxy zostaje wycofane — trwale, w przeciwieństwie do odwracalnej blokady limitu zużycia. Aby odnowić klienta, utwórz nowe proxy (nowy port i poświadczenia). Idealne do sprzedaży przepustek dziennych/tygodniowych:

# A proxy that stops serving in 7 days
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "protocol": "socks5", "expires_at": "2026-07-13T09:00:00Z" }'

# Extend or clear it later
curl -X PATCH \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID \
  -H "Authorization: Bearer mpx_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "expires_at": "2026-07-20T09:00:00Z" }'   # or null to remove

VPN configs (WireGuard)

Turn a SOCKS5 username/password proxy into a full-device WireGuard tunnel. Each proxy can carry one WireGuard config; creation requires the VPN add-on. Legacy OpenVPN rows remain downloadable and revocable, but new OpenVPN configs cannot be provisioned.

Plik jest pokazywany tylko raz
The create response includes the full WireGuard file and its client private key. Store it securely; the same file can be downloaded later from the file endpoint.
# Create a WireGuard config on a proxy
curl -X POST \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/vpn-configs \
  -H "Authorization: Bearer mpx_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "kind": "wireguard", "name": "My laptop" }'
# → { "id": "vpn_9f2c1a0b7e", "kind": "wireguard", "client_ip": "10.77.0.2",
#     "config_text": "[Interface]\nPrivateKey = …\n[Peer]\n…", … }

# List a proxy's configs (metadata + usage vs the one-config cap)
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/vpn-configs \
     -H "Authorization: Bearer mpx_live_…"

# Re-download the file straight to disk
curl -OJ \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/vpn-configs/vpn_9f2c1a0b7e/file \
  -H "Authorization: Bearer mpx_live_…"

# Revoke (drops the WireGuard peer and kills any live session)
curl -X DELETE \
  https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/proxies/PROXY_ID/vpn-configs/vpn_9f2c1a0b7e \
  -H "Authorization: Bearer mpx_live_…"

Use the file with wg-quick up ./mpx-9f2c1a0b.conf or import it into a WireGuard client. Rotating the proxy also rotates the VPN exit.

Rotacja IP

Rotacja prosi operatora o nowy IP. Działa per urządzenie — każde proxy na urządzeniu dostaje nowy IP — jest kolejkowana do telefonu i stosowana w ciągu jednego cyklu odpytywania (~25 s).

Best-effort w sieciach komórkowych
To, czy ponowne połączenie da nowy adres, zależy od operatora — niektórzy przydzielają ten sam IP przy szybkich ponownych połączeniach. Potwierdź w exit_ip urządzenia lub w /ip-history.

Rotuj teraz — zakolejkuj jednorazową rotację:

curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/change-ip \
     -H "Authorization: Bearer mpx_live_…"

# → { "status": "rotating", "subscription_id": "sub_760c1fc8ddab",
#     "command_id": "cmd_a41b",
#     "note": "IP rotation on mobile networks is best-effort; …" }

Rotacja do unikatowego IP — przekaż unique: true, aby rotować, dopóki wyjściowy IP nie będzie takim, którego nie odnotowano w ostatnich window_min minutach historii IP tej subskrypcji (domyślnie 60, maks. 1440), ponawiając próbę do max_attempts razy (domyślnie 3, maks. 5). Każda próba kosztuje pełny cykl rotacji (~30–90 s); odpytuj wariant GET, aby śledzić postęp. Operatorzy mogą zgodnie z prawem ponownie przydzielić ten sam IP, więc exhausted to możliwy uczciwy wynik:

curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/change-ip \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "unique": true, "window_min": 60, "max_attempts": 3 }'
# → { "status": "rotating", "request_id": "rr_18d2c4", "command_id": "cmd_a41b",
#     "unique": { "window_min": 60, "max_attempts": 3 }, … }

# Poll for the outcome (active | succeeded | exhausted | superseded | expired)
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/change-ip \
     -H "Authorization: Bearer mpx_live_…"
# → { "request_id": "rr_18d2c4", "status": "succeeded",
#     "attempts_used": 2, "attempts_max": 3, "window_min": 60,
#     "started_ip": "77.136.66.63", "result_ip": "77.136.67.101", … }

Rotacja zbiorcza — rotuj każde sparowane urządzenie jednym wywołaniem z all: true albo wybrany zestaw przez subscription_ids (jedno albo drugie jest wymagane, więc błędne żądanie nigdy nie zrotuje przez przypadek całej Twojej floty). Przyjmuje te same opcje unique co endpoint per subskrypcja, a każda subskrypcja raportuje własny wynik — jeden wstrzymany lub niesparowany slot nigdy nie oblewa całej partii. Wymaga roli operatora dla każdej subskrypcji:

# Rotate every paired device at once (explicit opt-in)…
curl -X POST https://mobileproxy.app/api/v1/proxies/rotate \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "all": true }'

# …or a chosen set, with the unique-IP options
curl -X POST https://mobileproxy.app/api/v1/proxies/rotate \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "subscription_ids": ["sub_760c1fc8ddab"], "unique": true }'
# → { "results": [ { "subscription_id": "sub_760c1fc8ddab",
#       "status": "rotating", "command_id": "…", "request_id": "rr_18d2c4" } ],
#     "rotating": 1, "skipped": 0, … }

Linki rotacyjne — tokenizowany URL, który rotuje IP tego urządzenia po pobraniu, bez nagłówka uwierzytelniania (sekretem jest token). Wklej go do dowolnego narzędzia obsługującego „rotation URL”. Listuj, twórz i unieważniaj je:

# List rotation links
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation-links \
     -H "Authorization: Bearer mpx_live_…"
# → { "rotation_links": [ { "token": "rk_9f2c81d4e7",
#       "url": "https://mobileproxy.app/rotate/rk_9f2c81d4e7", "created_at": "…" } ] }

# Create one
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation-links \
     -H "Authorization: Bearer mpx_live_…"
# → { "token": "rk_9f2c81d4e7", "url": "https://mobileproxy.app/rotate/rk_9f2c81d4e7" }

# Revoke one
curl -X DELETE https://mobileproxy.app/api/v1/rotation-links/ROTATION_TOKEN \
     -H "Authorization: Bearer mpx_live_…"
# → { "deleted": true, "token": "rk_9f2c81d4e7" }

Rotacja zaplanowana (czasowa) — ustaw interwał automatycznej rotacji w minutach (0 ją wyłącza; maks. 1440). Zapisuje się jako rotation_interval_min na urządzeniu i wysyła polecenie set_rotation_interval, które telefon stosuje przy kolejnym odpytaniu, więc sam ponawia połączenie w tym rytmie:

# Read the current settings
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation \
     -H "Authorization: Bearer mpx_live_…"
# → { "subscription_id": "sub_760c1fc8ddab", "interval_minutes": 0,
#     "airplane_seconds": 5, "stale_ip_alert_minutes": 0 }

# Rotate automatically every 15 minutes
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "interval_minutes": 15 }'
# → { "status": "set", "subscription_id": "sub_760c1fc8ddab",
#     "interval_minutes": 15, "airplane_seconds": 5,
#     "stale_ip_alert_minutes": 0, "command_id": "cmd_a41b" }

Czas trybu samolotowego — jak długo telefon utrzymuje włączony tryb samolotowy podczas każdej zmiany IP (airplane_seconds, 3–60, domyślnie 5). Niektórzy operatorzy zwalniają starą dzierżawę dopiero po dłuższym przytrzymaniu; zwiększ tę wartość, jeśli rotacje wciąż zwracają ten sam IP. Dotyczy tak samo rotacji zaplanowanych, z panelu i z API:

curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "airplane_seconds": 20 }'
# → { "status": "set", "subscription_id": "sub_760c1fc8ddab",
#     "interval_minutes": 15, "airplane_seconds": 20,
#     "stale_ip_alert_minutes": 0, "command_id": "cmd_b52c" }

Własny DNS — resolwery, których telefon używa do wyszukiwania domen przez proxy (do 3 literałów IP; telefon stosuje pierwszy i ponownie zestawia tunel). Pusta lista przywraca domyślny DNS operatora:

# Read
curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/dns \
     -H "Authorization: Bearer mpx_live_…"
# → { "subscription_id": "sub_760c1fc8ddab", "dns_servers": [] }

# Set (and later send [] to go back to carrier DNS)
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/dns \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "dns_servers": ["1.1.1.1", "8.8.8.8"] }'
# → { "status": "set", "subscription_id": "sub_760c1fc8ddab",
#     "dns_servers": ["1.1.1.1", "8.8.8.8"], "command_id": "cmd_c63d" }

Monitoring

Historia wyjściowych IP — ostatnie wyjściowe IP zgłoszone przez telefon, z usuniętymi duplikatami (nowy wiersz tylko wtedy, gdy IP faktycznie się zmienił). Niezawodny sposób na sprawdzenie, czy rotacja się powiodła:

curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/ip-history \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab", "ip_history": [
#     { "ip": "77.136.66.63", "carrier": "SFR", "ts": "…" }, … ] }

Opcjonalne parametry zapytania: from/to (ISO 8601) ograniczają okno, limit ogranicza liczbę wpisów (domyślnie 50, maks. 500), a group=day zwraca zamiast tego dzienną liczbę zmian — przekaż tz jako swoje przesunięcie względem UTC w minutach, aby dni były grupowane w Twojej strefie czasowej. To właśnie zasila kalendarz historii IP w panelu:

# Entries for one day
curl "https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/ip-history?from=2026-07-04T22:00:00Z&to=2026-07-05T22:00:00Z&limit=500" \
     -H "Authorization: Bearer mpx_live_…"

# Per-day counts for a month (tz = minutes east of UTC, e.g. 120 for CEST)
curl "https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/ip-history?group=day&tz=120&from=2026-06-30T22:00:00Z&to=2026-07-31T22:00:00Z" \
     -H "Authorization: Bearer mpx_live_…"
# → { "subscription_id": "sub_760c1fc8ddab", "days": [
#     { "day": "2026-07-03", "changes": 9 }, { "day": "2026-07-05", "changes": 2 } ] }

Alerty IP — serwer obserwuje Twoją flotę (~co 60 s) i otwiera alert, gdy coś wymaga uwagi: stale_ip, gdy urządzenie jest online, ale jego wyjściowy IP nie zmienił się dłużej niż próg subskrypcji (ustaw stale_ip_alert_minutes na /rotation; 0 = wyłączone, 2–10080), oraz duplicate_ip, gdy dwa Twoje urządzenia zgłaszają ten sam wyjściowy IP (NAT operatora może przydzielić dwóm SIM jeden adres — rotuj jeden, aby je rozdzielić). Alerty rozwiązują się automatycznie, gdy warunek ustanie; pokazują się też w dzwonku alertów w panelu:

# Turn on stale-IP alerts: warn after 60 min without an IP change
curl -X POST https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/rotation \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "stale_ip_alert_minutes": 60 }'

# Poll open alerts (feed this to your own monitoring)
curl https://mobileproxy.app/api/v1/alerts \
     -H "Authorization: Bearer mpx_live_…"
# → { "alerts": [
#     { "id": "42", "sub_id": "sub_760c1fc8ddab", "sub_name": "Galaxy S8",
#       "kind": "stale_ip",
#       "message": "IP unchanged for 75 min (alert threshold 60 min) — still 77.136.66.44",
#       "detail": { "ip": "77.136.66.44", "age_min": 75, "threshold_min": 60 },
#       "created_at": "…", "resolved_at": null, "seen_at": null },
#     { "id": "41", "sub_id": "sub_9d8e7f6a5b4c", "sub_name": "Galaxy A32",
#       "kind": "duplicate_ip",
#       "message": "Exit IP 77.136.67.33 is also used by “Galaxy S8” — rotate one device to separate them",
#       "detail": { "ip": "77.136.67.33",
#                   "shared_with": [ { "sub_id": "sub_760c1fc8ddab", "name": "Galaxy S8" } ] },
#       "created_at": "…", "resolved_at": null, "seen_at": null } ],
#     "unseen": 2 }

# Include resolved history; filter to one subscription
curl "https://mobileproxy.app/api/v1/alerts?status=all&subscription=SUBSCRIPTION_ID" \
     -H "Authorization: Bearer mpx_live_…"

# Reset the dashboard's unseen badge (never resolves anything)
curl -X POST https://mobileproxy.app/api/v1/alerts/seen \
     -H "Authorization: Bearer mpx_live_…"
# → { "status": "ok", "marked": 2 }

Ruch dla urządzenia — bajty liczone w bramie, rozbite na poszczególne proxy. Przydatne do rozliczania klientów, którym odsprzedajesz dostęp:

curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/traffic \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab",
#     "bytes_sent": 10485760, "bytes_recv": 262144000, "bytes_total": 272629760,
#     "per_proxy": [ { "proxy_id": "acc_5f734b9270e8",
#                      "bytes_sent": 10485760, "bytes_recv": 262144000 } ] }

Dzienny podział ruchu — dzienne bajty wysłane/odebrane, z próbek o rozdzielczości minutowej przechowywanych w warstwie webowej, dzięki czemu seria przetrwa wymiany urządzeń i wycofanie proxy. data_since oznacza najstarszą próbkę — dni przed nią nie mają danych, co nie jest tym samym co zerowy ruch. Przekaż tz (Twoje przesunięcie względem UTC w minutach), aby dni były grupowane w Twojej strefie czasowej; okna do 92 dni:

curl "https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/traffic/by-day?tz=120" \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab", "tz": 120, "data_since": "…",
#     "days": [ { "day": "2026-07-06", "bytes_sent": 10485760,
#                 "bytes_recv": 262144000, "bytes_total": 272629760 } ],
#     "total": { "bytes_sent": 10485760, "bytes_recv": 262144000,
#                "bytes_total": 272629760 } }

Dzienny czas działania — dzienne sekundy aktywności/braku aktywności zwinięte z rejestru sygnałów heartbeat urządzenia (ujednolicone mimo wymian urządzeń). Mierzy żywotność sygnałów heartbeat urządzenia (rytm ~25 s, próg przerwy ~90 s), a nie sprawność tunelu od końca do końca. current to stan w tej chwili; uptime_pct obejmuje obserwowaną część każdego dnia:

curl "https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/uptime?tz=120" \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab", "tz": 120, "current": "up",
#     "data_since": "…",
#     "days": [ { "day": "2026-07-06", "up_seconds": 31547,
#                 "down_seconds": 253, "uptime_pct": 99.2 } ] }

Zużycie w skali konta — zbiorcze zestawienie ze wszystkich urządzeń:

curl https://mobileproxy.app/api/v1/usage/summary \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscriptions": 3, "proxies": 5,
#     "bytes_sent": 31457280, "bytes_recv": 786432000, "bytes_total": 817889280 }

SMS / OTP

Odebrane SMS — wiadomości przychodzące na SIM tego telefonu, najnowsze na górze. Przydatne do odczytywania jednorazowych kodów weryfikacyjnych (OTP) na telefonach, które posiadasz. Zależy od opcjonalnego uprawnienia aplikacji do odbioru SMS; jeśli odmówiono go na urządzeniu, lista pozostaje pusta:

curl https://mobileproxy.app/api/v1/subscriptions/SUBSCRIPTION_ID/sms \
     -H "Authorization: Bearer mpx_live_…"

# → { "subscription_id": "sub_760c1fc8ddab", "messages": [
#     { "id": "1042", "sender": "+15550101",
#       "body": "Your verification code is 314159",
#       "received_at": "2026-07-05T14:12:00.000Z" }, … ] }

Serwery

Lokalizacje bram — lokalizacje, z których serwowane są Twoje proxy:

curl https://mobileproxy.app/api/v1/servers/locations \
     -H "Authorization: Bearer mpx_live_…"

# → { "locations": [ { "id": "eu-de-1", "host": "173.249.36.102",
#       "region": "EU · Germany (Frankfurt)", "country": "DE",
#       "protocols": ["socks5"], "pool": "mobile" } ] }

Tokeny API

Listuj, twórz i unieważniaj tokeny API. Sekret nowo utworzonego tokenu jest pokazywany raz — zapisz go od razu; nigdy nie da się go później odzyskać. Unieważnienie działa natychmiast:

# List (metadata only — never the secret)
curl https://mobileproxy.app/api/v1/tokens \
     -H "Authorization: Bearer mpx_live_…"
# → { "tokens": [ { "id": "tk_51ad", "name": "storefront",
#       "prefix": "mpx_live_9f2c", "created_at": "…", "last_used_at": "…" } ] }

# Create (secret shown once)
curl -X POST https://mobileproxy.app/api/v1/tokens \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "name": "storefront" }'
# → { "id": "tk_51ad", "name": "storefront",
#     "token": "mpx_live_9f2c81d4e7…", "prefix": "mpx_live_9f2c",
#     "scope_subscription_id": null, "readonly": false,
#     "note": "Store this token now — it will not be shown again." }

# Revoke
curl -X DELETE https://mobileproxy.app/api/v1/tokens/TOKEN_ID \
     -H "Authorization: Bearer mpx_live_…"
# → { "deleted": true, "id": "tk_51ad" }

Klucze ograniczone i tylko do odczytu

Deleguj dostęp bez udostępniania konta. Przekaż subscription_id, aby ograniczyć token do jednej subskrypcji, oraz readonly: true, aby ograniczyć go do żądań GET. Token ograniczony sięga tylko do endpointów własnych tej subskrypcji (plus /me); token tylko do odczytu jest odrzucany przy każdym zapisie. Oba to ograniczenia nałożone na Twoje konto — klucz ograniczony nigdy nie sięgnie do danych innego konta.

# A read-only key for ONE subscription — safe to hand a teammate or a monitor
curl -X POST https://mobileproxy.app/api/v1/tokens \
     -H "Authorization: Bearer mpx_live_…" \
     -H "Content-Type: application/json" \
     -d '{ "name": "customer-42",
           "subscription_id": "sub_760c1fc8ddab",
           "readonly": true }'
# → { …, "scope_subscription_id": "sub_760c1fc8ddab", "readonly": true }

# With that key: a GET on its own subscription works…
curl https://mobileproxy.app/api/v1/subscriptions/sub_760c1fc8ddab/traffic \
     -H "Authorization: Bearer mpx_live_scoped…"     # 200

# …but another subscription, the account-wide list, or any write is refused.
curl -X POST https://mobileproxy.app/api/v1/subscriptions/sub_760c1fc8ddab/change-ip \
     -H "Authorization: Bearer mpx_live_scoped…"     # 401 (read-only)
Wskazówka
Ta dokumentacja pozostaje w pełnej zgodzie z API. Aby klikać po niej w przeglądarce — z własnym tokenem i odpowiedziami na żywo — otwórz interaktywną konsolę lub przeczytaj surowy dokument OpenAPI.