Documentation

Troubleshooting

Most problems fall into a handful of buckets. Work top to bottom; each section starts with the fastest thing to check.

Start with diagnostics

Before anything else, get a picture of the gateway’s health. Two ways:

  • In the app — the Diagnostics screen checks the gateway is online, SMS permission is granted, battery optimisation is exempt, the Wi-Fi lock is held, the endpoint URL, your SIM(s), whether the last request was reachable, and how many messages went out today.
  • Over the API — an authenticated GET /api/diagnostics returns the same picture as JSON: uptime, active SIMs, today/month totals, webhook delivery health, and the current send mode.

A client can’t reach the gateway

  1. Confirm both devices are on the same network. Guest networks and AP isolation (client isolation) silently block device-to-device traffic — turn it off or use a different network.
  2. Confirm the address and port. It’s http://<phone-ip>:8080, exactly as the app shows after you tap Start. A firewall on the calling device can block port 8080.
  3. Hit GET /health — no key needed. A healthy gateway returns {"status":"running", ...}. If that works but your authenticated calls don’t, it’s a key problem (below), not a network one.

401 Unauthorized

The API key is missing, malformed, or wrong. Copy the current key from the app (or re-scan the QR) and send it as Authorization: Bearer sk_local_.... If you recently regenerated the key, every client still using the old one gets 401 until you update it.

403 Forbidden: local network access only

The request arrived from an address outside the allowed private ranges, so the local-network guard rejected it before the key was even checked. You’re calling from outside the LAN — get on the same network, or reach the gateway over a VPN.

429 Too many requests

You’ve hit a rate limit. Honour the retryAfterSeconds value (and the Retry-After header) and back off — don’t hammer. The limits are fixed; see Security for the exact numbers.

A send returns success but no text arrives

status: "queued" means Android accepted the message — it is not a delivery receipt. Hiras cannot see carrier-side delivery, and cannot detect “insufficient balance”; a carrier rejection shows up as a failed send, not a specific reason. Check:

  1. A SIM is inserted and active, and SMS permission is granted.
  2. There’s signal and load on that SIM.
  3. Check the message’s outcome with GET /api/messages/:idsent vs failed.
  4. Reproduce with Dry Run on to confirm your request itself is valid, separately from the SIM.

Webhooks aren’t arriving

  1. Confirm the gateway is running and the webhook is enabled with a reachable http/https URL.
  2. Use the app’s Send test event to fire a delivery on demand.
  3. Verify your endpoint returns a 2xx quickly — a 4xx tells Hiras to stop and is never retried.
  4. If deliveries arrive but you’re rejecting them, re-check your signature verification: compute the HMAC over the timestamp plus the raw body, keyed by your API key. The key is never sent, so don’t expect it in a header. See Webhooks.

The gateway keeps stopping

Android may suspend or kill background apps. Allow Hiras to ignore battery optimisation, and, if you want it back after a restart, enable start after reboot. Some OEMs are aggressive about killing background apps regardless; a full process kill stops the gateway. See Configuration.

Still stuck?

Email arcwhin@gmail.com with what you’re seeing — the diagnostics output helps.

Next

  • Security — what each guard does.
  • FAQ — the shorter questions.