Files

11 KiB
Raw Permalink Blame History

name, description, category, tags, triggers
name description category tags triggers
nodeloc-free-domain Register free 10-year domains on domain.nodeloc.com via API - account creation, domain ordering, coupon application, payment. automation
nodeloc
domain
free
api
automation
loc.cc
email
free domain nodeloc
domain.nodeloc.com
loc.cc domain
FREEJUL promo

Nodeloc Free Domain Registration

Register free .loc.cc (and .rr.kg) domains for 10 years on domain.nodeloc.com using the promo code FREEJUL.

Overview

  • Platform: https://domain.nodeloc.com
  • Root domains: loc.cc (ID=1), rr.kg (ID=5)
  • Price: 100 NL/year, 1000 NL lifetime
  • Promo: FREEJUL - 100% discount, one use per account. EXPIRED 2026-07-16T16:00:00Z — returns "Coupon has expired". No replacement found. Without coupon: 1000 NL (platform currency).
  • Quota: 2 domains per free account (normal level)
  • NS: ns1.nodelook.com, ns2.nodelook.com
  • DNS: PowerDNS backend, managed via web UI (DaisyUI comboboxes)

API Flow

1. Register Account

Password registration is disabled on the web UI, but the API accepts it.

curl -s 'https://domain.nodeloc.com/api/auth/register' -X POST \
  -H 'Content-Type: application/json' \
  -d '{"username":"USERNAME","email":"EMAIL","password":"PASSWORD"}'
# {"message":"success.user_created","user":{...}}

Email must be unique. Username must be unique. No email verification required for domain registration.

2. Login

curl -s 'https://domain.nodeloc.com/api/auth/login' -X POST \
  -H 'Content-Type: application/json' \
  -d '{"email":"EMAIL","password":"PASSWORD"}'
# {"message":"success.login","token":"eyJ...","user":{...}}

3. Create Order

