ResellerStack API

Everything the dashboard can do, your code can do. Check availability, register domains at wholesale, manage customers and invoices, and watch your wallet, all over a predictable JSON API. Money is always in minor units with an explicit currency.

Try it now

This call runs against the live API. Any rsk_-prefixed key works in the sandbox.

curl -H "Authorization: Bearer rsk_test_2a9x…" \
  "https://resellerstack-production.up.railway.app/api/v1/domains/check?q=example"

Getting started

The API lives under a single versioned base URL. Responses are JSON with a data envelope; list endpoints add a meta object with counts.

Base URL
https://resellerstack-production.up.railway.app/api/v1
Your first request, the API index (no auth required)
curl https://resellerstack-production.up.railway.app/api/v1
Response
{
  "data": {
    "name": "ResellerStack API",
    "version": "v1",
    "docs": "/docs",
    "endpoints": ["GET /api/v1/domains/check", "GET /api/v1/tlds", "…"]
  }
}

Authentication

Authenticate every request with a bearer API key. Create and rotate keys in Settings → API keys.

curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/domains
Key prefixes

rsk_test_ keys hit the sandbox, nothing provisions, nothing is billed. rsk_live_ keys act on your real account and wallet.

Key rotation

Create a second key, deploy it, then revoke the old one, both stay valid during the overlap, so rotation is zero-downtime.

ScopeGrants
domains:readCheck availability, list domains and DNS
domains:writeRegister, renew and update domains
orders:readRead orders, margins and timelines
orders:writeCreate and cancel orders
customers:readList and read customers
customers:writeCreate and update customers
wallet:readRead balance and ledger
webhooks:manageConfigure webhook endpoints

Errors

Errors use conventional HTTP status codes and a consistent envelope: an error object with a stable machine-readable code and a human message.

CodeStatusMeaning
unauthorized401Missing or malformed API key
insufficient_funds402Wallet balance cannot cover the wholesale cost
forbidden403Key lacks the required scope
not_found404No resource with that id
validation_error422Request body or query failed validation
rate_limited429Too many requests, back off and retry
Example error envelope
{
  "error": {
    "code": "unauthorized",
    "message": "Provide an API key: Authorization: Bearer rsk_live_…"
  }
}

Rate limits

Each key may make 300 requests per minute with bursts of up to 50 requests. Watch the response headers and back off when you approach zero.

Rate-limit headers
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1754467200

// When exhausted → 429
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Retry after the X-RateLimit-Reset time."
  }
}

Webhooks

Push instead of poll: subscribe an HTTPS endpoint to events and ResellerStack delivers a signed JSON payload within seconds of the event.

EventFires when
order.createdAn order was created (any action)
order.provisionedRegistry confirmed provisioning
order.renewedA renewal completed
order.failedProvisioning or renewal failed
domain.expiring_30dDomain enters the 30-day expiry window
domain.expiring_7dDomain enters the 7-day expiry window
transfer.initiatedInbound transfer submitted to the registry
transfer.completedInbound transfer completed
invoice.paidA customer invoice was paid
wallet.low_balanceBalance fell below your alert threshold
wallet.auto_topupAn automatic top-up ran
Example delivery
POST https://api.hurra.com/webhooks/resellerstack
X-RS-Signature: t=1754467201,v1=5f8a1c0e9b2d…
Content-Type: application/json

{
  "id": "evt_9f2ka01",
  "type": "order.provisioned",
  "createdAt": "2026-08-06T09:14:02Z",
  "data": {
    "orderId": "ord_1006",
    "domain": "kolkatacreative.in",
    "customerId": "cus_08",
    "status": "active"
  }
}
Verify signatures

Every delivery carries an X-RS-Signature header: an HMAC-SHA256 of {timestamp}.{raw body} using your endpoint secret. Recompute it, compare in constant time, and reject anything older than five minutes to prevent replays.

Domains

Availability checks, the domain portfolio, and registration.

GET/v1/domains/check

Check availability. Pass domain for a single exact check, or q to sweep every supported TLD. Availability is deterministic per name, and prices come straight from the live price book.

