Sessions

Plugipay family portal: sessions

The Session page at /dashboard/session is the main control surface for your Pawpado desktop. From here you start, stop, pair, and watch your session.

This page is also embedded as the dashboard's landing card — on /dashboard, the top half is the same session control. Visiting /dashboard/session directly just gives you the same thing on its own page with more diagnostic detail visible.

The big button

The most prominent control on the page is the action button. Its label changes based on session state:

State Button What it does
idle Start session Provisions and launches a new instance.
provisioning / starting Cancel Aborts the launch (rare; usually finishes faster than you can react).
running, ready: false (disabled) Starting up… Wait. Streaming server is registering.
running, ready: true Stop session Shuts down the instance.
stopping (disabled) Stopping… Wait for stop to finish before another action.
failed Retry Clears the failed state and lets you start fresh.

The button is the safe primary action for almost every situation — we deliberately disable it when there's nothing useful you should be doing.

Starting a session

Click Start session. Behind the scenes Pawpado:

  1. Reserves your EBS volume from the previous session (creates a new one if first time).
  2. Calls the AWS EC2 API to launch a g5.xlarge from the canonical Pawpado AMI in ap-southeast-3 (Jakarta).
  3. Mints a fresh Tailscale ephemeral auth key tagged tag:pawpado-user-<huudisUserId>.
  4. Polls the instance for apollo-ready and tailnet-registered.
  5. Flips ready to true when both are confirmed.

The progress card shows each step as it completes. Total time is usually 60-90 seconds, with the EC2 boot dominating.

Why two readiness signals? running only means the EC2 instance is up. We've been bitten by races where the dashboard shows "Running", the user clicks Pair, and Apollo isn't actually listening yet. Pawpado now waits for Apollo's own healthcheck and Tailscale registration before flipping ready.

Pairing a Moonlight client

Once the status is Ready, the Pair button activates.

  1. Click Pair. A modal shows a four-digit PIN.
  2. On the device you want to play on, open Moonlight and click Add Host manually.
  3. Type the PIN.

Moonlight handshakes with Apollo and adds your device to the Apollo allowlist. The PIN expires after two minutes — if Moonlight took too long, request a new one.

Each pair is per-device. Pair as many devices as you like during one session. The allowlist is wiped on session stop, so you'll re-pair next time.

Cost so far

While running, a Cost so far chip shows the credit you've spent on this session. It updates every five seconds and matches what the meter will actually have charged at this exact moment.

The chip is informational — the meter is canonical and runs in the backend regardless of whether you have the dashboard open.

Auto-stop

By default, Pawpado auto-stops your session after 15 minutes of input inactivity on the Apollo side. This protects you from leaving the meter running overnight after stepping away.

Change the timeout under Settings → Preferences → Auto-stop. Acceptable range is 5-120 minutes, or disable it entirely (not recommended).

If auto-stop triggers, you'll get a notification email and the dashboard reflects the stop on next load.

Stopping a session

Click Stop session. The state moves to stopping and:

  1. Apollo is told to disconnect any active clients.
  2. The EC2 instance is sent a shutdown signal (you have ~30 seconds for in-game saves to flush).
  3. The EBS volume is detached but kept.
  4. The tailnet node deregisters.

The compute meter stops the second Pawpado sees the EC2 state transition to stopping. Storage continues to bill until the volume is deleted (only happens if you delete your account, with 30-day grace).

What if it fails?

If a session enters failed, the dashboard shows the human-readable error in red. Common ones:

  • INSUFFICIENT_CREDITS — your balance ran out mid-session. The instance was stopped to protect you. Top up to start a new one.
  • AWS_CAPACITY — Jakarta is out of g5.xlarge capacity (rare). Wait 5-10 minutes and retry.
  • APOLLO_REGISTRATION_TIMEOUT — the streaming server didn't register within 5 minutes. Click Retry; if it persists, contact support.
  • TAILSCALE_KEY_REJECTED — Tailscale rejected the auth key. Almost always transient; retry.

The Retry button clears the failed state and lets you start fresh.

Diagnostic detail

The page footer collapses by default into a Diagnostics section. Expand it to see:

  • instanceId — the EC2 instance ID.
  • tailnetIp — the IP Moonlight uses to reach Apollo.
  • publicIp — visible but only Apollo uses it during handshake.
  • startedAt — when the current session began.
  • Last 50 backend log lines from your control plane interactions.

Useful when emailing support.

Programmatic control

Every button on this page maps to one API call — see API overview. In short:

  • StartPOST /api/v1/sessions/start
  • StopPOST /api/v1/sessions/stop
  • PollGET /api/v1/sessions/poll
  • PairPOST /api/v1/sessions/pair

Or via SDK:

import { PawpadoClient } from '@forjio/pawpado-node';

const pawpado = new PawpadoClient({ apiKey: process.env.PAWPADO_TOKEN });

await pawpado.sessions.start();
while (true) {
  const s = await pawpado.sessions.poll();
  if (s.state === 'running' && s.ready) break;
  await new Promise((r) => setTimeout(r, 5000));
}
const { pin } = await pawpado.sessions.pair();
console.log('Type this in Moonlight:', pin);

Next