CRITICAL — auth header must be lowercase authorization: tokenized endpoints (/api/domains, /api/orders, /api/user/profile) return {"error":"error.unauthorized"} with the standard Authorization: Bearer header but work with lowercase authorization: Bearer *** Always use lowercase in curl (-H "authorization: Bearer $TOKEN"`).

TOKEN="..."
curl -s 'https://domain.nodeloc.com/api/orders' -X POST \
  -H "authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"subdomain":"SUBDOMAIN","root_domain_id":1,"years":10,"coupon_code":"FREEJUL"}'
# {"message":"Order created successfully","order":{...}}

Critical: field names are snake_case - subdomain, root_domain_id, years, coupon_code. The Go backend error messages use PascalCase but the JSON must be snake_case.

4. Pay (Free Order)

curl -s "https://domain.nodeloc.com/api/payments/$ORDER_ID/complete-free" -X POST \
  -H "authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{}'
# {"message":"Free order completed successfully","order_id":6707}

Post-coupon state (live 2026-10-08): with FREEJUL dead, complete-free on a loc.cc order returns {"error":"This order requires payment"}. POST /api/payments/{order_id}/initiate then returns {"payment_id":N,"redirect_url":"https://www.nodeloc.com/payment/pay/txn_..."} — a real NL payment page, not automatable for free. However, some root domains (e.g. nl8.eu, root_domain_id=2) still registered end-to-end without a payment step (live: reform.nl8.eu created, id 8373, MX/SPF set via DNS API) — check /api/public/root-domains + /api/orders/calculate per TLD before assuming everything is paywalled.

5. Verify

curl -s 'https://domain.nodeloc.com/api/domains' \
  -H "Authorization: Bearer $TOKEN"
# {"domains":[{"full_domain":"xxx.loc.cc","status":"active","expires_at":"2036-..."}]}

Coupon: One Per Account

The FREEJUL coupon can only be used once per account. To register multiple domains, create a new account for each domain.

Email for Registration

Use AnyMessage for disposable Gmail addresses:

curl -s 'https://api.anymessage.shop/email/order?token=[REDACTED]'
# {"status":"success","id":"...","email":"xxx@gmail.com"}

See anymessage-email-api skill for full AnyMessage API docs.

DNS Management

Primary method: REST API — GET/POST /api/dns/{domain_id}/records:

# List records
curl -s 'https://domain.nodeloc.com/api/dns/DOMAIN_ID/records' \
  -H "Authorization: Bearer $TOKEN"

# Add TXT record
curl -s 'https://domain.nodeloc.com/api/dns/DOMAIN_ID/records' -X POST \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"@","type":"TXT","content":"google-site-verification=XXXX","ttl":3600}'

# Add MX record (priority field required for MX)
curl -s 'https://domain.nodeloc.com/api/dns/DOMAIN_ID/records' -X POST \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"@","type":"MX","content":"ASPMX.L.GOOGLE.COM","priority":1,"ttl":3600}'

Verify DNS: nslookup -q=TXT domain.loc.cc ns1.nodelook.com

Fallback: Web UI — DaisyUI comboboxes at /domains → domain → "DNS". Use browser_console:

document.querySelector('select').value = 'MX';

Google Workspace Integration

.loc.cc / .rr.kg are rejected for NEW Workspace signup (Google flags as spam). But they ARE accepted as secondary domains on an existing Workspace:

  1. Reset admin password if needed (google-workspace-sa skill)
  2. admin.google.com → Domains → Add domain → enter .loc.cc → Secondary domain
  3. Get TXT verification record from Google
  4. Add TXT to nodeloc DNS via API above
  5. Verify: nslookup -q=TXT domain.loc.cc ns1.nodelook.com
  6. Click "Verify" in Google Admin → domain confirmed
  7. Create users via SA key: admin.users().insert(body={'primaryEmail': 'user@domain.loc.cc', ...})

See google-workspace-sa skill for full Workspace + SA key pipeline.

  • nodeloc-domain-farm — mass-registration, account discovery, DO server inventory, known accounts list. Overlaps; prefer nodeloc-domain-farm for bulk operations and nodeloc-free-domain for single-domain registration.
  • google-workspace-sa — full Workspace + SA key pipeline for adding domains and creating users.

Domain Inventory

Full 167-domain list on DO server: ssh -i ~/.ssh/do_access root@[REDACTED-IP] → /root/domains_unique_167.txt. SSH to this host fails with Permission denied (publickey,password) (verified 2026-10-08) — treat the DO inventory as unreachable; recover domain lists via the API per-account instead.

Account discovery: [REDACTED-NAME]+DOMAINPREFIX@gmail.com / Reform123!@#. Login works with the +alias form (Gmail delivers it); known-good alias prefix: darkgate (token ~247 chars, owns darkgate.loc.cc active, id 4971). Base email without alias returns {"error":"error.invalid_credentials"} — try alias prefixes, not password variants. See nodeloc-domain-farm for known accounts.

{
  "id": 1,
  "domain": "loc.cc",
  "nameservers": ["ns1.nodelook.com", "ns2.nodelook.com"],
  "price_per_year": 100,
  "lifetime_price": 1000,
  "is_free": false,
  "min_user_level": "normal",
  "min_length": 3,
  "max_length": 63
}

Discovered API Endpoints

Method Path Purpose
POST /api/auth/register Create account
POST /api/auth/login Get token
GET /api/user/profile User profile
GET /api/domains List user domains
POST /api/orders Create domain order
POST /api/orders/calculate Calculate price
POST /api/payments/{id}/complete-free Pay free order
GET /api/public/root-domains List TLDs
GET /api/public/site-config Site config
GET /api/cyberpanel/accounts CyberPanel (broken)
POST /api/cyberpanel/accounts Create CyberPanel (422)

Pitfalls

  • Coupon is one-use: FREEJUL returns "You have already used this coupon" on second attempt. Create new account.
  • Field names are snake_case: subdomain, root_domain_id, coupon_code - not PascalCase.
  • Password registration disabled in UI: Web shows "current password registration disabled" but API accepts it.
  • Google OAuth blocked: Google blocks headless browsers ("browser or app may not be secure").
  • GitHub OAuth blocked: DataDome CAPTCHA on headless browser IPs.
  • NodeLoc OAuth via Telegram: Works but requires nodeloc.com forum account (invite-only).
  • DNS API: GET/POST /api/dns/{domain_id}/records. See nodeloc-domain-farm skill for full DNS API docs.
  • CyberPanel broken: Returns 422 "CyberPanel returned HTTP 404" - provisioning fails.
  • DaisyUI comboboxes: Use browser_console to set document.querySelector('select').value instead of clicking.
  • Order expires in 15 minutes: If not paid, the order becomes invalid. Pay immediately after creating.
  • FREEJUL expired 2026-07-16: Coupon dead. Orders on paid TLDs return {"error":"This order requires payment"}; /api/payments/{id}/initiate produces a real payment redirect. But nl8.eu (root_domain_id=2) still registered free end-to-end — probe orders/calculate per root_domain_id instead of assuming all TLDs are paywalled.
  • Auth header case matters: lowercase authorization: Bearer *** only; Authorization:→error.unauthorized` even with a valid token.
  • Free-subdomain domains are on target blocklists: *.loc.cc and *.nl8.eu both fail domain-validation onboarding at services like Daytona («validated work email») even after successful OTP — a free nodeloc domain is fine for mail forwarding/verification, useless for work-email-gated products. Real registered domains only for those.
  • OTP-форвардинг только через forwardemail.net: чтобы на домен реально приходили коды, поставить MX mx1/mx2.forwardemail.net + TXT forward-email=<свой gmail> + SPF v=spf1 include:spf.forwardemail.net ~all (через DNS API выше) и ПРОВЕРИТЬ: nslookup -type=TXT <domain> 8.8.8.8 (оба TXT на месте) + тестовое письмо. Форвардинг других регистраторов (Namecheap eforward) может молча не доставлять на Gmail — домен выглядит валидным, но непригоден. Форварды поллить из [Gmail]/All Mail. Подтверждено: .loc.cc с forwardemail проходят WorkOS Signals на type.com (полный флоу: ai-provider-autoreg → references/type-com-workos-2no-autoreg.md).
  • Google Workspace rejects .loc.cc for NEW signup: Google flags .loc.cc as spam TLD. Signup fails at final step. Workaround: add as secondary domain to existing Workspace (google-workspace-sa skill). Then create users via SA key.
  • DNS does NOT auto-configure (see references/dns-pitfall.md): After registration, the domain has NO A/AAAA/CNAME records. nslookup returns no IP, curl fails with exit code 6. You MUST add DNS records manually via API. Without DNS, the domain is registered but unresolvable.