aiosmsactivate.client

  1import asyncio
  2import json
  3import logging
  4import re
  5import time
  6from typing import Any, Literal
  7from cachetools import TTLCache, cached
  8
  9import aiohttp
 10
 11from .utils import is_json
 12from .exceptions import SmsActivateException, raise_smsactivate_error
 13from .models import ActivationData, Number, Service, SetActivationStatusResponse, Sms
 14from .types import SetActivationStatus, ActivationStatus
 15
 16cache = TTLCache(maxsize=100, ttl=3600)
 17
 18__all__ = [
 19    "SmsActivate",
 20]
 21
 22
 23allowed_domains = [
 24    'https://api.sms-activate.ae/stubs/handler_api.php',
 25    'https://api.sms-activate.ru/stubs/handler_api.php',
 26    'https://api.sms-activate.io/stubs/handler_api.php',
 27    'https://api.sms-activate.page/stubs/handler_api.php',
 28]
 29
 30class SmsActivate:
 31    """
 32    RU  
 33    Спасибо за использование моей библиотеки, вы можете принять участие в развитии библиотеки  
 34      
 35    ВАЖНО
 36    библиотека полностью поддерживает все методы с оффициальной документации
 37    https://sms-activate.page/api2 на момент 08.07.2025  
 38      
 39    на git: https://github.com/AioSmsProviders/aiosmsactivate
 40    Так же можете писать в чат https://t.me/+5YQ8k6H02bkxZmRi
 41    или обратиться к главному разработчику с идеями, предложениями и багами: https://t.me/lolkof  
 42    
 43    EN  
 44    Thank you for using my library, you can participate in the development of the library.  
 45      
 46    important
 47    The library fully supports all methods from the official documentation
 48    https://sms-activate.page/api2 as of 07/08/2025  
 49      
 50    on git: https://github.com/AioSmsProviders/aiosmsactivate
 51    You can also write to the chat https://t.me/+5YQ8k6H02bkxZmRi
 52    or contact the main developer with ideas, suggestions, and bugs: https://t.me/lolkof
 53    
 54    SIMPLE USAGE
 55    ```python
 56    from aiosmsactivate import SmsActivate
 57    from aiosmsactivate.types import SetActivationStatus
 58
 59    import asyncio
 60
 61
 62    sa = SmsActivate('token')
 63
 64    async def main():
 65        balance = await sa.get_balance()
 66        print(balance) # 6.25
 67        
 68        number = await sa.purchase('ya')
 69        number.activation_id # 3807035855
 70        number.phone_number # '79238944456'
 71        number.operator # 'mtt'
 72        print(number)
 73        # activation_id=3807035855 phone_number='79238944456' activation_cost=0.2 
 74        # country_code='0' can_get_another_sms=True activation_time='2025-07-08 10:49:27' 
 75        # operator='mtt' 
 76        
 77        code = await number.wait_sms_code(timeout=300)
 78        print(code) # 1234
 79        
 80        status = await number.get_activation_status()
 81        
 82        await number.set_activation_status(SetActivationStatus.CANCEL) # Отменить номер || Cancel number
 83        await number.set_activation_status(8) # Отменить номер || Cancel number
 84        
 85    asyncio.run(main())
 86    ```
 87    """
 88
 89    def __init__(self, api_key: str, base_url: str | list = allowed_domains):
 90        """
 91        RU  
 92        api_key передавать api ключ, получить можно вот тут: https://sms-activate.page/profile
 93        В base_url можно указать список адресов, модуль будет проходиться по всем, пока не найдёт рабочий
 94        а можно указать один или вообще не указывать, если не указать будет браться из allowed_domains  
 95        
 96        EN  
 97        api_key to transfer the api key, you can get it here: https://sms-activate.page/profile
 98        You can specify a list of addresses in base_url, and the module will go through all of them until it finds a working one.
 99        or you can specify one or not at all, if not specified, it will be taken from allowed_domains.
100        """
101        self._api_key = api_key
102        if isinstance(base_url, str):
103            base_url = [base_url]
104        self._base_urls = base_url
105        self._accept_url = None
106
107    async def __send_request(self, action: str, **kwargs):
108        last_exception = None
109
110        for url in self._base_urls:
111            try:
112                url = self._accept_url if self._accept_url else url
113                params = None
114                if 'params' in kwargs.keys():
115                    params = kwargs.pop('params')
116                async with aiohttp.ClientSession() as session:
117                    async with session.request(
118                        'POST',
119                        url,
120                        **kwargs,
121                        params={
122                            'api_key': self._api_key,
123                            'action': action,
124                            **(params if params else {})
125                        }
126                    ) as response:
127                        response.raise_for_status()
128                        resp_text = await response.text()
129                        raise_smsactivate_error(resp_text)
130                        logging.debug(response.real_url)
131                        return resp_text
132            except Exception as e:
133                last_exception = e
134                continue
135            self._accept_url = url
136            break
137
138        raise last_exception
139
140    async def get_balance(self, cashback: bool = False) -> float:
141        pattern = re.compile(r'ACCESS_BALANCE:(\d+\.\d{2})')
142        response = await self.__send_request('getBalance' if not cashback else 'getBalanceAndCashBack')
143        match = pattern.match(response)
144        if not match:
145            raise SmsActivateException('Invalid response sequence')
146
147        return float(match.group(1))
148    async def get_balance_and_cashback(self):
149        return await self.get_balance(cashback=True)
150
151    async def get_available_countries(self, service: str, freePrice: bool | str) -> dict[str, Any]:
152        response = await self.__send_request('getTopCountriesByService', params={
153            'service': service,
154            'freePrice': str(freePrice).lower()
155        })
156        
157        if not is_json(response):
158            return response
159        
160        return json.loads(response)
161    
162    async def get_count_numbers(self, country: str, operator: str) -> dict[str, Any]:
163        response = await self.__send_request('getNumbersStatus', params={
164            'country': country,
165            'operator': operator
166        })
167        
168        if not is_json(response):
169            return response
170        
171        return json.loads(response)
172    
173    async def get_operators(self, country: str = None) -> dict[str, Any]:
174        params = {}
175        if country is not None:
176            params["country"] = country
177        response = await self.__send_request('getOperators', params=params)
178        
179        if not is_json(response):
180            return response
181        
182        return json.loads(response)
183    
184    async def get_active_activations(self) -> dict[str, Any]:
185        response = await self.__send_request('getActiveActivations')
186        
187        if not is_json(response):
188            return response
189        
190        return json.loads(response)
191
192    async def get_activation_status_v1(self, id: str) -> tuple[ActivationStatus, str | None]:
193        response = await self.__send_request('getStatus', params={
194            'id': id
195        })
196
197        data = response.split(':')
198
199        match data[0]:
200            case 'STATUS_WAIT_CODE':
201                return ActivationStatus.WAIT, None
202            case 'STATUS_WAIT_RETRY':
203                return ActivationStatus.RETRY, data[1]
204            case 'STATUS_WAIT_RESEND':
205                return ActivationStatus.RESEND, None
206            case 'STATUS_CANCEL':
207                return ActivationStatus.CANCEL, None
208            case 'STATUS_OK':
209                return ActivationStatus.OK, data[1]
210            case _:
211                raise SmsActivateException('Invalid response sequence')
212    
213    async def get_activation_status(self, activation_id: str | int | Number) -> ActivationData | str:
214        if isinstance(activation_id, Number):
215            activation_id = activation_id.activation_id
216        response = await self.__send_request('getStatusV2', params={
217            'id': activation_id
218        })
219
220        if not is_json(response):
221            return response
222        
223        return ActivationData(**json.loads(response))
224    
225    async def wait_sms_code(self, activation_id: str | int | Number, timeout: int = 60*5, per_attempt: int = 5) -> Sms | str | int | None:
226        """
227        Ожидание смс кода
228        Wait sms code
229
230        Аргументы:
231            activation_id: activation_id номера или целый объект номера
232            timeout: максимальное время ожидание смс в секундах, по умолчанию 5 минут 
233            per_attempt: время между попыткой получить смс, по умолчанию 5 секунд
234            
235        Args:
236            activation_id: activation_id of number or Number object
237            timeout: maximum time to wait sms code 
238            per_attempt: time per attempt
239            
240        Returns: Sms
241        """
242        activation_id = activation_id.activation_id if isinstance(activation_id, Number) else activation_id
243        if not self._api_key:
244            raise ValueError('API key is required for this method')
245
246        try:
247            await self.set_activation_status(activation_id=activation_id, status=SetActivationStatus.READY)
248        except:
249            pass
250
251        start_time = time.time()
252        
253        while time.time() - start_time < timeout:
254            await asyncio.sleep(per_attempt)
255            status, code = await self.get_activation_status_v1(activation_id)
256            if status == ActivationStatus.OK:
257                try:
258                    await self.set_activation_status(activation_id, SetActivationStatus.AGAIN)
259                except:
260                    pass
261                return code
262        
263        return None
264
265    async def purchase(self, service: str, forward: bool | None = None, maxPrice: float | None = None,
266                       phoneException: str | None = None, operator: str | None = None,
267                       activationType: int | str | None = None, language: str | None = None,
268                       userId: str | int | None = None,
269                       ref: str | None = None, country: str | None = None,
270                       useCashBack: bool | None = None,
271                       orderId: str | int | None = None,
272                       _is_v2: bool = True
273                       ) -> Number | str:
274        response = await self.__send_request('getNumber' if not _is_v2 else 'getNumberV2', params={
275            'service': service,
276            **({'forward': 1 if forward else 0} if forward is not None else {}),
277            **({'maxPrice': str(maxPrice)} if maxPrice is not None else {}),
278            **({'phoneException': phoneException} if phoneException is not None else {}),
279            **({'operator': operator} if operator is not None else {}),
280            **({'activationType': str(activationType)} if activationType is not None else {}),
281            **({'language': str(language)} if language is not None else {}),
282            **({'userId': str(userId)} if userId is not None else {}),
283            **({'orderId': str(orderId)} if orderId is not None and _is_v2 else {}),
284            **({'ref': ref} if ref is not None else {}),
285            **({'country ': country} if country is not None else {}),
286            **({'useCashBack': str(useCashBack).lower()} if useCashBack is not None else {}),
287        })
288
289        if not is_json(response):
290            return response
291        
292        return Number.from_response(self, json.loads(response))
293    
294    async def get_number(self, *args, **kwargs):
295        kwargs["_is_v2"] = False
296        return await self.purchase(*args, **kwargs)
297    
298    async def get_multi_service_number(self, 
299                        multiService: str, multiForward: str | None = None,
300                        operator: str | None = None,
301                        ref: str | None = None, country: str | None = None,
302                       ) -> dict:
303        """
304        Get multiservice number.
305
306        :param multiService: service1,service2,service3 (Services separated by commas)
307        :param multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count)
308        :return: dict object of response
309        """
310        response = await self.__send_request('getMultiServiceNumber', params={
311            'multiService': multiService,
312            **({'multiForward': multiForward} if multiForward is not None else {}),
313            **({'operator': operator} if operator is not None else {}),
314            **({'ref': ref} if ref is not None else {}),
315            **({'country ': country} if country is not None else {}),
316        })
317
318        if not is_json(response):
319            return response
320        
321        return json.loads(response)
322    
323
324    async def set_activation_status(self, activation_id: str | int, status: SetActivationStatus | int,
325                                    forward: str | None = None) -> SetActivationStatusResponse:
326        members = {member.value: member for member in SetActivationStatusResponse}
327        response = await self.__send_request('setStatus', params={
328            'id': activation_id,
329            'status': status.value if isinstance(status, SetActivationStatus) else status,
330            **({'forward': forward} if forward is not None else {})
331        })
332
333        return members[response]
334
335    async def get_history(self, 
336                          start: str | int = None,
337                          end: str | int = None,
338                          offset: str | int = None,
339                          limit: str | int = None,
340                       ) -> dict | list:
341        response = await self.__send_request('getHistory', params={
342            **({'start': str(start)} if start is not None else {}),
343            **({'end': str(end)} if end is not None else {}),
344            **({'offset': str(offset)} if offset is not None else {}),
345            **({'limit': str(limit)} if limit is not None else {}),
346        })
347
348        if not is_json(response):
349            return response
350        
351        return json.loads(response)
352    
353    async def get_list_top_countries(self, 
354                          service: str,
355                       ) -> dict | list:
356        response = await self.__send_request('getListOfTopCountriesByService', params={
357            'service': service
358        })
359
360        if not is_json(response):
361            return response
362        
363        return json.loads(response)
364    
365    async def get_incoming_call_status(self, 
366                          id: str | int = None,
367                       ) -> dict | list:
368        response = await self.__send_request('getIncomingCallStatus', params={
369            'activationId': id
370        })
371
372        if not is_json(response):
373            return response
374        
375        return json.loads(response)
376    
377    async def get_service(self, service_code: str, country: str | int, lang: Literal['ru', 'en', 'es', 'cn'] = 'en'):
378        """
379        RU  
380        Получить все данные о сервисе  
381        EN  
382        Get all data about service  
383        
384        Example
385        ```python
386        service = await sa.get_service('ya', 0)
387        print(service) # code='ya' name='Yandex/Uber' country='0' cost=0.115 count=10794 physical_count=5075
388        ```
389        """
390        
391        country = str(country)
392        name = await self.get_service_name(service_code, lang)
393        data = await self.get_prices(service_code, country)
394        
395        cost = data[country][service_code]['cost']
396        count = data[country][service_code]['count']
397        physical_count = data[country][service_code]['physicalCount']
398        return Service(
399            code=service_code,
400            country=country,
401            name=name,
402            cost=cost,
403            count=count,
404            physical_count=physical_count,
405        )
406    
407    async def get_prices(self, 
408                          service: str = None,
409                          country: str | int = None,
410                       ) -> dict | list:
411        response = await self.__send_request('getPrices', params={
412            **({'service': str(service)} if service is not None else {}),
413            **({'country': str(country)} if country is not None else {}),
414        })
415
416        if not is_json(response):
417            return response
418        
419        return json.loads(response)
420    
421    async def _get_service_cost(self, service: str, country: str | int):
422        data = await self.get_prices(service, country)
423        return data[country][service]['cost']
424    
425    async def _get_service_quantity(self, service: str, country: str | int):
426        data = await self.get_prices(service, country)
427        return data[country][service]['count']
428    
429    async def get_prices_verification(self, 
430                          service: str = None,
431                       ) -> dict | list:
432        response = await self.__send_request('getPricesVerification', params={
433            **({'service': str(service)} if service is not None else {}),
434        })
435
436        if not is_json(response):
437            return response
438        
439        return json.loads(response)
440    
441    async def get_countries(self,
442                       ) -> dict | list:
443        response = await self.__send_request('getCountries', params={
444        })
445
446        if not is_json(response):
447            return response
448        
449        return json.loads(response)
450    
451    @cached(cache)
452    async def get_service_list(self, 
453                          country: str = None,
454                          lang: Literal['ru', 'en', 'es', 'cn'] = None,
455                       ) -> dict | list:
456        response = await self.__send_request('getServicesList', params={
457            **({'country': str(country)} if country is not None else {}),
458            **({'lang': str(lang)} if lang is not None else {}),
459        })
460
461        if not is_json(response):
462            return response
463        
464        return json.loads(response)
465    
466    async def get_service_name(self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None):
467        """
468        RU  
469        Получение полного имени сервиса по его id  
470          
471        EN  
472        Get full service name by service code  
473            
474        Пример Example:  
475        service_name = await SmsActivate.get_service_name('go')  
476        service_name # 'Google,youtube,Gmail'
477        """
478        services = await self.get_service_list(lang=lang)
479        services = services.get('services')
480        for service in services:
481            if service['code'] == service_code:
482                return service['name']
483        return None
484    
485    async def get_additional_service(self, 
486                          service: str = None,
487                          id: str = None,
488                       ):
489        """
490        Get additional service to activation its cost 5rub
491        return 2 values: addition activation id and phone number
492        
493        use like this: 
494        activation_id, phone_number = await getAdditionalService(service, activation id)
495        """
496        response = await self.__send_request('getAdditionalService', params={
497            'service': service,
498            'id':id
499        })
500
501        data = response.split(':')
502        if len(data) > 2:
503            return data[1], data[2]
504        
505        return data
506    
507    async def get_extra_activation(self, 
508                          id: str = None,
509                       ):
510        """
511        return 2 values: addition activation id and phone number
512        
513        use like this: 
514        activation_id, phone_number = await getExtraActivation(activation id)
515        """
516        response = await self.__send_request('getExtraActivation', params={
517            'id':id
518        })
519
520        data = response.split(':')
521        if len(data) > 2:
522            return data[1], data[2]
523        
524        return data
525    
526    async def check_extra_activation(self, 
527                          activationId: str | int
528                       ) -> dict | list:
529        response = await self.__send_request('checkExtraActivation', params={
530            'activationId': str(activationId)
531        })
532
533        if not is_json(response):
534            return response
535        
536        return json.loads(response)
537    
538    async def parse_call(self, 
539                          id: str | int,
540                          newLang: str,
541                       ) -> dict | list:
542        response = await self.__send_request('parseCall', params={
543            "id": id,
544            "newLang": newLang,
545        })
546
547        if not is_json(response):
548            return response
549        
550        return json.loads(response)
551    
552    # !!! BOTTOM IT IS RENT API
553    async def get_rent_services_and_countries(self,
554                       time: int | str | None = None,
555                       operator: str | None = None,
556                       country: str | None = None,
557                       currency: str | None = None,
558                       incomingCall: bool | None = None,
559                       ) -> dict | str:
560        response = await self.__send_request('getRentServicesAndCountries', params={
561            **({'time ': str(time )} if time is not None else {}),
562            **({'operator ': str(operator )} if operator is not None else {}),
563            **({'country ': str(country )} if country is not None else {}),
564            **({'currency ': str(currency )} if currency is not None else {}),
565            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
566        })
567
568        if not is_json(response):
569            return response
570        
571        return json.loads(response)
572    
573    async def get_rent_number(self,
574                        service: str,
575                        time: int | str | None = None,
576                        operator: str | None = None,
577                        country: str | None = None,
578                        url: str | None = None,
579                        incomingCall: bool | None = None,
580                       ) -> dict | str:
581        response = await self.__send_request('getRentNumber', params={
582            'service': service,
583            **({'time ': str(time )} if time is not None else {}),
584            **({'operator ': str(operator )} if operator is not None else {}),
585            **({'country ': str(country )} if country is not None else {}),
586            **({'url ': str(url )} if url is not None else {}),
587            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
588        })
589
590        if not is_json(response):
591            return response
592        
593        return json.loads(response)
594    
595    async def get_rent_status(self,
596                        id: str,
597                        page: int | str | None = None,
598                        size: int | str | None = None,
599                       ) -> dict | str:
600        response = await self.__send_request('getRentStatus', params={
601            'id': id,
602            **({'page ': str(page)} if page is not None else {}),
603            **({'size ': str(size )} if size is not None else {}),
604        })
605
606        if not is_json(response):
607            return response
608        
609        return json.loads(response)
610    
611    async def set_rent_status(self,
612                        id: str,
613                        status: Literal[1, 2, '1', '2'],
614                       ) -> dict | str:
615        response = await self.__send_request('getRentStatus', params={
616            'id': str(id),
617            'status': str(status),
618        })
619
620        if not is_json(response):
621            return response
622        
623        return json.loads(response)
624    
625    async def get_rent_list(self,
626                       ) -> dict | str:
627        response = await self.__send_request('getRentList', params={
628        })
629
630        if not is_json(response):
631            return response
632        
633        return json.loads(response)
634    
635    async def continue_rent_number(self,
636                        id: str,
637                        rent_time: int | str | None = 4,
638                       ) -> dict | str:
639        response = await self.__send_request('continueRentNumber', params={
640            'id': id,
641            'rent_time': str(rent_time)
642        })
643
644        if not is_json(response):
645            return response
646        
647        return json.loads(response)
648    
649    async def get_continue_rent_price_number(self,
650                        id: str,
651                        rent_time: int | str | None = 4,
652                        currency: str | None = None
653                       ) -> dict | str:
654        response = await self.__send_request('getContinueRentPriceNumber', params={
655            'id': id,
656            'rent_time': str(rent_time),
657            **({'currency ': str(currency )} if currency is not None else {}),
658        })
659
660        if not is_json(response):
661            return response
662        
663        return json.loads(response)
664    
665    # !!! BOTTOM IS IT PARTNER SOFT API
666    async def buy_partner_product(self,
667                        id: str,
668                       ) -> dict | str:
669        response = await self.__send_request('buyPartnerProduct', params={
670            'id': id,
671        })
672
673        if not is_json(response):
674            return response
675        
676        return json.loads(response)
677    
678
679# === Method Aliases (outside class for pdoc) ===
680SmsActivate.getBalance = SmsActivate.get_balance
681SmsActivate.getBalanceAndCashBack = SmsActivate.get_balance_and_cashback
682SmsActivate.getTopCountriesByService = SmsActivate.get_available_countries
683SmsActivate.getNumbersStatus = SmsActivate.get_count_numbers
684SmsActivate.getOperators = SmsActivate.get_operators
685SmsActivate.getActiveActivations = SmsActivate.get_active_activations
686SmsActivate.getStatus = SmsActivate.get_activation_status_v1
687SmsActivate.getStatusV2 = SmsActivate.get_activation_status
688SmsActivate.getNumberV2 = SmsActivate.purchase
689SmsActivate.purchase_v1 = SmsActivate.get_number
690SmsActivate.getNumber = SmsActivate.get_number
691SmsActivate.getMultiServiceNumber = SmsActivate.get_multi_service_number
692SmsActivate.setStatus = SmsActivate.set_activation_status
693SmsActivate.getHistory = SmsActivate.get_history
694SmsActivate.getListOfTopCountriesByService = SmsActivate.get_list_top_countries
695SmsActivate.getIncomingCallStatus = SmsActivate.get_incoming_call_status
696SmsActivate.getPrices = SmsActivate.get_prices
697SmsActivate.getPricesVerification = SmsActivate.get_prices_verification
698SmsActivate.getCountries = SmsActivate.get_countries
699SmsActivate.getServicesList = SmsActivate.get_service_list
700SmsActivate.getAdditionalService = SmsActivate.get_additional_service
701SmsActivate.getExtraActivation = SmsActivate.get_extra_activation
702SmsActivate.checkExtraActivation = SmsActivate.check_extra_activation
703SmsActivate.parseCall = SmsActivate.parse_call
704SmsActivate.getRentServicesAndCountries = SmsActivate.get_rent_services_and_countries
705SmsActivate.getRentNumber = SmsActivate.get_rent_number
706SmsActivate.getRentStatus = SmsActivate.get_rent_status
707SmsActivate.getRentStatus = SmsActivate.get_rent_status
708SmsActivate.getRentList = SmsActivate.get_rent_list
709SmsActivate.continueRentNumber = SmsActivate.continue_rent_number
710SmsActivate.getContinueRentPriceNumber = SmsActivate.get_continue_rent_price_number
711SmsActivate.buyPartnerProduct = SmsActivate.buy_partner_product
class SmsActivate:
 31class SmsActivate:
 32    """
 33    RU  
 34    Спасибо за использование моей библиотеки, вы можете принять участие в развитии библиотеки  
 35      
 36    ВАЖНО
 37    библиотека полностью поддерживает все методы с оффициальной документации
 38    https://sms-activate.page/api2 на момент 08.07.2025  
 39      
 40    на git: https://github.com/AioSmsProviders/aiosmsactivate
 41    Так же можете писать в чат https://t.me/+5YQ8k6H02bkxZmRi
 42    или обратиться к главному разработчику с идеями, предложениями и багами: https://t.me/lolkof  
 43    
 44    EN  
 45    Thank you for using my library, you can participate in the development of the library.  
 46      
 47    important
 48    The library fully supports all methods from the official documentation
 49    https://sms-activate.page/api2 as of 07/08/2025  
 50      
 51    on git: https://github.com/AioSmsProviders/aiosmsactivate
 52    You can also write to the chat https://t.me/+5YQ8k6H02bkxZmRi
 53    or contact the main developer with ideas, suggestions, and bugs: https://t.me/lolkof
 54    
 55    SIMPLE USAGE
 56    ```python
 57    from aiosmsactivate import SmsActivate
 58    from aiosmsactivate.types import SetActivationStatus
 59
 60    import asyncio
 61
 62
 63    sa = SmsActivate('token')
 64
 65    async def main():
 66        balance = await sa.get_balance()
 67        print(balance) # 6.25
 68        
 69        number = await sa.purchase('ya')
 70        number.activation_id # 3807035855
 71        number.phone_number # '79238944456'
 72        number.operator # 'mtt'
 73        print(number)
 74        # activation_id=3807035855 phone_number='79238944456' activation_cost=0.2 
 75        # country_code='0' can_get_another_sms=True activation_time='2025-07-08 10:49:27' 
 76        # operator='mtt' 
 77        
 78        code = await number.wait_sms_code(timeout=300)
 79        print(code) # 1234
 80        
 81        status = await number.get_activation_status()
 82        
 83        await number.set_activation_status(SetActivationStatus.CANCEL) # Отменить номер || Cancel number
 84        await number.set_activation_status(8) # Отменить номер || Cancel number
 85        
 86    asyncio.run(main())
 87    ```
 88    """
 89
 90    def __init__(self, api_key: str, base_url: str | list = allowed_domains):
 91        """
 92        RU  
 93        api_key передавать api ключ, получить можно вот тут: https://sms-activate.page/profile
 94        В base_url можно указать список адресов, модуль будет проходиться по всем, пока не найдёт рабочий
 95        а можно указать один или вообще не указывать, если не указать будет браться из allowed_domains  
 96        
 97        EN  
 98        api_key to transfer the api key, you can get it here: https://sms-activate.page/profile
 99        You can specify a list of addresses in base_url, and the module will go through all of them until it finds a working one.
100        or you can specify one or not at all, if not specified, it will be taken from allowed_domains.
101        """
102        self._api_key = api_key
103        if isinstance(base_url, str):
104            base_url = [base_url]
105        self._base_urls = base_url
106        self._accept_url = None
107
108    async def __send_request(self, action: str, **kwargs):
109        last_exception = None
110
111        for url in self._base_urls:
112            try:
113                url = self._accept_url if self._accept_url else url
114                params = None
115                if 'params' in kwargs.keys():
116                    params = kwargs.pop('params')
117                async with aiohttp.ClientSession() as session:
118                    async with session.request(
119                        'POST',
120                        url,
121                        **kwargs,
122                        params={
123                            'api_key': self._api_key,
124                            'action': action,
125                            **(params if params else {})
126                        }
127                    ) as response:
128                        response.raise_for_status()
129                        resp_text = await response.text()
130                        raise_smsactivate_error(resp_text)
131                        logging.debug(response.real_url)
132                        return resp_text
133            except Exception as e:
134                last_exception = e
135                continue
136            self._accept_url = url
137            break
138
139        raise last_exception
140
141    async def get_balance(self, cashback: bool = False) -> float:
142        pattern = re.compile(r'ACCESS_BALANCE:(\d+\.\d{2})')
143        response = await self.__send_request('getBalance' if not cashback else 'getBalanceAndCashBack')
144        match = pattern.match(response)
145        if not match:
146            raise SmsActivateException('Invalid response sequence')
147
148        return float(match.group(1))
149    async def get_balance_and_cashback(self):
150        return await self.get_balance(cashback=True)
151
152    async def get_available_countries(self, service: str, freePrice: bool | str) -> dict[str, Any]:
153        response = await self.__send_request('getTopCountriesByService', params={
154            'service': service,
155            'freePrice': str(freePrice).lower()
156        })
157        
158        if not is_json(response):
159            return response
160        
161        return json.loads(response)
162    
163    async def get_count_numbers(self, country: str, operator: str) -> dict[str, Any]:
164        response = await self.__send_request('getNumbersStatus', params={
165            'country': country,
166            'operator': operator
167        })
168        
169        if not is_json(response):
170            return response
171        
172        return json.loads(response)
173    
174    async def get_operators(self, country: str = None) -> dict[str, Any]:
175        params = {}
176        if country is not None:
177            params["country"] = country
178        response = await self.__send_request('getOperators', params=params)
179        
180        if not is_json(response):
181            return response
182        
183        return json.loads(response)
184    
185    async def get_active_activations(self) -> dict[str, Any]:
186        response = await self.__send_request('getActiveActivations')
187        
188        if not is_json(response):
189            return response
190        
191        return json.loads(response)
192
193    async def get_activation_status_v1(self, id: str) -> tuple[ActivationStatus, str | None]:
194        response = await self.__send_request('getStatus', params={
195            'id': id
196        })
197
198        data = response.split(':')
199
200        match data[0]:
201            case 'STATUS_WAIT_CODE':
202                return ActivationStatus.WAIT, None
203            case 'STATUS_WAIT_RETRY':
204                return ActivationStatus.RETRY, data[1]
205            case 'STATUS_WAIT_RESEND':
206                return ActivationStatus.RESEND, None
207            case 'STATUS_CANCEL':
208                return ActivationStatus.CANCEL, None
209            case 'STATUS_OK':
210                return ActivationStatus.OK, data[1]
211            case _:
212                raise SmsActivateException('Invalid response sequence')
213    
214    async def get_activation_status(self, activation_id: str | int | Number) -> ActivationData | str:
215        if isinstance(activation_id, Number):
216            activation_id = activation_id.activation_id
217        response = await self.__send_request('getStatusV2', params={
218            'id': activation_id
219        })
220
221        if not is_json(response):
222            return response
223        
224        return ActivationData(**json.loads(response))
225    
226    async def wait_sms_code(self, activation_id: str | int | Number, timeout: int = 60*5, per_attempt: int = 5) -> Sms | str | int | None:
227        """
228        Ожидание смс кода
229        Wait sms code
230
231        Аргументы:
232            activation_id: activation_id номера или целый объект номера
233            timeout: максимальное время ожидание смс в секундах, по умолчанию 5 минут 
234            per_attempt: время между попыткой получить смс, по умолчанию 5 секунд
235            
236        Args:
237            activation_id: activation_id of number or Number object
238            timeout: maximum time to wait sms code 
239            per_attempt: time per attempt
240            
241        Returns: Sms
242        """
243        activation_id = activation_id.activation_id if isinstance(activation_id, Number) else activation_id
244        if not self._api_key:
245            raise ValueError('API key is required for this method')
246
247        try:
248            await self.set_activation_status(activation_id=activation_id, status=SetActivationStatus.READY)
249        except:
250            pass
251
252        start_time = time.time()
253        
254        while time.time() - start_time < timeout:
255            await asyncio.sleep(per_attempt)
256            status, code = await self.get_activation_status_v1(activation_id)
257            if status == ActivationStatus.OK:
258                try:
259                    await self.set_activation_status(activation_id, SetActivationStatus.AGAIN)
260                except:
261                    pass
262                return code
263        
264        return None
265
266    async def purchase(self, service: str, forward: bool | None = None, maxPrice: float | None = None,
267                       phoneException: str | None = None, operator: str | None = None,
268                       activationType: int | str | None = None, language: str | None = None,
269                       userId: str | int | None = None,
270                       ref: str | None = None, country: str | None = None,
271                       useCashBack: bool | None = None,
272                       orderId: str | int | None = None,
273                       _is_v2: bool = True
274                       ) -> Number | str:
275        response = await self.__send_request('getNumber' if not _is_v2 else 'getNumberV2', params={
276            'service': service,
277            **({'forward': 1 if forward else 0} if forward is not None else {}),
278            **({'maxPrice': str(maxPrice)} if maxPrice is not None else {}),
279            **({'phoneException': phoneException} if phoneException is not None else {}),
280            **({'operator': operator} if operator is not None else {}),
281            **({'activationType': str(activationType)} if activationType is not None else {}),
282            **({'language': str(language)} if language is not None else {}),
283            **({'userId': str(userId)} if userId is not None else {}),
284            **({'orderId': str(orderId)} if orderId is not None and _is_v2 else {}),
285            **({'ref': ref} if ref is not None else {}),
286            **({'country ': country} if country is not None else {}),
287            **({'useCashBack': str(useCashBack).lower()} if useCashBack is not None else {}),
288        })
289
290        if not is_json(response):
291            return response
292        
293        return Number.from_response(self, json.loads(response))
294    
295    async def get_number(self, *args, **kwargs):
296        kwargs["_is_v2"] = False
297        return await self.purchase(*args, **kwargs)
298    
299    async def get_multi_service_number(self, 
300                        multiService: str, multiForward: str | None = None,
301                        operator: str | None = None,
302                        ref: str | None = None, country: str | None = None,
303                       ) -> dict:
304        """
305        Get multiservice number.
306
307        :param multiService: service1,service2,service3 (Services separated by commas)
308        :param multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count)
309        :return: dict object of response
310        """
311        response = await self.__send_request('getMultiServiceNumber', params={
312            'multiService': multiService,
313            **({'multiForward': multiForward} if multiForward is not None else {}),
314            **({'operator': operator} if operator is not None else {}),
315            **({'ref': ref} if ref is not None else {}),
316            **({'country ': country} if country is not None else {}),
317        })
318
319        if not is_json(response):
320            return response
321        
322        return json.loads(response)
323    
324
325    async def set_activation_status(self, activation_id: str | int, status: SetActivationStatus | int,
326                                    forward: str | None = None) -> SetActivationStatusResponse:
327        members = {member.value: member for member in SetActivationStatusResponse}
328        response = await self.__send_request('setStatus', params={
329            'id': activation_id,
330            'status': status.value if isinstance(status, SetActivationStatus) else status,
331            **({'forward': forward} if forward is not None else {})
332        })
333
334        return members[response]
335
336    async def get_history(self, 
337                          start: str | int = None,
338                          end: str | int = None,
339                          offset: str | int = None,
340                          limit: str | int = None,
341                       ) -> dict | list:
342        response = await self.__send_request('getHistory', params={
343            **({'start': str(start)} if start is not None else {}),
344            **({'end': str(end)} if end is not None else {}),
345            **({'offset': str(offset)} if offset is not None else {}),
346            **({'limit': str(limit)} if limit is not None else {}),
347        })
348
349        if not is_json(response):
350            return response
351        
352        return json.loads(response)
353    
354    async def get_list_top_countries(self, 
355                          service: str,
356                       ) -> dict | list:
357        response = await self.__send_request('getListOfTopCountriesByService', params={
358            'service': service
359        })
360
361        if not is_json(response):
362            return response
363        
364        return json.loads(response)
365    
366    async def get_incoming_call_status(self, 
367                          id: str | int = None,
368                       ) -> dict | list:
369        response = await self.__send_request('getIncomingCallStatus', params={
370            'activationId': id
371        })
372
373        if not is_json(response):
374            return response
375        
376        return json.loads(response)
377    
378    async def get_service(self, service_code: str, country: str | int, lang: Literal['ru', 'en', 'es', 'cn'] = 'en'):
379        """
380        RU  
381        Получить все данные о сервисе  
382        EN  
383        Get all data about service  
384        
385        Example
386        ```python
387        service = await sa.get_service('ya', 0)
388        print(service) # code='ya' name='Yandex/Uber' country='0' cost=0.115 count=10794 physical_count=5075
389        ```
390        """
391        
392        country = str(country)
393        name = await self.get_service_name(service_code, lang)
394        data = await self.get_prices(service_code, country)
395        
396        cost = data[country][service_code]['cost']
397        count = data[country][service_code]['count']
398        physical_count = data[country][service_code]['physicalCount']
399        return Service(
400            code=service_code,
401            country=country,
402            name=name,
403            cost=cost,
404            count=count,
405            physical_count=physical_count,
406        )
407    
408    async def get_prices(self, 
409                          service: str = None,
410                          country: str | int = None,
411                       ) -> dict | list:
412        response = await self.__send_request('getPrices', params={
413            **({'service': str(service)} if service is not None else {}),
414            **({'country': str(country)} if country is not None else {}),
415        })
416
417        if not is_json(response):
418            return response
419        
420        return json.loads(response)
421    
422    async def _get_service_cost(self, service: str, country: str | int):
423        data = await self.get_prices(service, country)
424        return data[country][service]['cost']
425    
426    async def _get_service_quantity(self, service: str, country: str | int):
427        data = await self.get_prices(service, country)
428        return data[country][service]['count']
429    
430    async def get_prices_verification(self, 
431                          service: str = None,
432                       ) -> dict | list:
433        response = await self.__send_request('getPricesVerification', params={
434            **({'service': str(service)} if service is not None else {}),
435        })
436
437        if not is_json(response):
438            return response
439        
440        return json.loads(response)
441    
442    async def get_countries(self,
443                       ) -> dict | list:
444        response = await self.__send_request('getCountries', params={
445        })
446
447        if not is_json(response):
448            return response
449        
450        return json.loads(response)
451    
452    @cached(cache)
453    async def get_service_list(self, 
454                          country: str = None,
455                          lang: Literal['ru', 'en', 'es', 'cn'] = None,
456                       ) -> dict | list:
457        response = await self.__send_request('getServicesList', params={
458            **({'country': str(country)} if country is not None else {}),
459            **({'lang': str(lang)} if lang is not None else {}),
460        })
461
462        if not is_json(response):
463            return response
464        
465        return json.loads(response)
466    
467    async def get_service_name(self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None):
468        """
469        RU  
470        Получение полного имени сервиса по его id  
471          
472        EN  
473        Get full service name by service code  
474            
475        Пример Example:  
476        service_name = await SmsActivate.get_service_name('go')  
477        service_name # 'Google,youtube,Gmail'
478        """
479        services = await self.get_service_list(lang=lang)
480        services = services.get('services')
481        for service in services:
482            if service['code'] == service_code:
483                return service['name']
484        return None
485    
486    async def get_additional_service(self, 
487                          service: str = None,
488                          id: str = None,
489                       ):
490        """
491        Get additional service to activation its cost 5rub
492        return 2 values: addition activation id and phone number
493        
494        use like this: 
495        activation_id, phone_number = await getAdditionalService(service, activation id)
496        """
497        response = await self.__send_request('getAdditionalService', params={
498            'service': service,
499            'id':id
500        })
501
502        data = response.split(':')
503        if len(data) > 2:
504            return data[1], data[2]
505        
506        return data
507    
508    async def get_extra_activation(self, 
509                          id: str = None,
510                       ):
511        """
512        return 2 values: addition activation id and phone number
513        
514        use like this: 
515        activation_id, phone_number = await getExtraActivation(activation id)
516        """
517        response = await self.__send_request('getExtraActivation', params={
518            'id':id
519        })
520
521        data = response.split(':')
522        if len(data) > 2:
523            return data[1], data[2]
524        
525        return data
526    
527    async def check_extra_activation(self, 
528                          activationId: str | int
529                       ) -> dict | list:
530        response = await self.__send_request('checkExtraActivation', params={
531            'activationId': str(activationId)
532        })
533
534        if not is_json(response):
535            return response
536        
537        return json.loads(response)
538    
539    async def parse_call(self, 
540                          id: str | int,
541                          newLang: str,
542                       ) -> dict | list:
543        response = await self.__send_request('parseCall', params={
544            "id": id,
545            "newLang": newLang,
546        })
547
548        if not is_json(response):
549            return response
550        
551        return json.loads(response)
552    
553    # !!! BOTTOM IT IS RENT API
554    async def get_rent_services_and_countries(self,
555                       time: int | str | None = None,
556                       operator: str | None = None,
557                       country: str | None = None,
558                       currency: str | None = None,
559                       incomingCall: bool | None = None,
560                       ) -> dict | str:
561        response = await self.__send_request('getRentServicesAndCountries', params={
562            **({'time ': str(time )} if time is not None else {}),
563            **({'operator ': str(operator )} if operator is not None else {}),
564            **({'country ': str(country )} if country is not None else {}),
565            **({'currency ': str(currency )} if currency is not None else {}),
566            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
567        })
568
569        if not is_json(response):
570            return response
571        
572        return json.loads(response)
573    
574    async def get_rent_number(self,
575                        service: str,
576                        time: int | str | None = None,
577                        operator: str | None = None,
578                        country: str | None = None,
579                        url: str | None = None,
580                        incomingCall: bool | None = None,
581                       ) -> dict | str:
582        response = await self.__send_request('getRentNumber', params={
583            'service': service,
584            **({'time ': str(time )} if time is not None else {}),
585            **({'operator ': str(operator )} if operator is not None else {}),
586            **({'country ': str(country )} if country is not None else {}),
587            **({'url ': str(url )} if url is not None else {}),
588            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
589        })
590
591        if not is_json(response):
592            return response
593        
594        return json.loads(response)
595    
596    async def get_rent_status(self,
597                        id: str,
598                        page: int | str | None = None,
599                        size: int | str | None = None,
600                       ) -> dict | str:
601        response = await self.__send_request('getRentStatus', params={
602            'id': id,
603            **({'page ': str(page)} if page is not None else {}),
604            **({'size ': str(size )} if size is not None else {}),
605        })
606
607        if not is_json(response):
608            return response
609        
610        return json.loads(response)
611    
612    async def set_rent_status(self,
613                        id: str,
614                        status: Literal[1, 2, '1', '2'],
615                       ) -> dict | str:
616        response = await self.__send_request('getRentStatus', params={
617            'id': str(id),
618            'status': str(status),
619        })
620
621        if not is_json(response):
622            return response
623        
624        return json.loads(response)
625    
626    async def get_rent_list(self,
627                       ) -> dict | str:
628        response = await self.__send_request('getRentList', params={
629        })
630
631        if not is_json(response):
632            return response
633        
634        return json.loads(response)
635    
636    async def continue_rent_number(self,
637                        id: str,
638                        rent_time: int | str | None = 4,
639                       ) -> dict | str:
640        response = await self.__send_request('continueRentNumber', params={
641            'id': id,
642            'rent_time': str(rent_time)
643        })
644
645        if not is_json(response):
646            return response
647        
648        return json.loads(response)
649    
650    async def get_continue_rent_price_number(self,
651                        id: str,
652                        rent_time: int | str | None = 4,
653                        currency: str | None = None
654                       ) -> dict | str:
655        response = await self.__send_request('getContinueRentPriceNumber', params={
656            'id': id,
657            'rent_time': str(rent_time),
658            **({'currency ': str(currency )} if currency is not None else {}),
659        })
660
661        if not is_json(response):
662            return response
663        
664        return json.loads(response)
665    
666    # !!! BOTTOM IS IT PARTNER SOFT API
667    async def buy_partner_product(self,
668                        id: str,
669                       ) -> dict | str:
670        response = await self.__send_request('buyPartnerProduct', params={
671            'id': id,
672        })
673
674        if not is_json(response):
675            return response
676        
677        return json.loads(response)