ParameterTypeRequiredDescription
domainstringNoExact domain to check, e.g. acme.dev
qstringNoBare name to check across all supported TLDs
Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  "https://resellerstack-production.up.railway.app/api/v1/domains/check?domain=acme.dev"
Response
{
  "data": [
    {
      "domain": "acme.dev",
      "tld": ".dev",
      "supported": true,
      "available": true,
      "wholesale": { "amount": 1100, "currency": "USD" },
      "suggestedRetail": { "amount": 1599, "currency": "USD" }
    }
  ],
  "meta": { "query": "acme.dev", "count": 1 }
}
GET/v1/domains

List all domain orders in your account with status, expiry and auto-renew state.

Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/domains
Response
{
  "data": [
    {
      "id": "ord_1001",
      "domain": "nordlicht.studio",
      "status": "active",
      "customerId": "cus_01",
      "expiresAt": "2026-11-02",
      "autoRenew": true
    },
    {
      "id": "ord_1002",
      "domain": "brightpath.dev",
      "status": "expiring",
      "customerId": "cus_02",
      "expiresAt": "2026-08-21",
      "autoRenew": false
    }
  ],
  "meta": { "count": 10 }
}
GET/v1/domains/{id}

Retrieve a single domain order, including nameservers, DNS records and WHOIS contacts when the domain is provisioned.

ParameterTypeRequiredDescription
idstring (path)YesDomain order id, e.g. ord_1001
Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/domains/ord_1001
Response
{
  "data": {
    "id": "ord_1001",
    "domain": "nordlicht.studio",
    "status": "active",
    "customerId": "cus_01",
    "expiresAt": "2026-11-02",
    "autoRenew": true,
    "nameservers": ["ns1.resellerstack.net", "ns2.resellerstack.net"],
    "dnssec": true,
    "privacyProtection": true,
    "transferLock": true,
    "dnsRecords": [
      { "id": "r1", "type": "A", "host": "@", "value": "76.76.21.21", "ttl": 3600 },
      { "id": "r3", "type": "MX", "host": "@", "value": "mx1.titan.email", "ttl": 3600, "priority": 10 }
    ]
  }
}
POST/v1/domains

Register a domain. The wholesale cost is drawn from your wallet; the order provisions asynchronously, poll the order or subscribe to order.provisioned.

ParameterTypeRequiredDescription
domainstringYesFull domain to register, e.g. acme.dev
yearsintegerNoRegistration term, 1–10 (default 1)
customerIdstringNoAttach the order to an existing customer
Request
curl -X POST -H "Authorization: Bearer rsk_live_7f3k…" \
  -H "Content-Type: application/json" \
  -d '{"domain": "acme.dev", "years": 2, "customerId": "cus_02"}' \
  https://resellerstack-production.up.railway.app/api/v1/domains
Response · 202 Accepted
{
  "data": {
    "orderId": "ord_new_acme-dev",
    "status": "processing",
    "domain": "acme.dev",
    "years": 2,
    "customerId": "cus_02",
    "autoRenew": true
  }
}

TLDs & pricing

The wholesale price book that drives every quote.

GET/v1/tlds

The full price book: wholesale register/renew/transfer/restore cost, suggested retail (SRP), and any live promo per TLD. All amounts are minor units (cents), per year.

Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/tlds
Response
{
  "data": [
    {
      "tld": ".ai",
      "category": "new",
      "trend": "rising",
      "wholesale": {
        "register": { "amount": 6200, "currency": "USD" },
        "renew": { "amount": 6500, "currency": "USD" },
        "transfer": { "amount": 6200, "currency": "USD" },
        "restore": { "amount": 18500, "currency": "USD" }
      },
      "srp": {
        "register": { "amount": 8999, "currency": "USD" },
        "renew": { "amount": 9499, "currency": "USD" },
        "transfer": { "amount": 8999, "currency": "USD" }
      },
      "promo": {
        "register": { "amount": 7999, "currency": "USD" },
        "endsAt": "2026-08-31",
        "label": "AI summer promo"
      }
    }
  ],
  "meta": { "count": 15 }
}

