Skip to content

Demo Runbook (Source)

Airfree Cloud ↔ HostivaPro Sandbox — Demo Runbook (Checklist)

Goal: In ≤ 60 minutes, demo Domain Search → Order → Checkout from Airfree Cloud using HostivaPro Sandbox API.

This runbook is intentionally short and copy/paste friendly.


0) What you need (5 minutes)

A) API Base (Hostiva Core)

  • Base URL: https://core.hostiva.quantumdevlabs.com/api/v1

B) Tenant Slug

Each reseller has its own tenant slug: - Airfree Cloud → airfree (or hostiva if you’re still running single-tenant during demo) - Celteck Cloud → celteck - Default/dev tenant → hostiva

C) Sandbox Developer API Key

You need a key starting with sbx_...

Security rule: Do NOT expose the key in browser JS.
Airfree backend should call Hostiva (server-to-server), then return clean results to the frontend.


1) Define environment variables (copy/paste)

Run on any machine with curl + jq (Linux server, WSL, macOS).

BASE="https://core.hostiva.quantumdevlabs.com/api/v1"
TENANT="airfree"     # set to your reseller tenant slug (airfree/celteck/hostiva)
KEY="sbx_REPLACE_WITH_YOUR_KEY"

Quick sanity check:

echo "$BASE" && echo "$TENANT" && echo "${KEY:0:8}"


2) Sandbox Domain Search (✅ must work first)

Request

curl -sk "$BASE/sandbox/domains/search"   -H "Accept: application/json"   -H "Content-Type: application/json"   -H "X-Tenant: $TENANT"   -H "Authorization: Bearer $KEY"   --data-raw '{"domain":"example.com"}' | jq .

Expected (example)

{
  "query": "example.com",
  "status": "available",
  "tld": "com",
  "price": { "currency": "USD", "register": 9.99, "renew": 11.99, "transfer": 9.99 },
  "meta": { "source": "hostiva-sandbox" }
}

Common failures

  • 401 Unauthorized (developer api key invalid)
    → wrong key, wrong tenant, or key not stored/hashed with the current hashing mode.
  • 403 Forbidden (scope permission denied)
    → enable permission sandbox.search for that key in Developer Keys UI.

3) Sandbox Order (reserve intent)

This step creates an “order intent” (a draft order) for the domain.

Request

curl -sk "$BASE/sandbox/domains/order"   -H "Accept: application/json"   -H "Content-Type: application/json"   -H "X-Tenant: $TENANT"   -H "Authorization: Bearer $KEY"   --data-raw '{
    "domain": "example.com",
    "years": 1,
    "contact": {
      "first_name": "Valentine",
      "last_name": "Onyemachi",
      "email": "dev@airfreeng.com",
      "phone": "+2348000000000",
      "country": "NG"
    }
  }' | jq .

Expected (shape)

You should receive something like: - order_id or order_ref - domain - state like draft / pending_checkout - pricing totals

Your exact response fields depend on your controller implementation, but the key is: order intent is created and returned.


4) Sandbox Checkout (finalize order)

This simulates a “paid” completion in Sandbox and returns a final state.

Request (example — adjust to your response fields)

If order returned order_id, use it here:

ORDER_ID="REPLACE_WITH_ORDER_ID"

curl -sk "$BASE/sandbox/domains/checkout"   -H "Accept: application/json"   -H "Content-Type: application/json"   -H "X-Tenant: $TENANT"   -H "Authorization: Bearer $KEY"   --data-raw "{
    "order_id": "$ORDER_ID",
    "payment": { "method": "sandbox", "reference": "demo_$(date +%s)" }
  }" | jq .

Expected (shape)

  • status like completed
  • domain info
  • maybe provisioning_job_id if your SLE hooks in

5) “Happy path” demo flow for Airfree UI (what to show management)

1) Search a domain that is available: example.com
2) Show price box + checkout summary
3) Click “Order” (calls order)
4) Click “Complete Checkout” (calls checkout)
5) Show confirmation “Domain order completed (Sandbox)”
6) Optionally show “Order ID / Reference”


6) Test scenarios (fast but thorough)

A) Search scenarios

  • Available domain: example.com
  • Taken domain: google.com (your mock can force taken)
  • Invalid domain format: example (no TLD) → expect 422
  • Unsupported TLD: example.invalidtld → expect 422 or unsupported

B) Permission scenarios

Use a key without search: - Expect 403 with:

{ "message":"Forbidden (scope permission denied).", "required":"search" }

C) Tenant isolation scenarios

Use Airfree key with Celteck tenant: - Expect 401/403 (depends on your policy) - This proves tenant isolation works

D) Rate limiting scenarios

Spam search in a loop: - Eventually expect 429 “Rate limit exceeded”


7) Troubleshooting cheatsheet

“parse error: Invalid numeric literal” from jq

You likely wrote the curl as a single line incorrectly. Fix: Use the multiline version exactly as shown.

401 “developer api key invalid”

  • Confirm you’re calling the core host: core.hostiva.quantumdevlabs.com
  • Confirm headers include both:
  • Authorization: Bearer $KEY
  • X-Tenant: $TENANT
  • Confirm DB has a row with correct tenant_slug, scope=sandbox, and it is active

403 “scope permission denied”

  • Set the permission in UI: sandbox.search / sandbox.order / sandbox.checkout

8) Where devs manage keys & permissions (UI)

Developer portal: - https://core.hostiva.quantumdevlabs.com/developer/keys

Per key: - Scope: sandbox / sandbox-proxy / live - Permissions: - sandbox: search, order, checkout - sandbox-proxy: check - live: check, smart-search


Frontend (Airfree Cloud UI) - Search form + results - Checkout sidebar

Backend (Airfree API) - Calls Hostiva Sandbox API - Stores order_id + statuses - Never exposes Hostiva dev key to browser

HostivaPro Core - Does auth, permission enforcement, rate limiting, usage logging


10) Quick “ready to demo” checklist

  • [ ] Sandbox key created for tenant airfree
  • [ ] Key has permissions: search, order, checkout
  • [ ] Search endpoint returns JSON for example.com
  • [ ] Order endpoint returns an order identifier
  • [ ] Checkout endpoint returns completed status
  • [ ] Airfree UI calls Airfree backend (not Hostiva directly)
  • [ ] Demo flow rehearsed once end-to-end

If anything fails: copy/paste the exact curl + output and we’ll fix in minutes.