RU
Спасибо за использование моей библиотеки, вы можете принять участие в развитии библиотеки

ВАЖНО библиотека полностью поддерживает все методы с оффициальной документации https://sms-activate.page/api2 на момент 08.07.2025

на git: https://github.com/AioSmsProviders/aiosmsactivate Так же можете писать в чат https://t.me/+5YQ8k6H02bkxZmRi или обратиться к главному разработчику с идеями, предложениями и багами: https://t.me/lolkof

EN
Thank you for using my library, you can participate in the development of the library.

important The library fully supports all methods from the official documentation https://sms-activate.page/api2 as of 07/08/2025

on git: https://github.com/AioSmsProviders/aiosmsactivate You can also write to the chat https://t.me/+5YQ8k6H02bkxZmRi or contact the main developer with ideas, suggestions, and bugs: https://t.me/lolkof

SIMPLE USAGE

from aiosmsactivate import SmsActivate
from aiosmsactivate.types import SetActivationStatus

import asyncio


sa = SmsActivate('token')

async def main():
    balance = await sa.get_balance()
    print(balance) # 6.25

    number = await sa.purchase('ya')
    number.activation_id # 3807035855
    number.phone_number # '79238944456'
    number.operator # 'mtt'
    print(number)
    # activation_id=3807035855 phone_number='79238944456' activation_cost=0.2 
    # country_code='0' can_get_another_sms=True activation_time='2025-07-08 10:49:27' 
    # operator='mtt' 

    code = await number.wait_sms_code(timeout=300)
    print(code) # 1234

    status = await number.get_activation_status()

    await number.set_activation_status(SetActivationStatus.CANCEL) # Отменить номер || Cancel number
    await number.set_activation_status(8) # Отменить номер || Cancel number

