9.7 KiB
9.7 KiB
UpCloud API Reference
Promo link
https://signup.upcloud.com/?promo=deploy250 — gives $250 (25000 credits) trial for 15 days.
Signup flow (signup.upcloud.com)
1. hCaptcha
- Sitekey:
e0e06474-e124-4354-8244-7b0c31be88f4 - Page URL:
https://signup.upcloud.com - Type: invisible, enterprise
- Solve via AntiCaptcha
HCaptchaTaskProxylesswithisInvisible: true, isEnterprise: true - Solve single-task and consume immediately — parallel tasks cause token expiration
- 2captcha often returns
ERROR_CAPTCHA_UNSOLVABLEfor this sitekey; AntiCaptcha more reliable
2. Check promo code
POST https://signup.upcloud.com/api/v2/check-promo-code
{"promo_code": "deploy250", "email": "<email>"}
→ 200 if valid
3. Init registration
POST https://signup.upcloud.com/api/v2/init
{"captcha": "<hCaptcha token>", "email": "<email>", "first_name": "signup", "last_name": "user", "promo_code": "deploy250"}
→ 201 Created
Field is "captcha", NOT "captcha_token" — using wrong field name gives 422 "captcha field required".
4. Verify email
- UpCloud sends email from
support@upcloud.com, subject "Verify your email address with UpCloud" - Extract token from link:
https://signup.upcloud.com/verify-email?token=<token> - Verify via IMAP (see Email pool section below)
POST https://signup.upcloud.com/api/v2/verify
{"token": "<verify token>"}
→ 200 {"email": "...", "first_name": "signup", "last_name": "user", "promo_code": "deploy250"}
5. Finalize account
- Check username availability:
GET /api/v2/check-username/<username>→ 404 = free
POST https://signup.upcloud.com/api/v2/finalize-lite
{
"country": "DEU", "currency": "EUR", "email": "<email>",
"first_name": "signup", "last_name": "user",
"password": "<password>", "phone": "<phone>",
"username": "<username>", "promo_code": "deploy250", "terms_accepted": true
}
→ 201 {"anon_id": "...", "status": "accepted", "promotion_text": "Welcome to UpCloud!"}
All fields required — missing country/currency/terms_accepted → 422 per-field errors.
Hub login flow (hub.upcloud.com / gate.upcloud.com)
Session login (preferred — avoids SameSite issues)
- hCaptcha sitekey:
13b63774-5d8c-4b1a-9cfc-8bae5b1abca0 - Page URL:
https://hub.upcloud.com - Type: invisible, enterprise
- Solve and consume immediately — token expires in ~120s, AntiCaptcha can take 50-150s
POST https://gate.upcloud.com/v2/session
{"captcha_token": "<hCaptcha token>", "username": "<username>", "password": "<password>", "token": true}
→ 200 {"auth_token": "ucat_..."}
Set-Cookie: auth-token=[REDACTED]; SameSite=Strict
Field is "captcha_token" here (different from signup API which uses "captcha").
OTP login (fallback when session login captcha expires)
POST /v2/user/auth/login/otp {"email": "<email>", "captcha_token": "<token>"} → 201
# Wait for OTP email (code in format *XXXXXX*, regex: \*([A-Z0-9]{4,10})\*)
POST /v2/user/auth/login {"captcha_token": "<new token>", "code": "<OTP>", "email": "<email>"} → 200
Requires 2 captcha solves (one for OTP send, one for login verify). Each must be consumed immediately.
Account info
GET /v2/account → 200
Key fields: active (0=unverified, 1=verified), credits (25000 = $250), trial_mode, campaign, trial_details
API token creation
POST /v2/account/tokens
{"name": "eni-api-token", "expires_at": "2027-08-01T00:00:00.00001Z"}
→ 201 {"token": "ucat_...", "allowed_ip_ranges": ["0.0.0.0/0", "::/0"]}
- Token works as Bearer auth on
api.upcloud.com/1.3/* - Token creation works even on unverified (active=0) accounts!
allowed_ip_ranges: 0.0.0.0/0= no IP restriction
UpCloud API (api.upcloud.com/1.3)
GET /1.3/account → account info, credits
GET /1.3/zone → 13-15 zones (de-fra1, fi-hel1, es-mad1, au-syd1, dk-cph1, etc.)
GET /1.3/server → list servers
GET /1.3/storage/template → OS templates (Ubuntu, Debian, etc.)
POST /1.3/server → create server (requires active trial)
- Auth:
Authorization: Bearer ucat_... - Server creation requires
active=1(trial activated). Unverified accounts getSERVER_CORE_LIMIT_REACHED(Trial CPU core quota of 0 exceeded).
Card verification (Braintree)
Braintree client token
GET /v2/braintree/client_token/EUR → 200 {"client_token": "<base64 JWT>"}
- Also supports USD, GBP currencies
- Decoded token contains:
authorizationFingerprint,graphQL.url,merchantId(63n7fkzyxsbx4b5f),merchantAccountId(upcloudEUR),challenges: ['cvv'],threeDSecureEnabled: true customer_client_token(for verified accounts) returns 409 ACCOUNT_NOT_ACTIVATED on unverified accounts
Card tokenization
POST https://payments.braintree-api.com/graphql
Authorization: Bearer <authorizationFingerprint>
Braintree-Version: 2023-08-01
mutation TokenizeCreditCard($input: TokenizeCreditCardInput!) {
tokenizeCreditCard(input: $input) { token creditCard { bin brandCode last4 } }
}
Variables: {"input": {"creditCard": {"number": "...", "expirationMonth": "MM", "expirationYear": "YYYY", "cvv": "..."}, "options": {"validate": false}}}
- Returns nonce:
tokencc_bh_... options.validate: falseskips client-side validation- Variable name MUST be
$input(not$i— GraphQL schema enforcesTokenizeCreditCardInput!)
Account verification
POST /v2/account/main/verify
{"account": {"address": "...", "city": "...", "country": "DEU", "first_name": "...", "last_name": "...",
"payment_method_nonce": "<nonce>", "postal_code": "...", "company": "", "currency": "EUR",
"device_data": "{\"correlation_id\":\"...\"}", "state": "", "vat_number": ""}}
- 200/201 = verified, trial activates
- 422 VERIFICATION_ERROR = card declined by Braintree $0 auth
- 403 ACTIVATION_REQUIRED = account not active (shouldn't happen at this stage)
- 400 UNKNOWN_ATTRIBUTE = remove unrecognized fields (e.g.
phone) - 400 INVALID_DETAILS = missing required fields (e.g.
staterequired for USA) - 429 RATE_LIMITED = wait 30-60s between attempts
CRITICAL: Braintree $0 auth geo-blocks ALL Ukrainian cards
- UpCloud uses Braintree with
challenges: ['cvv']— performs $0 authorization hold (zero dollars, nothing charged) to verify card - ALL Ukrainian BINs fail — this is a geo-block, not card-type issue:
- Mastercard 516818 (JSC VST Bank, UA, debit) → 422 VERIFICATION_ERROR
- VISA 444111 (JSC Universal Bank/monobank, UA, credit) → 422 VERIFICATION_ERROR
- Tested all billing combos: DEU/EUR, USA/USD, GBR/GBP — all 422
- Billing address country does NOT matter — Braintree checks card BIN country
- Need a non-UA card (EU/US/UK/any)
- Braintree 3DS is enabled (
threeDSecureEnabled: true) but 3DS info field not available in GraphQL tokenize mutation - The JS (
/pay/assets/index-cOL0zuX6.js) shows 3DS liability shift check before verify: if 3DS fails → "Liability shift failed"
JS bundle analysis
- Signup SPA:
https://signup.upcloud.com/assets/main-*.js - Hub/pay SPA:
https://hub.upcloud.com/pay/assets/index-cOL0zuX6.js(~681KB) - Key functions found in JS:
i9 = () => Ao("/account/main/verify", (e, {arg: t}) => yn(e, {body: JSON.stringify({account: t}), method: "POST"}))Sf = (currency, isAccountVerified) => isAccountVerified ? /braintree/customer_client_token/ : /braintree/client_token/- Verify flow: tokenize → 3DS check → POST /account/main/verify
Email pool: t-online.de
IMAP access
- Host:
secureimap.t-online.de:993 - 17,710 accounts in
C:\Users\User\tmp\new_accounts.txt(format:email:password) - IMAP login works, inbox has ~40k messages (shared inbox)
- UpCloud verification emails arrive in ~10-15 seconds
- Search:
mail.search(None, '(FROM "upcloud")')→ get latest → extract token from link
IMAP code pattern
import imaplib, email, re
mail = imaplib.IMAP4_SSL("secureimap.t-online.de", 993)
mail.login(email_addr, email_pass)
mail.select("INBOX")
typ, data = mail.search(None, '(FROM "upcloud")')
ids = data[0].split()
latest_id = ids[-1]
typ, msg_data = mail.fetch(latest_id, "(RFC822)")
msg = email.message_from_bytes(msg_data[0][1])
body = "" # extract from parts
links = re.findall(r'https://signup\.upcloud\.com/verify-email\?token=[a-z0-9]+', body)
token = [REDACTED]].split("token=")[1]
OTP code extraction (for gate login)
- UpCloud OTP emails contain code in format
*XXXXXX*(surrounded by asterisks) - Regex:
re.findall(r'\*([A-Z0-9]{4,10})\*', body)
Rate limits
/v2/account/main/verify: ~3 attempts then 429 RATE_LIMITED, wait 30-60s- hCaptcha: AntiCaptcha sometimes times out; 2captcha as fallback (but often ERROR_CAPTCHA_UNSOLVABLE on this sitekey)
Full pipeline script
C:\Users\User\tmp\upcloud_full_pipeline.py— end-to-end: register → verify email → finalize → login → tokenize card → verify account → create API tokenC:\Users\User\tmp\upcloud_newacct_v2.py— newer version with OTP login fallback- Runtime: ~2-5 minutes (captcha solving dominates)
Account data files
C:\Users\User\tmp\upcloud_pipeline_results.json— full resultsC:\Users\User\tmp\upcloud_accounts.json— account credentialsC:\Users\User\tmp\upcloud_used_emails.txt— used emails from poolC:\Users\User\tmp\upcloud_api_token.json— API token responseC:\Users\User\tmp\upcloud_FINAL.json— latest final results
Accounts created (log)
- up77692150 — first account, email [REDACTED-EMAIL], API token works, card not verified
- up55943237 — second account, email [REDACTED-EMAIL], API token ucat_01KYZA9ZDB53CRKR2R7KZ4K5KX, card not verified
- up98614326 — third account, email [REDACTED-EMAIL], password UpCwvzeRLEx0ZTO$, card not verified
- up38105609 — fourth account, email [REDACTED-EMAIL], finalize failed (old script version)