Orders

Orders across every product, with cost, price and margin.

GET/v1/orders

List every order, all product categories, with wholesale cost, retail price and your margin.

Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/orders
Response
{
  "data": [
    {
      "id": "ord_1010",
      "customerId": "cus_02",
      "productCategory": "domain",
      "productLabel": "schweier.ai",
      "action": "register",
      "status": "pending",
      "createdAt": "2026-08-03",
      "autoRenew": true,
      "cost": { "amount": 6200, "currency": "USD" },
      "price": { "amount": 8999, "currency": "USD" },
      "margin": { "amount": 2799, "currency": "USD" }
    }
  ],
  "meta": { "count": 10 }
}
GET/v1/orders/{id}

Retrieve one order with its full event timeline.

ParameterTypeRequiredDescription
idstring (path)YesOrder id, e.g. ord_1009
Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/orders/ord_1009
Response
{
  "data": {
    "id": "ord_1009",
    "customerId": "cus_07",
    "productLabel": "lyyde.com",
    "action": "renew",
    "status": "active",
    "expiresAt": "2027-06-30",
    "cost": { "amount": 950, "currency": "USD" },
    "price": { "amount": 1499, "currency": "USD" },
    "margin": { "amount": 549, "currency": "USD" },
    "timeline": [
      {
        "at": "2026-06-30T08:00:00Z",
        "type": "renewed",
        "summary": "Auto-renewed for 1 year",
        "actor": "system"
      }
    ]
  }
}

Customers

The people you sell to.

GET/v1/customers

List your customers with lifetime spend, domain count and open orders.

Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/customers
Response
{
  "data": [
    {
      "id": "cus_01",
      "name": "Evgenii Voitishek",
      "company": "Nordlicht Studio",
      "email": "evgenii@nordlicht.studio",
      "country": "DE",
      "status": "active",
      "totalSpend": { "amount": 184500, "currency": "USD" },
      "domains": 1,
      "openOrders": 0,
      "tags": ["agency", "priority"]
    }
  ],
  "meta": { "count": 10 }
}
POST/v1/customers

Create a customer. New customers start in the invited state until they accept your storefront invite.

ParameterTypeRequiredDescription
namestringYesFull name
emailstringYesUnique email address
companystringNoCompany name
countrystringNoISO 3166-1 alpha-2, e.g. US
Request
curl -X POST -H "Authorization: Bearer rsk_live_7f3k…" \
  -H "Content-Type: application/json" \
  -d '{"name": "Jane Cooper", "email": "jane@coopers.co", "country": "US"}' \
  https://resellerstack-production.up.railway.app/api/v1/customers
Response · 201 Created
{
  "data": {
    "id": "cus_new_jane",
    "name": "Jane Cooper",
    "email": "jane@coopers.co",
    "country": "US",
    "status": "invited",
    "totalSpend": { "amount": 0, "currency": "USD" },
    "domains": 0
  }
}
GET/v1/customers/{id}

Retrieve one customer, including a compact list of their orders.

ParameterTypeRequiredDescription
idstring (path)YesCustomer id, e.g. cus_02
Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/customers/cus_02
Response
{
  "data": {
    "id": "cus_02",
    "name": "Sean Schweier",
    "company": "Brightpath Web",
    "email": "sean@brightpath.dev",
    "country": "US",
    "status": "active",
    "totalSpend": { "amount": 96200, "currency": "USD" },
    "orders": [
      { "id": "ord_1002", "productLabel": "brightpath.dev", "status": "expiring" },
      { "id": "ord_1010", "productLabel": "schweier.ai", "status": "pending" }
    ]
  }
}

Invoices

Per-order invoices you issue to customers.

GET/v1/invoices

List customer invoices. Filter by status to build dunning flows.