asyncio.run(main())
SmsActivate( api_key: str, base_url: str | list = ['https://api.sms-activate.ae/stubs/handler_api.php', 'https://api.sms-activate.ru/stubs/handler_api.php', 'https://api.sms-activate.io/stubs/handler_api.php', 'https://api.sms-activate.page/stubs/handler_api.php'])
 90    def __init__(self, api_key: str, base_url: str | list = allowed_domains):
 91        """
 92        RU  
 93        api_key передавать api ключ, получить можно вот тут: https://sms-activate.page/profile
 94        В base_url можно указать список адресов, модуль будет проходиться по всем, пока не найдёт рабочий
 95        а можно указать один или вообще не указывать, если не указать будет браться из allowed_domains  
 96        
 97        EN  
 98        api_key to transfer the api key, you can get it here: https://sms-activate.page/profile
 99        You can specify a list of addresses in base_url, and the module will go through all of them until it finds a working one.
100        or you can specify one or not at all, if not specified, it will be taken from allowed_domains.
101        """
102        self._api_key = api_key
103        if isinstance(base_url, str):
104            base_url = [base_url]
105        self._base_urls = base_url
106        self._accept_url = None

RU
api_key передавать api ключ, получить можно вот тут: https://sms-activate.page/profile В base_url можно указать список адресов, модуль будет проходиться по всем, пока не найдёт рабочий а можно указать один или вообще не указывать, если не указать будет браться из allowed_domains

