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, 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_prices(self, 
378                          service: str = None,
379                          country: str = None,
380                       ) -> dict | list:
381        response = await self.__send_request('getPrices', params={
382            **({'service': str(service)} if service is not None else {}),
383            **({'country': str(country)} if country is not None else {}),
384        })
385
386        if not is_json(response):
387            return response
388        
389        return json.loads(response)
390    
391    async def get_prices_verification(self, 
392                          service: str = None,
393                       ) -> dict | list:
394        response = await self.__send_request('getPricesVerification', params={
395            **({'service': str(service)} if service is not None else {}),
396        })
397
398        if not is_json(response):
399            return response
400        
401        return json.loads(response)
402    
403    async def get_countries(self,
404                       ) -> dict | list:
405        response = await self.__send_request('getCountries', params={
406        })
407
408        if not is_json(response):
409            return response
410        
411        return json.loads(response)
412    
413    @cached(cache)
414    async def get_service_list(self, 
415                          country: str = None,
416                          lang: Literal['ru', 'en', 'es', 'cn'] = None,
417                       ) -> dict | list:
418        response = await self.__send_request('getServicesList', params={
419            **({'country': str(country)} if country is not None else {}),
420            **({'lang': str(lang)} if lang is not None else {}),
421        })
422
423        if not is_json(response):
424            return response
425        
426        return json.loads(response)
427    
428    async def get_service_name(self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None):
429        """
430        RU  
431        Получение полного имени сервиса по его id  
432          
433        EN  
434        Get full service name by service code  
435            
436        Пример Example:  
437        service_name = await SmsActivate.get_service_name('go')  
438        service_name # 'Google,youtube,Gmail'
439        """
440        services = await self.get_service_list(lang=lang)
441        services = services.get('services')
442        for service in services:
443            if service['code'] == service_code:
444                return service['name']
445        return None
446    
447    async def get_additional_service(self, 
448                          service: str = None,
449                          id: str = None,
450                       ):
451        """
452        Get additional service to activation its cost 5rub
453        return 2 values: addition activation id and phone number
454        
455        use like this: 
456        activation_id, phone_number = await getAdditionalService(service, activation id)
457        """
458        response = await self.__send_request('getAdditionalService', params={
459            'service': service,
460            'id':id
461        })
462
463        data = response.split(':')
464        if len(data) > 2:
465            return data[1], data[2]
466        
467        return data
468    
469    async def get_extra_activation(self, 
470                          id: str = None,
471                       ):
472        """
473        return 2 values: addition activation id and phone number
474        
475        use like this: 
476        activation_id, phone_number = await getExtraActivation(activation id)
477        """
478        response = await self.__send_request('getExtraActivation', params={
479            'id':id
480        })
481
482        data = response.split(':')
483        if len(data) > 2:
484            return data[1], data[2]
485        
486        return data
487    
488    async def check_extra_activation(self, 
489                          activationId: str | int
490                       ) -> dict | list:
491        response = await self.__send_request('checkExtraActivation', params={
492            'activationId': str(activationId)
493        })
494
495        if not is_json(response):
496            return response
497        
498        return json.loads(response)
499    
500    async def parse_call(self, 
501                          id: str | int,
502                          newLang: str,
503                       ) -> dict | list:
504        response = await self.__send_request('parseCall', params={
505            "id": id,
506            "newLang": newLang,
507        })
508
509        if not is_json(response):
510            return response
511        
512        return json.loads(response)
513    
514    # !!! BOTTOM IT IS RENT API
515    async def get_rent_services_and_countries(self,
516                       time: int | str | None = None,
517                       operator: str | None = None,
518                       country: str | None = None,
519                       currency: str | None = None,
520                       incomingCall: bool | None = None,
521                       ) -> dict | str:
522        response = await self.__send_request('getRentServicesAndCountries', params={
523            **({'time ': str(time )} if time is not None else {}),
524            **({'operator ': str(operator )} if operator is not None else {}),
525            **({'country ': str(country )} if country is not None else {}),
526            **({'currency ': str(currency )} if currency is not None else {}),
527            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
528        })
529
530        if not is_json(response):
531            return response
532        
533        return json.loads(response)
534    
535    async def get_rent_number(self,
536                        service: str,
537                        time: int | str | None = None,
538                        operator: str | None = None,
539                        country: str | None = None,
540                        url: str | None = None,
541                        incomingCall: bool | None = None,
542                       ) -> dict | str:
543        response = await self.__send_request('getRentNumber', params={
544            'service': service,
545            **({'time ': str(time )} if time is not None else {}),
546            **({'operator ': str(operator )} if operator is not None else {}),
547            **({'country ': str(country )} if country is not None else {}),
548            **({'url ': str(url )} if url is not None else {}),
549            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
550        })
551
552        if not is_json(response):
553            return response
554        
555        return json.loads(response)
556    
557    async def get_rent_status(self,
558                        id: str,
559                        page: int | str | None = None,
560                        size: int | str | None = None,
561                       ) -> dict | str:
562        response = await self.__send_request('getRentStatus', params={
563            'id': id,
564            **({'page ': str(page)} if page is not None else {}),
565            **({'size ': str(size )} if size 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 set_rent_status(self,
574                        id: str,
575                        status: Literal[1, 2, '1', '2'],
576                       ) -> dict | str:
577        response = await self.__send_request('getRentStatus', params={
578            'id': str(id),
579            'status': str(status),
580        })
581
582        if not is_json(response):
583            return response
584        
585        return json.loads(response)
586    
587    async def get_rent_list(self,
588                       ) -> dict | str:
589        response = await self.__send_request('getRentList', params={
590        })
591
592        if not is_json(response):
593            return response
594        
595        return json.loads(response)
596    
597    async def continue_rent_number(self,
598                        id: str,
599                        rent_time: int | str | None = 4,
600                       ) -> dict | str:
601        response = await self.__send_request('continueRentNumber', params={
602            'id': id,
603            'rent_time': str(rent_time)
604        })
605
606        if not is_json(response):
607            return response
608        
609        return json.loads(response)
610    
611    async def get_continue_rent_price_number(self,
612                        id: str,
613                        rent_time: int | str | None = 4,
614                        currency: str | None = None
615                       ) -> dict | str:
616        response = await self.__send_request('getContinueRentPriceNumber', params={
617            'id': id,
618            'rent_time': str(rent_time),
619            **({'currency ': str(currency )} if currency is not None else {}),
620        })
621
622        if not is_json(response):
623            return response
624        
625        return json.loads(response)
626    
627    # !!! BOTTOM IS IT PARTNER SOFT API
628    async def buy_partner_product(self,
629                        id: str,
630                       ) -> dict | str:
631        response = await self.__send_request('buyPartnerProduct', params={
632            'id': id,
633        })
634
635        if not is_json(response):
636            return response
637        
638        return json.loads(response)
639    
640
641# === Method Aliases (outside class for pdoc) ===
642SmsActivate.getBalance = SmsActivate.get_balance
643SmsActivate.getBalanceAndCashBack = SmsActivate.get_balance_and_cashback
644SmsActivate.getTopCountriesByService = SmsActivate.get_available_countries
645SmsActivate.getNumbersStatus = SmsActivate.get_count_numbers
646SmsActivate.getOperators = SmsActivate.get_operators
647SmsActivate.getActiveActivations = SmsActivate.get_active_activations
648SmsActivate.getStatus = SmsActivate.get_activation_status_v1
649SmsActivate.getStatusV2 = SmsActivate.get_activation_status
650SmsActivate.getNumberV2 = SmsActivate.purchase
651SmsActivate.purchase_v1 = SmsActivate.get_number
652SmsActivate.getNumber = SmsActivate.get_number
653SmsActivate.getMultiServiceNumber = SmsActivate.get_multi_service_number
654SmsActivate.setStatus = SmsActivate.set_activation_status
655SmsActivate.getHistory = SmsActivate.get_history
656SmsActivate.getListOfTopCountriesByService = SmsActivate.get_list_top_countries
657SmsActivate.getIncomingCallStatus = SmsActivate.get_incoming_call_status
658SmsActivate.getPrices = SmsActivate.get_prices
659SmsActivate.getPricesVerification = SmsActivate.get_prices_verification
660SmsActivate.getCountries = SmsActivate.get_countries
661SmsActivate.getServicesList = SmsActivate.get_service_list
662SmsActivate.getAdditionalService = SmsActivate.get_additional_service
663SmsActivate.getExtraActivation = SmsActivate.get_extra_activation
664SmsActivate.checkExtraActivation = SmsActivate.check_extra_activation
665SmsActivate.parseCall = SmsActivate.parse_call
666SmsActivate.getRentServicesAndCountries = SmsActivate.get_rent_services_and_countries
667SmsActivate.getRentNumber = SmsActivate.get_rent_number
668SmsActivate.getRentStatus = SmsActivate.get_rent_status
669SmsActivate.getRentStatus = SmsActivate.get_rent_status
670SmsActivate.getRentList = SmsActivate.get_rent_list
671SmsActivate.continueRentNumber = SmsActivate.continue_rent_number
672SmsActivate.getContinueRentPriceNumber = SmsActivate.get_continue_rent_price_number
673SmsActivate.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_prices(self, 
379                          service: str = None,
380                          country: str = None,
381                       ) -> dict | list:
382        response = await self.__send_request('getPrices', params={
383            **({'service': str(service)} if service is not None else {}),
384            **({'country': str(country)} if country is not None else {}),
385        })
386
387        if not is_json(response):
388            return response
389        
390        return json.loads(response)
391    
392    async def get_prices_verification(self, 
393                          service: str = None,
394                       ) -> dict | list:
395        response = await self.__send_request('getPricesVerification', params={
396            **({'service': str(service)} if service is not None else {}),
397        })
398
399        if not is_json(response):
400            return response
401        
402        return json.loads(response)
403    
404    async def get_countries(self,
405                       ) -> dict | list:
406        response = await self.__send_request('getCountries', params={
407        })
408
409        if not is_json(response):
410            return response
411        
412        return json.loads(response)
413    
414    @cached(cache)
415    async def get_service_list(self, 
416                          country: str = None,
417                          lang: Literal['ru', 'en', 'es', 'cn'] = None,
418                       ) -> dict | list:
419        response = await self.__send_request('getServicesList', params={
420            **({'country': str(country)} if country is not None else {}),
421            **({'lang': str(lang)} if lang is not None else {}),
422        })
423
424        if not is_json(response):
425            return response
426        
427        return json.loads(response)
428    
429    async def get_service_name(self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None):
430        """
431        RU  
432        Получение полного имени сервиса по его id  
433          
434        EN  
435        Get full service name by service code  
436            
437        Пример Example:  
438        service_name = await SmsActivate.get_service_name('go')  
439        service_name # 'Google,youtube,Gmail'
440        """
441        services = await self.get_service_list(lang=lang)
442        services = services.get('services')
443        for service in services:
444            if service['code'] == service_code:
445                return service['name']
446        return None
447    
448    async def get_additional_service(self, 
449                          service: str = None,
450                          id: str = None,
451                       ):
452        """
453        Get additional service to activation its cost 5rub
454        return 2 values: addition activation id and phone number
455        
456        use like this: 
457        activation_id, phone_number = await getAdditionalService(service, activation id)
458        """
459        response = await self.__send_request('getAdditionalService', params={
460            'service': service,
461            'id':id
462        })
463
464        data = response.split(':')
465        if len(data) > 2:
466            return data[1], data[2]
467        
468        return data
469    
470    async def get_extra_activation(self, 
471                          id: str = None,
472                       ):
473        """
474        return 2 values: addition activation id and phone number
475        
476        use like this: 
477        activation_id, phone_number = await getExtraActivation(activation id)
478        """
479        response = await self.__send_request('getExtraActivation', params={
480            'id':id
481        })
482
483        data = response.split(':')
484        if len(data) > 2:
485            return data[1], data[2]
486        
487        return data
488    
489    async def check_extra_activation(self, 
490                          activationId: str | int
491                       ) -> dict | list:
492        response = await self.__send_request('checkExtraActivation', params={
493            'activationId': str(activationId)
494        })
495
496        if not is_json(response):
497            return response
498        
499        return json.loads(response)
500    
501    async def parse_call(self, 
502                          id: str | int,
503                          newLang: str,
504                       ) -> dict | list:
505        response = await self.__send_request('parseCall', params={
506            "id": id,
507            "newLang": newLang,
508        })
509
510        if not is_json(response):
511            return response
512        
513        return json.loads(response)
514    
515    # !!! BOTTOM IT IS RENT API
516    async def get_rent_services_and_countries(self,
517                       time: int | str | None = None,
518                       operator: str | None = None,
519                       country: str | None = None,
520                       currency: str | None = None,
521                       incomingCall: bool | None = None,
522                       ) -> dict | str:
523        response = await self.__send_request('getRentServicesAndCountries', params={
524            **({'time ': str(time )} if time is not None else {}),
525            **({'operator ': str(operator )} if operator is not None else {}),
526            **({'country ': str(country )} if country is not None else {}),
527            **({'currency ': str(currency )} if currency is not None else {}),
528            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
529        })
530
531        if not is_json(response):
532            return response
533        
534        return json.loads(response)
535    
536    async def get_rent_number(self,
537                        service: str,
538                        time: int | str | None = None,
539                        operator: str | None = None,
540                        country: str | None = None,
541                        url: str | None = None,
542                        incomingCall: bool | None = None,
543                       ) -> dict | str:
544        response = await self.__send_request('getRentNumber', params={
545            'service': service,
546            **({'time ': str(time )} if time is not None else {}),
547            **({'operator ': str(operator )} if operator is not None else {}),
548            **({'country ': str(country )} if country is not None else {}),
549            **({'url ': str(url )} if url is not None else {}),
550            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
551        })
552
553        if not is_json(response):
554            return response
555        
556        return json.loads(response)
557    
558    async def get_rent_status(self,
559                        id: str,
560                        page: int | str | None = None,
561                        size: int | str | None = None,
562                       ) -> dict | str:
563        response = await self.__send_request('getRentStatus', params={
564            'id': id,
565            **({'page ': str(page)} if page is not None else {}),
566            **({'size ': str(size )} if size 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 set_rent_status(self,
575                        id: str,
576                        status: Literal[1, 2, '1', '2'],
577                       ) -> dict | str:
578        response = await self.__send_request('getRentStatus', params={
579            'id': str(id),
580            'status': str(status),
581        })
582
583        if not is_json(response):
584            return response
585        
586        return json.loads(response)
587    
588    async def get_rent_list(self,
589                       ) -> dict | str:
590        response = await self.__send_request('getRentList', params={
591        })
592
593        if not is_json(response):
594            return response
595        
596        return json.loads(response)
597    
598    async def continue_rent_number(self,
599                        id: str,
600                        rent_time: int | str | None = 4,
601                       ) -> dict | str:
602        response = await self.__send_request('continueRentNumber', params={
603            'id': id,
604            'rent_time': str(rent_time)
605        })
606
607        if not is_json(response):
608            return response
609        
610        return json.loads(response)
611    
612    async def get_continue_rent_price_number(self,
613                        id: str,
614                        rent_time: int | str | None = 4,
615                        currency: str | None = None
616                       ) -> dict | str:
617        response = await self.__send_request('getContinueRentPriceNumber', params={
618            'id': id,
619            'rent_time': str(rent_time),
620            **({'currency ': str(currency )} if currency is not None else {}),
621        })
622
623        if not is_json(response):
624            return response
625        
626        return json.loads(response)
627    
628    # !!! BOTTOM IS IT PARTNER SOFT API
629    async def buy_partner_product(self,
630                        id: str,
631                       ) -> dict | str:
632        response = await self.__send_request('buyPartnerProduct', params={
633            'id': id,
634        })
635
636        if not is_json(response):
637            return response
638        
639        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_prices(self, service: str = None, country: str = None) -> dict | list:
378    async def get_prices(self, 
379                          service: str = None,
380                          country: str = None,
381                       ) -> dict | list:
382        response = await self.__send_request('getPrices', params={
383            **({'service': str(service)} if service is not None else {}),
384            **({'country': str(country)} if country is not None else {}),
385        })
386
387        if not is_json(response):
388            return response
389        
390        return json.loads(response)
async def get_prices_verification(self, service: str = None) -> dict | list:
392    async def get_prices_verification(self, 
393                          service: str = None,
394                       ) -> dict | list:
395        response = await self.__send_request('getPricesVerification', params={
396            **({'service': str(service)} if service is not None else {}),
397        })
398
399        if not is_json(response):
400            return response
401        
402        return json.loads(response)
async def get_countries(self) -> dict | list:
404    async def get_countries(self,
405                       ) -> dict | list:
406        response = await self.__send_request('getCountries', params={
407        })
408
409        if not is_json(response):
410            return response
411        
412        return json.loads(response)
@cached(cache)
async def get_service_list( self, country: str = None, lang: Literal['ru', 'en', 'es', 'cn'] = None) -> dict | list:
414    @cached(cache)
415    async def get_service_list(self, 
416                          country: str = None,
417                          lang: Literal['ru', 'en', 'es', 'cn'] = None,
418                       ) -> dict | list:
419        response = await self.__send_request('getServicesList', params={
420            **({'country': str(country)} if country is not None else {}),
421            **({'lang': str(lang)} if lang is not None else {}),
422        })
423
424        if not is_json(response):
425            return response
426        
427        return json.loads(response)
async def get_service_name( self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None):
429    async def get_service_name(self, service_code: str, lang: Literal['ru', 'en', 'es', 'cn'] = None):
430        """
431        RU  
432        Получение полного имени сервиса по его id  
433          
434        EN  
435        Get full service name by service code  
436            
437        Пример Example:  
438        service_name = await SmsActivate.get_service_name('go')  
439        service_name # 'Google,youtube,Gmail'
440        """
441        services = await self.get_service_list(lang=lang)
442        services = services.get('services')
443        for service in services:
444            if service['code'] == service_code:
445                return service['name']
446        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):
448    async def get_additional_service(self, 
449                          service: str = None,
450                          id: str = None,
451                       ):
452        """
453        Get additional service to activation its cost 5rub
454        return 2 values: addition activation id and phone number
455        
456        use like this: 
457        activation_id, phone_number = await getAdditionalService(service, activation id)
458        """
459        response = await self.__send_request('getAdditionalService', params={
460            'service': service,
461            'id':id
462        })
463
464        data = response.split(':')
465        if len(data) > 2:
466            return data[1], data[2]
467        
468        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):
470    async def get_extra_activation(self, 
471                          id: str = None,
472                       ):
473        """
474        return 2 values: addition activation id and phone number
475        
476        use like this: 
477        activation_id, phone_number = await getExtraActivation(activation id)
478        """
479        response = await self.__send_request('getExtraActivation', params={
480            'id':id
481        })
482
483        data = response.split(':')
484        if len(data) > 2:
485            return data[1], data[2]
486        
487        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:
489    async def check_extra_activation(self, 
490                          activationId: str | int
491                       ) -> dict | list:
492        response = await self.__send_request('checkExtraActivation', params={
493            'activationId': str(activationId)
494        })
495
496        if not is_json(response):
497            return response
498        
499        return json.loads(response)
async def parse_call(self, id: str | int, newLang: str) -> dict | list:
501    async def parse_call(self, 
502                          id: str | int,
503                          newLang: str,
504                       ) -> dict | list:
505        response = await self.__send_request('parseCall', params={
506            "id": id,
507            "newLang": newLang,
508        })
509
510        if not is_json(response):
511            return response
512        
513        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:
516    async def get_rent_services_and_countries(self,
517                       time: int | str | None = None,
518                       operator: str | None = None,
519                       country: str | None = None,
520                       currency: str | None = None,
521                       incomingCall: bool | None = None,
522                       ) -> dict | str:
523        response = await self.__send_request('getRentServicesAndCountries', params={
524            **({'time ': str(time )} if time is not None else {}),
525            **({'operator ': str(operator )} if operator is not None else {}),
526            **({'country ': str(country )} if country is not None else {}),
527            **({'currency ': str(currency )} if currency is not None else {}),
528            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
529        })
530
531        if not is_json(response):
532            return response
533        
534        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:
536    async def get_rent_number(self,
537                        service: str,
538                        time: int | str | None = None,
539                        operator: str | None = None,
540                        country: str | None = None,
541                        url: str | None = None,
542                        incomingCall: bool | None = None,
543                       ) -> dict | str:
544        response = await self.__send_request('getRentNumber', params={
545            'service': service,
546            **({'time ': str(time )} if time is not None else {}),
547            **({'operator ': str(operator )} if operator is not None else {}),
548            **({'country ': str(country )} if country is not None else {}),
549            **({'url ': str(url )} if url is not None else {}),
550            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
551        })
552
553        if not is_json(response):
554            return response
555        
556        return json.loads(response)
async def get_rent_status( self, id: str, page: int | str | None = None, size: int | str | None = None) -> dict | str:
558    async def get_rent_status(self,
559                        id: str,
560                        page: int | str | None = None,
561                        size: int | str | None = None,
562                       ) -> dict | str:
563        response = await self.__send_request('getRentStatus', params={
564            'id': id,
565            **({'page ': str(page)} if page is not None else {}),
566            **({'size ': str(size )} if size is not None else {}),
567        })
568
569        if not is_json(response):
570            return response
571        
572        return json.loads(response)
async def set_rent_status(self, id: str, status: Literal[1, 2, '1', '2']) -> dict | str:
574    async def set_rent_status(self,
575                        id: str,
576                        status: Literal[1, 2, '1', '2'],
577                       ) -> dict | str:
578        response = await self.__send_request('getRentStatus', params={
579            'id': str(id),
580            'status': str(status),
581        })
582
583        if not is_json(response):
584            return response
585        
586        return json.loads(response)
async def get_rent_list(self) -> dict | str:
588    async def get_rent_list(self,
589                       ) -> dict | str:
590        response = await self.__send_request('getRentList', params={
591        })
592
593        if not is_json(response):
594            return response
595        
596        return json.loads(response)
async def continue_rent_number(self, id: str, rent_time: int | str | None = 4) -> dict | str:
598    async def continue_rent_number(self,
599                        id: str,
600                        rent_time: int | str | None = 4,
601                       ) -> dict | str:
602        response = await self.__send_request('continueRentNumber', params={
603            'id': id,
604            'rent_time': str(rent_time)
605        })
606
607        if not is_json(response):
608            return response
609        
610        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:
612    async def get_continue_rent_price_number(self,
613                        id: str,
614                        rent_time: int | str | None = 4,
615                        currency: str | None = None
616                       ) -> dict | str:
617        response = await self.__send_request('getContinueRentPriceNumber', params={
618            'id': id,
619            'rent_time': str(rent_time),
620            **({'currency ': str(currency )} if currency is not None else {}),
621        })
622
623        if not is_json(response):
624            return response
625        
626        return json.loads(response)
async def buy_partner_product(self, id: str) -> dict | str:
629    async def buy_partner_product(self,
630                        id: str,
631                       ) -> dict | str:
632        response = await self.__send_request('buyPartnerProduct', params={
633            'id': id,
634        })
635
636        if not is_json(response):
637            return response
638        
639        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 = None) -> dict | list:
378    async def get_prices(self, 
379                          service: str = None,
380                          country: str = None,
381                       ) -> dict | list:
382        response = await self.__send_request('getPrices', params={
383            **({'service': str(service)} if service is not None else {}),
384            **({'country': str(country)} if country is not None else {}),
385        })
386
387        if not is_json(response):
388            return response
389        
390        return json.loads(response)
async def getPricesVerification(self, service: str = None) -> dict | list:
392    async def get_prices_verification(self, 
393                          service: str = None,
394                       ) -> dict | list:
395        response = await self.__send_request('getPricesVerification', params={
396            **({'service': str(service)} if service is not None else {}),
397        })
398
399        if not is_json(response):
400            return response
401        
402        return json.loads(response)
async def getCountries(self) -> dict | list:
404    async def get_countries(self,
405                       ) -> dict | list:
406        response = await self.__send_request('getCountries', params={
407        })
408
409        if not is_json(response):
410            return response
411        
412        return json.loads(response)
@cached(cache)
async def getServicesList( self, country: str = None, lang: Literal['ru', 'en', 'es', 'cn'] = None) -> dict | list:
414    @cached(cache)
415    async def get_service_list(self, 
416                          country: str = None,
417                          lang: Literal['ru', 'en', 'es', 'cn'] = None,
418                       ) -> dict | list:
419        response = await self.__send_request('getServicesList', params={
420            **({'country': str(country)} if country is not None else {}),
421            **({'lang': str(lang)} if lang is not None else {}),
422        })
423
424        if not is_json(response):
425            return response
426        
427        return json.loads(response)
async def getAdditionalService(self, service: str = None, id: str = None):
448    async def get_additional_service(self, 
449                          service: str = None,
450                          id: str = None,
451                       ):
452        """
453        Get additional service to activation its cost 5rub
454        return 2 values: addition activation id and phone number
455        
456        use like this: 
457        activation_id, phone_number = await getAdditionalService(service, activation id)
458        """
459        response = await self.__send_request('getAdditionalService', params={
460            'service': service,
461            'id':id
462        })
463
464        data = response.split(':')
465        if len(data) > 2:
466            return data[1], data[2]
467        
468        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):
470    async def get_extra_activation(self, 
471                          id: str = None,
472                       ):
473        """
474        return 2 values: addition activation id and phone number
475        
476        use like this: 
477        activation_id, phone_number = await getExtraActivation(activation id)
478        """
479        response = await self.__send_request('getExtraActivation', params={
480            'id':id
481        })
482
483        data = response.split(':')
484        if len(data) > 2:
485            return data[1], data[2]
486        
487        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:
489    async def check_extra_activation(self, 
490                          activationId: str | int
491                       ) -> dict | list:
492        response = await self.__send_request('checkExtraActivation', params={
493            'activationId': str(activationId)
494        })
495
496        if not is_json(response):
497            return response
498        
499        return json.loads(response)
async def parseCall(self, id: str | int, newLang: str) -> dict | list:
501    async def parse_call(self, 
502                          id: str | int,
503                          newLang: str,
504                       ) -> dict | list:
505        response = await self.__send_request('parseCall', params={
506            "id": id,
507            "newLang": newLang,
508        })
509
510        if not is_json(response):
511            return response
512        
513        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:
516    async def get_rent_services_and_countries(self,
517                       time: int | str | None = None,
518                       operator: str | None = None,
519                       country: str | None = None,
520                       currency: str | None = None,
521                       incomingCall: bool | None = None,
522                       ) -> dict | str:
523        response = await self.__send_request('getRentServicesAndCountries', params={
524            **({'time ': str(time )} if time is not None else {}),
525            **({'operator ': str(operator )} if operator is not None else {}),
526            **({'country ': str(country )} if country is not None else {}),
527            **({'currency ': str(currency )} if currency is not None else {}),
528            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
529        })
530
531        if not is_json(response):
532            return response
533        
534        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:
536    async def get_rent_number(self,
537                        service: str,
538                        time: int | str | None = None,
539                        operator: str | None = None,
540                        country: str | None = None,
541                        url: str | None = None,
542                        incomingCall: bool | None = None,
543                       ) -> dict | str:
544        response = await self.__send_request('getRentNumber', params={
545            'service': service,
546            **({'time ': str(time )} if time is not None else {}),
547            **({'operator ': str(operator )} if operator is not None else {}),
548            **({'country ': str(country )} if country is not None else {}),
549            **({'url ': str(url )} if url is not None else {}),
550            **({'incomingCall': str(incomingCall).lower()} if incomingCall is not None else {}),
551        })
552
553        if not is_json(response):
554            return response
555        
556        return json.loads(response)
async def getRentStatus( self, id: str, page: int | str | None = None, size: int | str | None = None) -> dict | str:
558    async def get_rent_status(self,
559                        id: str,
560                        page: int | str | None = None,
561                        size: int | str | None = None,
562                       ) -> dict | str:
563        response = await self.__send_request('getRentStatus', params={
564            'id': id,
565            **({'page ': str(page)} if page is not None else {}),
566            **({'size ': str(size )} if size is not None else {}),
567        })
568
569        if not is_json(response):
570            return response
571        
572        return json.loads(response)
async def getRentList(self) -> dict | str:
588    async def get_rent_list(self,
589                       ) -> dict | str:
590        response = await self.__send_request('getRentList', params={
591        })
592
593        if not is_json(response):
594            return response
595        
596        return json.loads(response)
async def continueRentNumber(self, id: str, rent_time: int | str | None = 4) -> dict | str:
598    async def continue_rent_number(self,
599                        id: str,
600                        rent_time: int | str | None = 4,
601                       ) -> dict | str:
602        response = await self.__send_request('continueRentNumber', params={
603            'id': id,
604            'rent_time': str(rent_time)
605        })
606
607        if not is_json(response):
608            return response
609        
610        return json.loads(response)
async def getContinueRentPriceNumber( self, id: str, rent_time: int | str | None = 4, currency: str | None = None) -> dict | str:
612    async def get_continue_rent_price_number(self,
613                        id: str,
614                        rent_time: int | str | None = 4,
615                        currency: str | None = None
616                       ) -> dict | str:
617        response = await self.__send_request('getContinueRentPriceNumber', params={
618            'id': id,
619            'rent_time': str(rent_time),
620            **({'currency ': str(currency )} if currency is not None else {}),
621        })
622
623        if not is_json(response):
624            return response
625        
626        return json.loads(response)
async def buyPartnerProduct(self, id: str) -> dict | str:
629    async def buy_partner_product(self,
630                        id: str,
631                       ) -> dict | str:
632        response = await self.__send_request('buyPartnerProduct', params={
633            'id': id,
634        })
635
636        if not is_json(response):
637            return response
638        
639        return json.loads(response)