Python SDK
Official Python library for MyDisct Solver - Enterprise AI-Powered Captcha Solving Service with 21+ token types and 25+ image types. Full TypedDict support for type safety.
The MyDisct Solver Python SDK provides a Pythonic interface for solving all types of captchas. It handles task creation, polling, and result retrieval automatically. Perfect for web scraping, automation, testing, and any Python application that needs captcha solving capabilities.
Installation
pip install mydisct-solver
Requirements: Python 3.7+
Quick Start
from mydisct_solver import MyDisctSolver
# Initialize solver with your API key
solver = MyDisctSolver('YOUR_API_KEY')
# Solve reCAPTCHA v2
token = solver.recaptchaV2Token({
'siteUrl': 'https://example.com',
'siteKey': '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-'
})
print('Token:', token)
Type-Safe Usage with TypedDict
from mydisct_solver import MyDisctSolver, RecaptchaV2Options
solver = MyDisctSolver('YOUR_API_KEY')
options: RecaptchaV2Options = {
'siteUrl': 'https://example.com',
'siteKey': '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'invisible': False
}
token: str = solver.recaptchaV2Token(options)
Initialization
Constructor
solver = MyDisctSolver(apiKey, baseURL=None)
| Parameter | Type | Required | Description |
|---|---|---|---|
apiKey |
str | required | Your MyDisct Solver API key |
baseURL |
str | optional | Custom API base URL (default: https://solver-api.mydisct.com) |
Example with Custom Base URL
solver = MyDisctSolver(
'YOUR_API_KEY',
'https://custom-api.mydisct.com'
)
Token-Based Captchas (21 Types)
Token-based captchas return a verification token that you submit with your form or API request. All methods use Python dictionaries for options and return strings.
Complete Token Methods Reference
| Method | Captcha Type | Required Parameters |
|---|---|---|
recaptchaV2Token() |
Google reCAPTCHA v2 | siteUrl, siteKey |
recaptchaV3Token() |
Google reCAPTCHA v3 | siteUrl, siteKey |
recaptchaV2EnterpriseToken() |
reCAPTCHA v2 Enterprise | siteUrl, siteKey |
recaptchaV3EnterpriseToken() |
reCAPTCHA v3 Enterprise | siteUrl, siteKey |
hCaptchaToken() |
hCaptcha | siteUrl, siteKey |
hCaptchaEnterpriseToken() |
hCaptcha Enterprise | siteUrl, siteKey |
cloudflareTurnstileToken() |
Cloudflare Turnstile | siteUrl, siteKey |
cloudflareTurnstileManagedToken() |
Cloudflare Turnstile Managed | siteUrl, siteKey, data, chlPageData |
cloudflareChallengeToken() |
Cloudflare Challenge | siteUrl, proxy |
funCaptchaToken() |
FunCaptcha (Arkose Labs) | siteUrl, siteKey |
geeTestV4Token() |
GeeTest v4 | siteUrl, siteKey, proxy |
mtCaptchaToken() |
MTCaptcha | siteUrl, siteKey |
leminCaptchaToken() |
Lemin CAPTCHA | siteUrl, siteKey |
friendlyCaptchaToken() |
Friendly Captcha | siteUrl, siteKey |
dataDomeToken() |
DataDome | siteUrl, siteKey, proxy |
altchaCaptchaToken() |
Altcha | siteUrl, challenge, iterations, salt, signature |
tencentCaptchaToken() |
Tencent Captcha | siteUrl, siteKey |
netEaseCaptchaToken() |
NetEase Captcha | siteUrl, siteKey |
faucetPayCaptchaToken() |
FaucetPay Captcha | siteUrl, siteKey |
captchaFoxToken() |
CaptchaFox | siteUrl, siteKey |
awsCaptchaToken() |
AWS WAF Captcha | siteUrl, siteKey |
recaptchaV2Token()
Solve Google reCAPTCHA v2 checkbox and invisible captchas.
token = solver.recaptchaV2Token({
'siteUrl': 'https://example.com',
'siteKey': '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'invisible': False, # optional
'userAgent': 'Mozilla/5.0...', # optional
'cookies': [{'name': 'session', 'value': 'abc', 'domain': '.example.com'}], # optional
'domain': 'google.com', # optional
'proxy': {'protocol': 'http', 'host': '1.2.3.4', 'port': 8080} # optional
})
recaptchaV3Token()
Solve Google reCAPTCHA v3 score-based captchas.
token = solver.recaptchaV3Token({
'siteUrl': 'https://example.com',
'siteKey': '6LdO5_IbAAAAAAeVBL9TClS19NUTt5wswEb3Q7m5',
'recaptchaAction': 'submit', # optional, default: 'verify'
'userAgent': 'Mozilla/5.0...', # optional
'proxy': {} # optional
})
hCaptchaToken()
Solve standard hCaptcha challenges.
token = solver.hCaptchaToken({
'siteUrl': 'https://example.com',
'siteKey': 'a5f74b19-9e45-40e0-b45d-47ff91b7a6c2',
'invisible': False, # optional
'rqdata': 'custom_rqdata', # optional
'userAgent': 'Mozilla/5.0...', # optional
'proxy': {} # optional
})
hCaptchaEnterpriseToken()
Solve hCaptcha Enterprise (e.g., Discord, Epic Games).
token = solver.hCaptchaEnterpriseToken({
'siteUrl': 'https://discord.com/register',
'siteKey': 'f5561ba9-8f1e-40ca-9b5b-a0b3f719ef34',
'domain': 'discord.com', # optional
'rqdata': 'custom_rqdata', # optional
'userAgent': 'Mozilla/5.0...', # optional
'cookies': [{'name': '__dcfduid', 'value': '...', 'domain': '.discord.com'}], # optional
'proxy': {} # optional
})
cloudflareTurnstileToken()
Solve Cloudflare Turnstile challenges.
token = solver.cloudflareTurnstileToken({
'siteUrl': 'https://example.com',
'siteKey': '0x4AAAAAAAC3DHQFLr1GavRN',
'proxy': {} # optional
})
Additional Token Methods: recaptchaV2EnterpriseToken(), recaptchaV3EnterpriseToken(), cloudflareTurnstileManagedToken(), cloudflareChallengeToken(), funCaptchaToken(), geeTestV4Token(), mtCaptchaToken(), leminCaptchaToken(), friendlyCaptchaToken(), dataDomeToken(), altchaCaptchaToken(), tencentCaptchaToken(), netEaseCaptchaToken(), faucetPayCaptchaToken(), captchaFoxToken(), awsCaptchaToken()
All token methods follow the same pattern. Check the TypedDict definitions for complete parameter details.
Image-Based Captchas (25 Types)
Image-based captchas require you to provide the captcha image(s) as base64-encoded strings. The SDK will analyze the images and return the solution.
Complete Image Methods Reference
| Method | Captcha Type | Required Parameters |
|---|---|---|
textCaptchaImage() |
Text Recognition (OCR) | siteUrl, images |
recaptchaImage() |
reCAPTCHA Image Grid | siteUrl, images, question, questionType |
hCaptchaImage() |
hCaptcha Image | siteUrl, images, question |
funCaptchaImage() |
FunCaptcha Image | siteUrl, images, question |
geeTestV3Image() |
GeeTest v3 Image | siteUrl, images, question |
geeTestV4Image() |
GeeTest v4 Image | siteUrl, images, question |
tikTokImage() |
TikTok Captcha | siteUrl, images, question |
rotateImage() |
Rotate Image | siteUrl, images |
slideCaptchaImage() |
Slide Puzzle | siteUrl, images |
clickCaptchaImage() |
Click Captcha | siteUrl, images, question |
gridCaptchaImage() |
Grid Selection | siteUrl, images, question |
multiSelectImage() |
Multi-Select | siteUrl, images, question |
dragCaptchaImage() |
Drag Captcha | siteUrl, images, question |
mtCaptchaImage() |
MTCaptcha Image | siteUrl, images |
leminCaptchaImage() |
Lemin Image | siteUrl, images, question |
dataDomeCaptchaImage() |
DataDome Image | siteUrl, images |
captchaFoxImage() |
CaptchaFox Image | siteUrl, images, question |
binanceImage() |
Binance Puzzle | siteUrl, images, question, questionType |
blsImage() |
BLS Captcha | siteUrl, images, question |
shopeeImage() |
Shopee Puzzle | siteUrl, images, question |
temuCaptchaImage() |
Temu Captcha | siteUrl, images |
tencentImage() |
Tencent Image | siteUrl, images, question |
awsWAFImage() |
AWS WAF Image | siteUrl, images, question |
prosopoImage() |
Prosopo Image | siteUrl, images, question |
faucetPayImage() |
FaucetPay Image | siteUrl, images, question |
textCaptchaImage()
Solve text-based image captchas (OCR).
import base64
# Read and encode image
with open('captcha.png', 'rb') as f:
image_base64 = base64.b64encode(f.read()).decode('utf-8')
solution = solver.textCaptchaImage({
'siteUrl': 'https://example.com',
'images': [f'data:image/png;base64,{image_base64}'],
'questionType': 'text', # optional
'caseSensitive': False, # optional
'numeric': False, # optional
'minLength': 4, # optional
'maxLength': 6, # optional
'referenceImages': [] # optional
})
print('Captcha text:', solution)
recaptchaImage()
Solve reCAPTCHA image grid challenges.
solution = solver.recaptchaImage({
'siteUrl': 'https://example.com',
'images': [
'data:image/png;base64,iVBORw0KGgoAAAANS...',
'data:image/png;base64,iVBORw0KGgoAAAANS...',
# ... 9 images for 3x3 grid
],
'question': 'Select all images with traffic lights',
'questionType': 'grid_3x3'
})
print('Selected indices:', solution)
rotateImage()
Solve rotate image captchas.
angle = solver.rotateImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,iVBORw0KGgoAAAANS...'],
'question': 'Rotate the image to the correct orientation', # optional
'angle': 90, # optional
'referenceImages': [] # optional
})
print('Rotation angle:', angle)
slideCaptchaImage()
Solve slide puzzle captchas.
position = solver.slideCaptchaImage({
'siteUrl': 'https://example.com',
'images': [
'data:image/png;base64,...', # Background image
'data:image/png;base64,...' # Slider piece
],
'question': 'Slide to complete the puzzle' # optional
})
print('Slide position:', position)
funCaptchaImage()
Solve FunCaptcha image puzzles.
solution = solver.funCaptchaImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Use the arrows to rotate the animal'
})
print('Solution:', solution)
geeTestV3Image()
Solve GeeTest v3 image slide puzzles.
solution = solver.geeTestV3Image({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...', 'data:image/png;base64,...'],
'question': 'Slide to complete the puzzle'
})
print('Slide distance:', solution)
geeTestV4Image()
Solve GeeTest v4 image challenges.
solution = solver.geeTestV4Image({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Click on the object'
})
print('Solution:', solution)
tikTokImage()
Solve TikTok image puzzles.
solution = solver.tikTokImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Rotate the object to match'
})
print('Solution:', solution)
clickCaptchaImage()
Solve click-based captchas (click specific points).
coordinates = solver.clickCaptchaImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Click on all traffic lights',
'questionType': 'click', # optional
'referenceImages': [] # optional
})
print('Click coordinates:', coordinates)
gridCaptchaImage()
Solve grid-based image selection captchas.
solution = solver.gridCaptchaImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Select all squares with traffic lights',
'rows': 3, # optional
'columns': 3 # optional
})
print('Selected cells:', solution)
multiSelectImage()
Solve multiple image selection captchas.
solution = solver.multiSelectImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...', 'data:image/png;base64,...'],
'question': 'Select all images containing a cat',
'referenceImages': [] # optional
})
print('Selected indices:', solution)
dragCaptchaImage()
Solve drag-based captchas.
solution = solver.dragCaptchaImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Drag the slider to complete',
'questionType': 'drag', # optional
'referenceImages': [] # optional
})
print('Drag position:', solution)
mtCaptchaImage()
Solve MTCaptcha image challenges.
solution = solver.mtCaptchaImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'module': 'mtcaptcha', # optional
'maxLength': 5 # optional
})
print('Captcha text:', solution)
leminCaptchaImage()
Solve Lemin CAPTCHA image challenges.
solution = solver.leminCaptchaImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Select the correct image'
})
print('Solution:', solution)
dataDomeCaptchaImage()
Solve DataDome image challenges.
solution = solver.dataDomeCaptchaImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Slide to verify' # optional
})
print('Solution:', solution)
captchaFoxImage()
Solve CaptchaFox image puzzles.
solution = solver.captchaFoxImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Select matching images',
'questionType': 'select', # optional
'referenceImages': [] # optional
})
print('Solution:', solution)
binanceImage()
Solve Binance puzzle captchas.
solution = solver.binanceImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Slide to complete the puzzle',
'questionType': 'slide',
'referenceImages': [] # optional
})
print('Slide position:', solution)
blsImage()
Solve BLS image captchas.
solution = solver.blsImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Select the correct image'
})
print('Solution:', solution)
shopeeImage()
Solve Shopee image puzzles.
solution = solver.shopeeImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Slide to complete'
})
print('Slide position:', solution)
temuCaptchaImage()
Solve Temu puzzle captchas.
solution = solver.temuCaptchaImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...']
})
print('Solution:', solution)
tencentImage()
Solve Tencent image challenges.
solution = solver.tencentImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Slide to verify'
})
print('Solution:', solution)
awsWAFImage()
Solve AWS WAF image challenges.
solution = solver.awsWAFImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Select all matching images'
})
print('Solution:', solution)
prosopoImage()
Solve Prosopo image challenges.
solution = solver.prosopoImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Select the correct image'
})
print('Solution:', solution)
faucetPayImage()
Solve FaucetPay image puzzles.
solution = solver.faucetPayImage({
'siteUrl': 'https://example.com',
'images': ['data:image/png;base64,...'],
'question': 'Select matching images'
})
print('Solution:', solution)
Account Methods
getBalance()
Get your current account balance.
balance = solver.getBalance()
print(f'Current balance: $' + str(balance) + ' USD')
getAccountInfo()
Get detailed account information.
account = solver.getAccountInfo()
print('Email:', account['email'])
print('Username:', account['username'])
print('Balance:', account['balance'], account['currency'])
Advanced Features
Proxy Support
Use proxies for captcha solving to match your target website's requirements.
token = solver.recaptchaV2Token({
'siteUrl': 'https://example.com',
'siteKey': '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'proxy': {
'protocol': 'http', # 'http', 'https', 'socks4', 'socks5'
'host': '1.2.3.4',
'port': 8080,
'username': 'proxyuser', # optional
'password': 'proxypass' # optional
}
})
UserAgent & Cookies
Provide browser fingerprint data for better success rates.
token = solver.hCaptchaEnterpriseToken({
'siteUrl': 'https://discord.com/register',
'siteKey': 'f5561ba9-8f1e-40ca-9b5b-a0b3f719ef34',
'userAgent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'cookies': [
{
'name': '__dcfduid',
'value': '7a2b3c4d5e6f7a8b',
'domain': '.discord.com',
'path': '/'
},
{
'name': '__sdcfduid',
'value': '9b1c2d3e4f5a6b7c',
'domain': '.discord.com',
'path': '/'
}
]
})
Error Handling
Properly handle errors and failed tasks.
try:
token = solver.recaptchaV2Token({
'siteUrl': 'https://example.com',
'siteKey': '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-'
})
print('Success! Token:', token)
except Exception as error:
print('Captcha solving failed:', str(error))
# Handle specific errors
if 'insufficient balance' in str(error).lower():
print('Please add funds to your account')
elif 'timeout' in str(error).lower():
print('Task took too long, try again')
elif 'invalid site key' in str(error).lower():
print('Check your site key')
Complete Examples
Login Automation with reCAPTCHA
from mydisct_solver import MyDisctSolver
import requests
solver = MyDisctSolver('YOUR_API_KEY')
def login_with_captcha():
try:
# Step 1: Solve captcha
print('Solving reCAPTCHA...')
captcha_token = solver.recaptchaV2Token({
'siteUrl': 'https://example.com/login',
'siteKey': '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'userAgent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
})
print('Captcha solved!')
# Step 2: Submit login form
response = requests.post('https://example.com/api/login', json={
'username': 'myusername',
'password': 'mypassword',
'g-recaptcha-response': captcha_token
})
print('Login successful!')
print('Auth token:', response.json()['token'])
return response.json()
except Exception as error:
print('Login failed:', str(error))
raise
if __name__ == '__main__':
login_with_captcha()
Batch Processing Multiple Captchas
from mydisct_solver import MyDisctSolver
from concurrent.futures import ThreadPoolExecutor, as_completed
solver = MyDisctSolver('YOUR_API_KEY')
def solve_batch_captchas():
tasks = [
{
'name': 'Login Page',
'solve': lambda: solver.recaptchaV2Token({
'siteUrl': 'https://example.com/login',
'siteKey': '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-'
})
},
{
'name': 'Registration',
'solve': lambda: solver.recaptchaV3Token({
'siteUrl': 'https://example.com/register',
'siteKey': '6LdyC2cUAAAAACGuDKpXeDorzUDWXmdqeg-xy696',
'recaptchaAction': 'register'
})
},
{
'name': 'Contact Form',
'solve': lambda: solver.hCaptchaToken({
'siteUrl': 'https://example.com/contact',
'siteKey': 'a5f74b19-9e45-40e0-b45d-47ff91b7a6c2'
})
}
]
# Solve all captchas in parallel
with ThreadPoolExecutor(max_workers=3) as executor:
futures = {executor.submit(task['solve']): task for task in tasks}
for future in as_completed(futures):
task = futures[future]
try:
token = future.result()
print("✓ " + task['name'] + ": " + token[:40] + "...")
except Exception as error:
print("✗ " + task['name'] + ": " + str(error))
if __name__ == '__main__':
solve_batch_captchas()
Selenium Integration
from mydisct_solver import MyDisctSolver
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
solver = MyDisctSolver('YOUR_API_KEY')
def automate_with_selenium():
driver = webdriver.Chrome()
try:
# Navigate to page
driver.get('https://example.com/login')
# Extract site key
site_key = driver.find_element(By.CSS_SELECTOR, '[data-sitekey]').get_attribute('data-sitekey')
print('Site key:', site_key)
# Solve captcha
print('Solving captcha...')
token = solver.recaptchaV2Token({
'siteUrl': driver.current_url,
'siteKey': site_key,
'userAgent': driver.execute_script('return navigator.userAgent')
})
print('Captcha solved!')
# Inject token into page
driver.execute_script(f'''
document.querySelector('[name="g-recaptcha-response"]').value = "{token}";
document.querySelector('textarea[name="g-recaptcha-response"]').style.display = "block";
''')
# Fill form and submit
driver.find_element(By.ID, 'username').send_keys('myusername')
driver.find_element(By.ID, 'password').send_keys('mypassword')
driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()
# Wait for navigation
WebDriverWait(driver, 10).until(
EC.url_changes(driver.current_url)
)
print('Login successful!')
print('Current URL:', driver.current_url)
except Exception as error:
print('Error:', str(error))
finally:
driver.quit()
if __name__ == '__main__':
automate_with_selenium()
Type Safety with TypedDict
The SDK includes TypedDict definitions for type safety and IDE autocomplete support.
Type Definitions
from mydisct_solver import (
MyDisctSolver,
RecaptchaV2Options,
RecaptchaV3Options,
HCaptchaOptions,
ProxyConfig,
Cookie
)
solver = MyDisctSolver('YOUR_API_KEY')
# Type-safe options
options: RecaptchaV2Options = {
'siteUrl': 'https://example.com',
'siteKey': '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'invisible': False,
'userAgent': 'Mozilla/5.0...',
'cookies': [
{
'name': 'session',
'value': 'abc123',
'domain': '.example.com',
'path': '/'
}
],
'proxy': {
'protocol': 'http',
'host': '1.2.3.4',
'port': 8080,
'username': 'user',
'password': 'pass'
}
}
# Type-safe return value
token: str = solver.recaptchaV2Token(options)
Available Types
# Core types
from mydisct_solver import (
ProxyConfig,
Cookie,
TaskResponse,
AccountInfo,
# Token captcha options
RecaptchaV2Options,
RecaptchaV3Options,
RecaptchaV2EnterpriseOptions,
RecaptchaV3EnterpriseOptions,
HCaptchaOptions,
HCaptchaEnterpriseOptions,
CloudflareTurnstileOptions,
CloudflareTurnstileManagedOptions,
CloudflareChallengeOptions,
FunCaptchaOptions,
GeeTestV4Options,
MTCaptchaOptions,
LeminCaptchaOptions,
FriendlyCaptchaOptions,
DataDomeOptions,
AltchaOptions,
TencentCaptchaOptions,
NetEaseCaptchaOptions,
FaucetPayCaptchaOptions,
CaptchaFoxOptions,
AWSCaptchaOptions,
# Image captcha options
TextCaptchaImageOptions,
RecaptchaImageOptions,
HCaptchaImageOptions,
FunCaptchaImageOptions,
GeeTestV3ImageOptions,
GeeTestV4ImageOptions,
RotateImageOptions,
SlideCaptchaImageOptions,
ClickCaptchaImageOptions,
GridCaptchaImageOptions,
MultiSelectImageOptions,
DragCaptchaImageOptions,
# ... and more
)
Best Practices
- Always check balance before starting batch operations
- Use try-except blocks to handle errors gracefully
- Provide userAgent for better success rates on token captchas
- Use proxies when the target site requires specific geolocation
- Cache tokens briefly if making multiple requests (tokens expire after ~2 minutes)
- Implement retry logic for failed tasks with exponential backoff
- Monitor your usage with getBalance() and getAccountInfo()
- Use TypedDict for better development experience and type safety
- Use ThreadPoolExecutor for parallel captcha solving
Troubleshooting
Common Issues
Solution: Ensure you're passing your API key to the constructor.
Solution: Verify the siteKey and siteUrl are correct. The URL must match exactly where the captcha appears.
Solution: Some captchas take longer. The SDK waits up to 2 minutes by default. This is normal for complex captchas.
Solution: Add funds to your account at solver.mydisct.com
Solution: Ensure you have Python 3.7+ and the package is installed: pip install mydisct-solver