EN
api_key to transfer the api key, you can get it here: https://sms-activate.page/profile You can specify a list of addresses in base_url, and the module will go through all of them until it finds a working one. or you can specify one or not at all, if not specified, it will be taken from allowed_domains.

async def get_balance(self, cashback: bool = False) -> float:
141    async def get_balance(self, cashback: bool = False) -> float:
142        pattern = re.compile(r'ACCESS_BALANCE:(\d+\.\d{2})')
143        response = await self.__send_request('getBalance' if not cashback else 'getBalanceAndCashBack')
144        match = pattern.match(response)
145        if not match:
146            raise SmsActivateException('Invalid response sequence')
147
148        return float(match.group(1))
async def get_balance_and_cashback(self):
149    async def get_balance_and_cashback(self):
150        return await self.get_balance(cashback=True)
async def get_available_countries(self, service: str, freePrice: bool | str) -> dict[str, typing.Any]:
152    async def get_available_countries(self, service: str, freePrice: bool | str) -> dict[str, Any]:
153        response = await self.__send_request('getTopCountriesByService', params={
154            'service': service,
155            'freePrice': str(freePrice).lower()
156        })
157        
158        if not is_json(response):
159            return response
160        
161        return json.loads(response)
async def get_count_numbers(self, country: str, operator: str) -> dict[str, typing.Any]:
163    async def get_count_numbers(self, country: str, operator: str) -> dict[str, Any]:
164        response = await self.__send_request('getNumbersStatus', params={
165            'country': country,
166            'operator': operator
167        })
168        
169        if not is_json(response):
170            return response
171        
172        return json.loads(response)
async def get_operators(self, country: str = None) -> dict[str, typing.Any]:
174    async def get_operators(self, country: str = None) -> dict[str, Any]:
175        params = {}
176        if country is not None:
177            params["country"] = country
178        response = await self.__send_request('getOperators', params=params)
179        
180        if not is_json(response):
181            return response
182        
183        return json.loads(response)
async def get_active_activations(self) -> dict[str, typing.Any]:
185    async def get_active_activations(self) -> dict[str, Any]:
186        response = await self.__send_request('getActiveActivations')
187        
188        if not is_json(response):
189            return response
190        
191        return json.loads(response)
async def get_activation_status_v1( self, id: str) -> tuple[aiosmsactivate.types.ActivationStatus, str | None]:
193    async def get_activation_status_v1(self, id: str) -> tuple[ActivationStatus, str | None]:
194        response = await self.__send_request('getStatus', params={
195            'id': id
196        })
197
198        data = response.split(':')
199
200        match data[0]:
201            case 'STATUS_WAIT_CODE':
202                return ActivationStatus.WAIT, None
203            case 'STATUS_WAIT_RETRY':
204                return ActivationStatus.RETRY, data[1]
205            case 'STATUS_WAIT_RESEND':
206                return ActivationStatus.RESEND, None
207            case 'STATUS_CANCEL':
208                return ActivationStatus.CANCEL, None
209            case 'STATUS_OK':
210                return ActivationStatus.OK, data[1]
211            case _:
212                raise SmsActivateException('Invalid response sequence')
async def get_activation_status( self, activation_id: str | int | aiosmsactivate.models.Number) -> aiosmsactivate.models.ActivationData | str:
214    async def get_activation_status(self, activation_id: str | int | Number) -> ActivationData | str:
215        if isinstance(activation_id, Number):
216            activation_id = activation_id.activation_id
217        response = await self.__send_request('getStatusV2', params={
218            'id': activation_id
219        })
220
221        if not is_json(response):
222            return response
223        
224        return ActivationData(**json.loads(response))
async def wait_sms_code( self, activation_id: str | int | aiosmsactivate.models.Number, timeout: int = 300, per_attempt: int = 5) -> aiosmsactivate.models.Sms | str | int | None:
226    async def wait_sms_code(self, activation_id: str | int | Number, timeout: int = 60*5, per_attempt: int = 5) -> Sms | str | int | None:
227        """
228        Ожидание смс кода
229        Wait sms code
230
231        Аргументы:
232            activation_id: activation_id номера или целый объект номера
233            timeout: максимальное время ожидание смс в секундах, по умолчанию 5 минут 
234            per_attempt: время между попыткой получить смс, по умолчанию 5 секунд
235            
236        Args:
237            activation_id: activation_id of number or Number object
238            timeout: maximum time to wait sms code 
239            per_attempt: time per attempt
240            
241        Returns: Sms
242        """
243        activation_id = activation_id.activation_id if isinstance(activation_id, Number) else activation_id
244        if not self._api_key:
245            raise ValueError('API key is required for this method')
246
247        try:
248            await self.set_activation_status(activation_id=activation_id, status=SetActivationStatus.READY)
249        except:
250            pass
251
252        start_time = time.time()
253        
254        while time.time() - start_time < timeout:
255            await asyncio.sleep(per_attempt)
256            status, code = await self.get_activation_status_v1(activation_id)
257            if status == ActivationStatus.OK:
258                try:
259                    await self.set_activation_status(activation_id, SetActivationStatus.AGAIN)
260                except:
261                    pass
262                return code
263        
264        return None