ParameterTypeRequiredDescription
statusstringNopaid | due | overdue | refunded | void
Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  "https://resellerstack-production.up.railway.app/api/v1/invoices?status=due"
Response
{
  "data": [
    {
      "id": "INV-2026-0158",
      "orderId": "ord_1003",
      "customerId": "cus_04",
      "issuedAt": "2026-07-30",
      "dueAt": "2026-08-13",
      "status": "due",
      "method": "payment-link",
      "lineItems": [
        {
          "label": "lagosdigital.ng transfer + 1 yr extension",
          "amount": { "amount": 2999, "currency": "USD" }
        }
      ],
      "total": { "amount": 2999, "currency": "USD" }
    }
  ],
  "meta": { "count": 3, "status": "due" }
}

Wallet

Your prepaid balance funds every wholesale purchase.

GET/v1/wallet

Current balance plus a computed estimate of the wholesale draw from renewals due in the next 30 days, wire this into your treasury alerts.

Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/wallet
Response
{
  "data": {
    "balance": { "amount": 201180, "currency": "USD" },
    "autoTopup": { "enabled": false },
    "upcomingRenewals": {
      "windowDays": 30,
      "count": 1,
      "estimatedDraw": { "amount": 1200, "currency": "USD" },
      "items": [
        {
          "orderId": "ord_1002",
          "domain": "brightpath.dev",
          "expiresAt": "2026-08-21",
          "autoRenew": false,
          "wholesaleRenew": { "amount": 1200, "currency": "USD" }
        }
      ]
    }
  }
}
GET/v1/wallet/transactions

The wallet ledger, top-ups, order debits, refunds and promo credits, newest first. Amounts are signed; positive is a credit.

Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/wallet/transactions
Response
{
  "data": [
    {
      "id": "txn_898",
      "at": "2026-07-28T09:12:00Z",
      "type": "topup",
      "description": "Wallet top-up via Stripe",
      "amount": { "amount": 50000, "currency": "USD" },
      "balanceAfter": { "amount": 210780, "currency": "USD" },
      "status": "completed"
    }
  ],
  "meta": { "count": 8 }
}

Migrations

Bulk transfer-in jobs from other registrars.

GET/v1/migrations

List transfer-in migration jobs. Auto-mode jobs schedule themselves for 15 days before expiry and chase EPP codes for you.

Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/migrations
Response
{
  "data": [
    {
      "id": "mig_02",
      "domain": "brightpath.co",
      "providerId": "namecheap",
      "customerId": "cus_02",
      "expiresAt": "2026-08-30",
      "transferWindowAt": "2026-08-15",
      "status": "awaiting-auth",
      "autoMode": true,
      "events": [
        { "at": "2026-08-02T09:00:00Z", "summary": "Auth-code request emailed to sean@brightpath.dev" }
      ]
    }
  ],
  "meta": { "count": 4 }
}

Webhook config

Manage the endpoints that receive event deliveries.

GET/v1/webhooks

List configured webhook endpoints and their delivery health.

Request
curl -H "Authorization: Bearer rsk_live_7f3k…" \
  https://resellerstack-production.up.railway.app/api/v1/webhooks
Response
{
  "data": [
    {
      "id": "wh_01",
      "url": "https://api.hurra.com/webhooks/resellerstack",
      "events": ["order.provisioned", "order.renewed", "transfer.completed"],
      "active": true,
      "lastDeliveryStatus": "ok"
    }
  ],
  "meta": { "count": 1 }
}
POST/v1/webhooks

Create a webhook endpoint. The signing secret is returned once, store it and verify every delivery.

ParameterTypeRequiredDescription
urlstringYesHTTPS endpoint that receives deliveries
eventsstring[]YesEvents to subscribe to (see the event catalog)
Request
curl -X POST -H "Authorization: Bearer rsk_live_7f3k…" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://api.example.com/hooks/rs", "events": ["order.provisioned", "invoice.paid"]}' \
  https://resellerstack-production.up.railway.app/api/v1/webhooks
Response · 201 Created
{
  "data": {
    "id": "wh_new_8fk2ma",
    "url": "https://api.example.com/hooks/rs",
    "events": ["order.provisioned", "invoice.paid"],
    "active": true,
    "secret": "whsec_XXXXXXXXXXXXXXXXXXXXXXXX"
  }
}