Ожидание смс кода Wait sms code

Аргументы: activation_id: activation_id номера или целый объект номера timeout: максимальное время ожидание смс в секундах, по умолчанию 5 минут per_attempt: время между попыткой получить смс, по умолчанию 5 секунд

Args: activation_id: activation_id of number or Number object timeout: maximum time to wait sms code per_attempt: time per attempt

Returns: Sms

async def purchase( self, service: str, forward: bool | None = None, maxPrice: float | None = None, phoneException: str | None = None, operator: str | None = None, activationType: int | str | None = None, language: str | None = None, userId: str | int | None = None, ref: str | None = None, country: str | None = None, useCashBack: bool | None = None, orderId: str | int | None = None, _is_v2: bool = True) -> aiosmsactivate.models.Number | str:
266    async def purchase(self, service: str, forward: bool | None = None, maxPrice: float | None = None,
267                       phoneException: str | None = None, operator: str | None = None,
268                       activationType: int | str | None = None, language: str | None = None,
269                       userId: str | int | None = None,
270                       ref: str | None = None, country: str | None = None,
271                       useCashBack: bool | None = None,
272                       orderId: str | int | None = None,
273                       _is_v2: bool = True
274                       ) -> Number | str:
275        response = await self.__send_request('getNumber' if not _is_v2 else 'getNumberV2', params={
276            'service': service,
277            **({'forward': 1 if forward else 0} if forward is not None else {}),
278            **({'maxPrice': str(maxPrice)} if maxPrice is not None else {}),
279            **({'phoneException': phoneException} if phoneException is not None else {}),
280            **({'operator': operator} if operator is not None else {}),
281            **({'activationType': str(activationType)} if activationType is not None else {}),
282            **({'language': str(language)} if language is not None else {}),
283            **({'userId': str(userId)} if userId is not None else {}),
284            **({'orderId': str(orderId)} if orderId is not None and _is_v2 else {}),
285            **({'ref': ref} if ref is not None else {}),
286            **({'country ': country} if country is not None else {}),
287            **({'useCashBack': str(useCashBack).lower()} if useCashBack is not None else {}),
288        })
289
290        if not is_json(response):
291            return response
292        
293        return Number.from_response(self, json.loads(response))
async def get_number(self, *args, **kwargs):
295    async def get_number(self, *args, **kwargs):
296        kwargs["_is_v2"] = False
297        return await self.purchase(*args, **kwargs)
async def get_multi_service_number( self, multiService: str, multiForward: str | None = None, operator: str | None = None, ref: str | None = None, country: str | None = None) -> dict:
299    async def get_multi_service_number(self, 
300                        multiService: str, multiForward: str | None = None,
301                        operator: str | None = None,
302                        ref: str | None = None, country: str | None = None,
303                       ) -> dict:
304        """
305        Get multiservice number.
306
307        :param multiService: service1,service2,service3 (Services separated by commas)
308        :param multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count)
309        :return: dict object of response
310        """
311        response = await self.__send_request('getMultiServiceNumber', params={
312            'multiService': multiService,
313            **({'multiForward': multiForward} if multiForward is not None else {}),
314            **({'operator': operator} if operator is not None else {}),
315            **({'ref': ref} if ref is not None else {}),
316            **({'country ': country} if country is not None else {}),
317        })
318
319        if not is_json(response):
320            return response
321        
322        return json.loads(response)

Get multiservice number.

Parameters
  • multiService: service1,service2,service3 (Services separated by commas)
  • multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count)
Returns

dict object of response

async def set_activation_status( self, activation_id: str | int, status: aiosmsactivate.types.SetActivationStatus | int, forward: str | None = None) -> aiosmsactivate.models.SetActivationStatusResponse:
325    async def set_activation_status(self, activation_id: str | int, status: SetActivationStatus | int,
326                                    forward: str | None = None) -> SetActivationStatusResponse:
327        members = {member.value: member for member in SetActivationStatusResponse}
328        response = await self.__send_request('setStatus', params={
329            'id': activation_id,
330            'status': status.value if isinstance(status, SetActivationStatus) else status,
331            **({'forward': forward} if forward is not None else {})
332        })
333
334        return members[response]
async def get_history( self, start: str | int = None, end: str | int = None, offset: str | int = None, limit: str | int = None) -> dict | list:
336    async def get_history(self, 
337                          start: str | int = None,
338                          end: str | int = None,
339                          offset: str | int = None,
340                          limit: str | int = None,
341                       ) -> dict | list:
342        response = await self.__send_request('getHistory', params={
343            **({'start': str(start)} if start is not None else {}),
344            **({'end': str(end)} if end is not None else {}),
345            **({'offset': str(offset)} if offset is not None else {}),
346            **({'limit': str(limit)} if limit is not None else {}),
347        })
348
349        if not is_json(response):
350            return response
351        
352        return json.loads(response)
async def get_list_top_countries(self, service: str) -> dict | list:
354    async def get_list_top_countries(self, 
355                          service: str,
356                       ) -> dict | list:
357        response = await self.__send_request('getListOfTopCountriesByService', params={
358            'service': service
359        })
360
361        if not is_json(response):
362            return response
363        
364        return json.loads(response)
async def get_incoming_call_status(self, id: str | int = None) -> dict | list:
366    async def get_incoming_call_status(self, 
367                          id: str | int = None,
368                       ) -> dict | list:
369        response = await self.__send_request('getIncomingCallStatus', params={
370            'activationId': id
371        })
372
373        if not is_json(response):
374            return response
375        
376        return json.loads(response)
async def get_service( self, service_code: str, country: str | int, lang: Literal['ru', 'en', 'es', 'cn'] = 'en'):
378    async def get_service(self, service_code: str, country: str | int, lang: Literal['ru', 'en', 'es', 'cn'] = 'en'):
379        """
380        RU  
381        Получить все данные о сервисе  
382        EN  
383        Get all data about service  
384        
385        Example
386        ```python
387        service = await sa.get_service('ya', 0)
388        print(service) # code='ya' name='Yandex/Uber' country='0' cost=0.115 count=10794 physical_count=5075
389        ```
390        """
391        
392        country = str(country)
393        name = await self.get_service_name(service_code, lang)
394        data = await self.get_prices(service_code, country)
395        
396        cost = data[country][service_code]['cost']
397        count = data[country][service_code]['count']
398        physical_count = data[country][service_code]['physicalCount']
399        return Service(
400            code=service_code,
401            country=country,
402            name=name,
403            cost=cost,
404            count=count,
405            physical_count=physical_count,
406        )

RU
Получить все данные о сервисе
EN
Get all data about service

Example

service = await sa.get_service('ya', 0)
print(service) # code='ya' name='Yandex/Uber' country='0' cost=0.115 count=10794 physical_count=5075
async def get_prices(self, service: str = None, country: str | int = None) -> dict | list:
408    async def get_prices(self, 
409                          service: str = None,
410                          country: str | int = None,
411                       ) -> dict | list:
412        response = await self.__send_request('getPrices', params={
413            **({'service': str(service)} if service is not None else {}),
414            **({'country': str(country)} if country is not None else {}),
415        })
416
417        if not is_json(response):
418            return response
419        
420        return json.loads(response)
async def get_prices_verification(self, service: str = None) -> dict | list:
430    async def get_prices_verification(self, 
431                          service: str = None,
432                       ) -> dict | list:
433        response = await self.__send_request('getPricesVerification', params={
434            **({'service': str(service)} if service is not None else {}),
435        })
436
437        if not is_json(response):
438            return response
439        
440        return json.loads(response)
async def get_countries(self) -> dict | list:
442    async def get_countries(self,
443                       ) -> dict | list:
444        response = await self.__send_request('getCountries', params={
445        })
446
447        if not is_json(response):
448            return response
449        
450        return json.loads(response)
@cached(cache)
async def get_service_list( self, country: str = None, lang: Literal['ru', 'en', 'es', 'cn'] = None) -> dict | list:
452    @cached(cache)
453    async def get_service_list(self, 
454                          country: str = None,
455                          lang: Literal['ru', 'en', 'es', 'cn'] = None,
456                       ) -> dict | list:
457        response = await self.__send_request('getServicesList', params={
458            **({'country': str(country)} if country is not None else {}),
459            **({'lang': str(lang)} if lang is not None else {}),
460        })
461
462        if not is_json(response):
463            return response
464        
465        return json.loads(response)
async def get_service_name( self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None):
467    async def get_service_name(self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None):
468        """
469        RU  
470        Получение полного имени сервиса по его id  
471          
472        EN  
473        Get full service name by service code  
474            
475        Пример Example:  
476        service_name = await SmsActivate.get_service_name('go')  
477        service_name # 'Google,youtube,Gmail'
478        """
479        services = await self.get_service_list(lang=lang)
480        services = services.get('services')
481        for service in services:
482            if service['code'] == service_code:
483                return service['name']
484        return None

RU
Получение полного имени сервиса по его id

EN
Get full service name by service code

Пример Example:
service_name = await SmsActivate.get_service_name('go')
service_name # 'Google,youtube,Gmail'

async def get_additional_service(self, service: str = None, id: str = None):
486    async def get_additional_service(self, 
487                          service: str = None,
488                          id: str = None,
489                       ):
490        """
491        Get additional service to activation its cost 5rub
492        return 2 values: addition activation id and phone number
493        
494        use like this: 
495        activation_id, phone_number = await getAdditionalService(service, activation id)
496        """
497        response = await self.__send_request('getAdditionalService', params={
498            'service': service,
499            'id':id
500        })
501
502        data = response.split(':')
503        if len(data) > 2:
504            return data[1], data[2]
505        
506        return data

Get additional service to activation its cost 5rub return 2 values: addition activation id and phone number

use like this: activation_id, phone_number = await getAdditionalService(service, activation id)

async def get_extra_activation(self, id: str = None):
508    async def get_extra_activation(self, 
509                          id: str = None,
510                       ):
511        """
512        return 2 values: addition activation id and phone number
513        
514        use like this: 
515        activation_id, phone_number = await getExtraActivation(activation id)
516        """
517        response = await self.__send_request('getExtraActivation', params={
518            'id':id
519        })
520
521        data = response.split(':')
522        if len(data) > 2:
523            return data[1], data[2]
524        
525        return data

return 2 values: addition activation id and phone number

use like this: activation_id, phone_number = await getExtraActivation(activation id)

async def check_extra_activation(self, activationId: str | int) -> dict | list:
527    async def check_extra_activation(self, 
528                          activationId: str | int
529                       ) -> dict | list:
530        response = await self.__send_request('checkExtraActivation', params={
531            'activationId': str(activationId)
532        })
533
534        if not is_json(response):
535            return response
536        
537        return json.loads(response)
async def parse_call(self, id: str | int, newLang: str) -> dict | list:
539    async def parse_call(self, 
540                          id: str | int,
541                          newLang: str,
542                       ) -> dict | list:
543        response = await self.__send_request('parseCall', params={
544            "id": id,
545            "newLang": newLang,
546        })
547
548        if not is_json(response):
549            return response
550        
551        return json.loads(response)
async def get_rent_services_and_countries( self, time: int | str | None = None, operator: str | None = None, country: str | None = None, currency: str | None = None, incomingCall: bool | None = None) -> dict | str:
554    async def get_rent_services_and_countries(self,
555                       time: int | str | None = None,
556                       operator: str | None = None,
557                       country: str | None = None,
558                       currency: str | None = None,
559                       incomingCall: bool | None = None,
560                       ) -> dict | str:
561        response = await self.__send_request('getRentServicesAndCountries', params={
562            **({'time ': str(time )} if time is not None else {}),
563            **({'operator ': str(operator )} if operator is not None else {}),
564            **({'country ': str(country )} if country is not None else {}),
565            **({'currency ': str(currency )} if currency is not None else {}),
566            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
567        })
568
569        if not is_json(response):
570            return response
571        
572        return json.loads(response)
async def get_rent_number( self, service: str, time: int | str | None = None, operator: str | None = None, country: str | None = None, url: str | None = None, incomingCall: bool | None = None) -> dict | str:
574    async def get_rent_number(self,
575                        service: str,
576                        time: int | str | None = None,
577                        operator: str | None = None,
578                        country: str | None = None,
579                        url: str | None = None,
580                        incomingCall: bool | None = None,
581                       ) -> dict | str:
582        response = await self.__send_request('getRentNumber', params={
583            'service': service,
584            **({'time ': str(time )} if time is not None else {}),
585            **({'operator ': str(operator )} if operator is not None else {}),
586            **({'country ': str(country )} if country is not None else {}),
587            **({'url ': str(url )} if url is not None else {}),
588            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
589        })
590
591        if not is_json(response):
592            return response
593        
594        return json.loads(response)
async def get_rent_status( self, id: str, page: int | str | None = None, size: int | str | None = None) -> dict | str:
596    async def get_rent_status(self,
597                        id: str,
598                        page: int | str | None = None,
599                        size: int | str | None = None,
600                       ) -> dict | str:
601        response = await self.__send_request('getRentStatus', params={
602            'id': id,
603            **({'page ': str(page)} if page is not None else {}),
604            **({'size ': str(size )} if size is not None else {}),
605        })
606
607        if not is_json(response):
608            return response
609        
610        return json.loads(response)
async def set_rent_status(self, id: str, status: Literal[1, 2, '1', '2']) -> dict | str:
612    async def set_rent_status(self,
613                        id: str,
614                        status: Literal[1, 2, '1', '2'],
615                       ) -> dict | str:
616        response = await self.__send_request('getRentStatus', params={
617            'id': str(id),
618            'status': str(status),
619        })
620
621        if not is_json(response):
622            return response
623        
624        return json.loads(response)
async def get_rent_list(self) -> dict | str:
626    async def get_rent_list(self,
627                       ) -> dict | str:
628        response = await self.__send_request('getRentList', params={
629        })
630
631        if not is_json(response):
632            return response
633        
634        return json.loads(response)
async def continue_rent_number(self, id: str, rent_time: int | str | None = 4) -> dict | str:
636    async def continue_rent_number(self,
637                        id: str,
638                        rent_time: int | str | None = 4,
639                       ) -> dict | str:
640        response = await self.__send_request('continueRentNumber', params={
641            'id': id,
642            'rent_time': str(rent_time)
643        })
644
645        if not is_json(response):
646            return response
647        
648        return json.loads(response)
async def get_continue_rent_price_number( self, id: str, rent_time: int | str | None = 4, currency: str | None = None) -> dict | str:
650    async def get_continue_rent_price_number(self,
651                        id: str,
652                        rent_time: int | str | None = 4,
653                        currency: str | None = None
654                       ) -> dict | str:
655        response = await self.__send_request('getContinueRentPriceNumber', params={
656            'id': id,
657            'rent_time': str(rent_time),
658            **({'currency ': str(currency )} if currency is not None else {}),
659        })
660
661        if not is_json(response):
662            return response
663        
664        return json.loads(response)
async def buy_partner_product(self, id: str) -> dict | str:
667    async def buy_partner_product(self,
668                        id: str,
669                       ) -> dict | str:
670        response = await self.__send_request('buyPartnerProduct', params={
671            'id': id,
672        })
673
674        if not is_json(response):
675            return response
676        
677        return json.loads(response)
async def getBalance(self, cashback: bool = False) -> float:
141    async def get_balance(self, cashback: bool = False) -> float:
142        pattern = re.compile(r'ACCESS_BALANCE:(\d+\.\d{2})')
143        response = await self.__send_request('getBalance' if not cashback else 'getBalanceAndCashBack')
144        match = pattern.match(response)
145        if not match:
146            raise SmsActivateException('Invalid response sequence')
147
148        return float(match.group(1))
async def getBalanceAndCashBack(self):
149    async def get_balance_and_cashback(self):
150        return await self.get_balance(cashback=True)
async def getTopCountriesByService(self, service: str, freePrice: bool | str) -> dict[str, typing.Any]:
152    async def get_available_countries(self, service: str, freePrice: bool | str) -> dict[str, Any]:
153        response = await self.__send_request('getTopCountriesByService', params={
154            'service': service,
155            'freePrice': str(freePrice).lower()
156        })
157        
158        if not is_json(response):
159            return response
160        
161        return json.loads(response)
async def getNumbersStatus(self, country: str, operator: str) -> dict[str, typing.Any]:
163    async def get_count_numbers(self, country: str, operator: str) -> dict[str, Any]:
164        response = await self.__send_request('getNumbersStatus', params={
165            'country': country,
166            'operator': operator
167        })
168        
169        if not is_json(response):
170            return response
171        
172        return json.loads(response)
async def getOperators(self, country: str = None) -> dict[str, typing.Any]:
174    async def get_operators(self, country: str = None) -> dict[str, Any]:
175        params = {}
176        if country is not None:
177            params["country"] = country
178        response = await self.__send_request('getOperators', params=params)
179        
180        if not is_json(response):
181            return response
182        
183        return json.loads(response)
async def getActiveActivations(self) -> dict[str, typing.Any]:
185    async def get_active_activations(self) -> dict[str, Any]:
186        response = await self.__send_request('getActiveActivations')
187        
188        if not is_json(response):
189            return response
190        
191        return json.loads(response)
async def getStatus( self, id: str) -> tuple[aiosmsactivate.types.ActivationStatus, str | None]:
193    async def get_activation_status_v1(self, id: str) -> tuple[ActivationStatus, str | None]:
194        response = await self.__send_request('getStatus', params={
195            'id': id
196        })
197
198        data = response.split(':')
199
200        match data[0]:
201            case 'STATUS_WAIT_CODE':
202                return ActivationStatus.WAIT, None
203            case 'STATUS_WAIT_RETRY':
204                return ActivationStatus.RETRY, data[1]
205            case 'STATUS_WAIT_RESEND':
206                return ActivationStatus.RESEND, None
207            case 'STATUS_CANCEL':
208                return ActivationStatus.CANCEL, None
209            case 'STATUS_OK':
210                return ActivationStatus.OK, data[1]
211            case _:
212                raise SmsActivateException('Invalid response sequence')
async def getStatusV2( self, activation_id: str | int | aiosmsactivate.models.Number) -> aiosmsactivate.models.ActivationData | str:
214    async def get_activation_status(self, activation_id: str | int | Number) -> ActivationData | str:
215        if isinstance(activation_id, Number):
216            activation_id = activation_id.activation_id
217        response = await self.__send_request('getStatusV2', params={
218            'id': activation_id
219        })
220
221        if not is_json(response):
222            return response
223        
224        return ActivationData(**json.loads(response))
async def getNumberV2( self, service: str, forward: bool | None = None, maxPrice: float | None = None, phoneException: str | None = None, operator: str | None = None, activationType: int | str | None = None, language: str | None = None, userId: str | int | None = None, ref: str | None = None, country: str | None = None, useCashBack: bool | None = None, orderId: str | int | None = None, _is_v2: bool = True) -> aiosmsactivate.models.Number | str:
266    async def purchase(self, service: str, forward: bool | None = None, maxPrice: float | None = None,
267                       phoneException: str | None = None, operator: str | None = None,
268                       activationType: int | str | None = None, language: str | None = None,
269                       userId: str | int | None = None,
270                       ref: str | None = None, country: str | None = None,
271                       useCashBack: bool | None = None,
272                       orderId: str | int | None = None,
273                       _is_v2: bool = True
274                       ) -> Number | str:
275        response = await self.__send_request('getNumber' if not _is_v2 else 'getNumberV2', params={
276            'service': service,
277            **({'forward': 1 if forward else 0} if forward is not None else {}),
278            **({'maxPrice': str(maxPrice)} if maxPrice is not None else {}),
279            **({'phoneException': phoneException} if phoneException is not None else {}),
280            **({'operator': operator} if operator is not None else {}),
281            **({'activationType': str(activationType)} if activationType is not None else {}),
282            **({'language': str(language)} if language is not None else {}),
283            **({'userId': str(userId)} if userId is not None else {}),
284            **({'orderId': str(orderId)} if orderId is not None and _is_v2 else {}),
285            **({'ref': ref} if ref is not None else {}),
286            **({'country ': country} if country is not None else {}),
287            **({'useCashBack': str(useCashBack).lower()} if useCashBack is not None else {}),
288        })
289
290        if not is_json(response):
291            return response
292        
293        return Number.from_response(self, json.loads(response))
async def purchase_v1(self, *args, **kwargs):
295    async def get_number(self, *args, **kwargs):
296        kwargs["_is_v2"] = False
297        return await self.purchase(*args, **kwargs)
async def getNumber(self, *args, **kwargs):
295    async def get_number(self, *args, **kwargs):
296        kwargs["_is_v2"] = False
297        return await self.purchase(*args, **kwargs)
async def getMultiServiceNumber( self, multiService: str, multiForward: str | None = None, operator: str | None = None, ref: str | None = None, country: str | None = None) -> dict:
299    async def get_multi_service_number(self, 
300                        multiService: str, multiForward: str | None = None,
301                        operator: str | None = None,
302                        ref: str | None = None, country: str | None = None,
303                       ) -> dict:
304        """
305        Get multiservice number.
306
307        :param multiService: service1,service2,service3 (Services separated by commas)
308        :param multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count)
309        :return: dict object of response
310        """
311        response = await self.__send_request('getMultiServiceNumber', params={
312            'multiService': multiService,
313            **({'multiForward': multiForward} if multiForward is not None else {}),
314            **({'operator': operator} if operator is not None else {}),
315            **({'ref': ref} if ref is not None else {}),
316            **({'country ': country} if country is not None else {}),
317        })
318
319        if not is_json(response):
320            return response
321        
322        return json.loads(response)

Get multiservice number.

Parameters
  • multiService: service1,service2,service3 (Services separated by commas)
  • multiForward: 1,0,1 (forwards separated by commas, forwards count equal services count)
Returns

dict object of response

async def setStatus( self, activation_id: str | int, status: aiosmsactivate.types.SetActivationStatus | int, forward: str | None = None) -> aiosmsactivate.models.SetActivationStatusResponse:
325    async def set_activation_status(self, activation_id: str | int, status: SetActivationStatus | int,
326                                    forward: str | None = None) -> SetActivationStatusResponse:
327        members = {member.value: member for member in SetActivationStatusResponse}
328        response = await self.__send_request('setStatus', params={
329            'id': activation_id,
330            'status': status.value if isinstance(status, SetActivationStatus) else status,
331            **({'forward': forward} if forward is not None else {})
332        })
333
334        return members[response]
async def getHistory( self, start: str | int = None, end: str | int = None, offset: str | int = None, limit: str | int = None) -> dict | list:
336    async def get_history(self, 
337                          start: str | int = None,
338                          end: str | int = None,
339                          offset: str | int = None,
340                          limit: str | int = None,
341                       ) -> dict | list:
342        response = await self.__send_request('getHistory', params={
343            **({'start': str(start)} if start is not None else {}),
344            **({'end': str(end)} if end is not None else {}),
345            **({'offset': str(offset)} if offset is not None else {}),
346            **({'limit': str(limit)} if limit is not None else {}),
347        })
348
349        if not is_json(response):
350            return response
351        
352        return json.loads(response)
async def getListOfTopCountriesByService(self, service: str) -> dict | list:
354    async def get_list_top_countries(self, 
355                          service: str,
356                       ) -> dict | list:
357        response = await self.__send_request('getListOfTopCountriesByService', params={
358            'service': service
359        })
360
361        if not is_json(response):
362            return response
363        
364        return json.loads(response)
async def getIncomingCallStatus(self, id: str | int = None) -> dict | list:
366    async def get_incoming_call_status(self, 
367                          id: str | int = None,
368                       ) -> dict | list:
369        response = await self.__send_request('getIncomingCallStatus', params={
370            'activationId': id
371        })
372
373        if not is_json(response):
374            return response
375        
376        return json.loads(response)
async def getPrices(self, service: str = None, country: str | int = None) -> dict | list:
408    async def get_prices(self, 
409                          service: str = None,
410                          country: str | int = None,
411                       ) -> dict | list:
412        response = await self.__send_request('getPrices', params={
413            **({'service': str(service)} if service is not None else {}),
414            **({'country': str(country)} if country is not None else {}),
415        })
416
417        if not is_json(response):
418            return response
419        
420        return json.loads(response)
async def getPricesVerification(self, service: str = None) -> dict | list:
430    async def get_prices_verification(self, 
431                          service: str = None,
432                       ) -> dict | list:
433        response = await self.__send_request('getPricesVerification', params={
434            **({'service': str(service)} if service is not None else {}),
435        })
436
437        if not is_json(response):
438            return response
439        
440        return json.loads(response)
async def getCountries(self) -> dict | list:
442    async def get_countries(self,
443                       ) -> dict | list:
444        response = await self.__send_request('getCountries', params={
445        })
446
447        if not is_json(response):
448            return response
449        
450        return json.loads(response)
@cached(cache)
async def getServicesList( self, country: str = None, lang: Literal['ru', 'en', 'es', 'cn'] = None) -> dict | list:
452    @cached(cache)
453    async def get_service_list(self, 
454                          country: str = None,
455                          lang: Literal['ru', 'en', 'es', 'cn'] = None,
456                       ) -> dict | list:
457        response = await self.__send_request('getServicesList', params={
458            **({'country': str(country)} if country is not None else {}),
459            **({'lang': str(lang)} if lang is not None else {}),
460        })
461
462        if not is_json(response):
463            return response
464        
465        return json.loads(response)
async def getAdditionalService(self, service: str = None, id: str = None):
486    async def get_additional_service(self, 
487                          service: str = None,
488                          id: str = None,
489                       ):
490        """
491        Get additional service to activation its cost 5rub
492        return 2 values: addition activation id and phone number
493        
494        use like this: 
495        activation_id, phone_number = await getAdditionalService(service, activation id)
496        """
497        response = await self.__send_request('getAdditionalService', params={
498            'service': service,
499            'id':id
500        })
501
502        data = response.split(':')
503        if len(data) > 2:
504            return data[1], data[2]
505        
506        return data

Get additional service to activation its cost 5rub return 2 values: addition activation id and phone number

use like this: activation_id, phone_number = await getAdditionalService(service, activation id)

async def getExtraActivation(self, id: str = None):
508    async def get_extra_activation(self, 
509                          id: str = None,
510                       ):
511        """
512        return 2 values: addition activation id and phone number
513        
514        use like this: 
515        activation_id, phone_number = await getExtraActivation(activation id)
516        """
517        response = await self.__send_request('getExtraActivation', params={
518            'id':id
519        })
520
521        data = response.split(':')
522        if len(data) > 2:
523            return data[1], data[2]
524        
525        return data

return 2 values: addition activation id and phone number

use like this: activation_id, phone_number = await getExtraActivation(activation id)

async def checkExtraActivation(self, activationId: str | int) -> dict | list:
527    async def check_extra_activation(self, 
528                          activationId: str | int
529                       ) -> dict | list:
530        response = await self.__send_request('checkExtraActivation', params={
531            'activationId': str(activationId)
532        })
533
534        if not is_json(response):
535            return response
536        
537        return json.loads(response)
async def parseCall(self, id: str | int, newLang: str) -> dict | list:
539    async def parse_call(self, 
540                          id: str | int,
541                          newLang: str,
542                       ) -> dict | list:
543        response = await self.__send_request('parseCall', params={
544            "id": id,
545            "newLang": newLang,
546        })
547
548        if not is_json(response):
549            return response
550        
551        return json.loads(response)
async def getRentServicesAndCountries( self, time: int | str | None = None, operator: str | None = None, country: str | None = None, currency: str | None = None, incomingCall: bool | None = None) -> dict | str:
554    async def get_rent_services_and_countries(self,
555                       time: int | str | None = None,
556                       operator: str | None = None,
557                       country: str | None = None,
558                       currency: str | None = None,
559                       incomingCall: bool | None = None,
560                       ) -> dict | str:
561        response = await self.__send_request('getRentServicesAndCountries', params={
562            **({'time ': str(time )} if time is not None else {}),
563            **({'operator ': str(operator )} if operator is not None else {}),
564            **({'country ': str(country )} if country is not None else {}),
565            **({'currency ': str(currency )} if currency is not None else {}),
566            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
567        })
568
569        if not is_json(response):
570            return response
571        
572        return json.loads(response)
async def getRentNumber( self, service: str, time: int | str | None = None, operator: str | None = None, country: str | None = None, url: str | None = None, incomingCall: bool | None = None) -> dict | str:
574    async def get_rent_number(self,
575                        service: str,
576                        time: int | str | None = None,
577                        operator: str | None = None,
578                        country: str | None = None,
579                        url: str | None = None,
580                        incomingCall: bool | None = None,
581                       ) -> dict | str:
582        response = await self.__send_request('getRentNumber', params={
583            'service': service,
584            **({'time ': str(time )} if time is not None else {}),
585            **({'operator ': str(operator )} if operator is not None else {}),
586            **({'country ': str(country )} if country is not None else {}),
587            **({'url ': str(url )} if url is not None else {}),
588            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
589        })
590
591        if not is_json(response):
592            return response
593        
594        return json.loads(response)
async def getRentStatus( self, id: str, page: int | str | None = None, size: int | str | None = None) -> dict | str:
596    async def get_rent_status(self,
597                        id: str,
598                        page: int | str | None = None,
599                        size: int | str | None = None,
600                       ) -> dict | str:
601        response = await self.__send_request('getRentStatus', params={
602            'id': id,
603            **({'page ': str(page)} if page is not None else {}),
604            **({'size ': str(size )} if size is not None else {}),
605        })
606
607        if not is_json(response):
608            return response
609        
610        return json.loads(response)
async def getRentList(self) -> dict | str:
626    async def get_rent_list(self,
627                       ) -> dict | str:
628        response = await self.__send_request('getRentList', params={
629        })
630
631        if not is_json(response):
632            return response
633        
634        return json.loads(response)
async def continueRentNumber(self, id: str, rent_time: int | str | None = 4) -> dict | str:
636    async def continue_rent_number(self,
637                        id: str,
638                        rent_time: int | str | None = 4,
639                       ) -> dict | str:
640        response = await self.__send_request('continueRentNumber', params={
641            'id': id,
642            'rent_time': str(rent_time)
643        })
644
645        if not is_json(response):
646            return response
647        
648        return json.loads(response)
async def getContinueRentPriceNumber( self, id: str, rent_time: int | str | None = 4, currency: str | None = None) -> dict | str:
650    async def get_continue_rent_price_number(self,
651                        id: str,
652                        rent_time: int | str | None = 4,
653                        currency: str | None = None
654                       ) -> dict | str:
655        response = await self.__send_request('getContinueRentPriceNumber', params={
656            'id': id,
657            'rent_time': str(rent_time),
658            **({'currency ': str(currency )} if currency is not None else {}),
659        })
660
661        if not is_json(response):
662            return response
663        
664        return json.loads(response)
async def buyPartnerProduct(self, id: str) -> dict | str:
667    async def buy_partner_product(self,
668                        id: str,
669                       ) -> dict | str:
670        response = await self.__send_request('buyPartnerProduct', params={
671            'id': id,
672        })
673
674        if not is_json(response):
675            return response
676        
677        return json.loads(response)