Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions docs/infrastructure/hyperyap-com.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# HyperYap.com Infrastructure

Last verified: 2026-06-19

## Purpose

`hyperyap.com` is the public website for HyperYap. The website should stay
separate from the Tauri desktop app surface and must preserve the project
privacy boundary:

- no analytics or telemetry by default
- no hosted transcription endpoint
- no open CORS examples
- no copy that implies uploaded audio processing

## Current Setup

- Registrar: Namecheap
- DNS authority target: Cloudflare
- Hosting target: Railway
- Website source path: `website/`
- Website branch: `codex/hyperyap-com`
- GitHub repository: `avalonreset/hyperyap`
- Railway project: `hyperyap-com`
- Railway project ID: `b377377b-002c-4537-af5f-f3f3024b4110`
- Railway environment: `production`
- Railway environment ID: `02bcbd37-47b5-4495-9e43-9fcd2bc26f05`
- Railway service: `hyperyap-site`
- Railway service ID: `585ad33d-03b6-49bc-993e-e51d89d3e31e`
- Railway service domain: `https://hyperyap-site-production.up.railway.app/`
- Railway deployment trigger: `avalonreset/hyperyap`, branch `codex/hyperyap-com`
- Cloudflare zone: `hyperyap.com`
- Cloudflare zone ID: `e6c37dee7e277e6be62833f3c5cd2480`
- Cloudflare nameservers assigned: `hazel.ns.cloudflare.com`, `kaiser.ns.cloudflare.com`
- Current Cloudflare zone status: `pending` until Namecheap delegates to Cloudflare

## Current Blocker

Namecheap API calls are blocked by the account's API client-IP whitelist. The
DNS records already exist in Cloudflare, but the registrar still uses Namecheap
default nameservers:

- `dns1.registrar-servers.com`
- `dns2.registrar-servers.com`

To finish delegation, update the Namecheap API whitelist for the current
outgoing IP and rerun `namecheap.domains.dns.setCustom`, or change the
nameservers manually in the Namecheap dashboard to:

- `hazel.ns.cloudflare.com`
- `kaiser.ns.cloudflare.com`

After that propagates, Cloudflare should activate the zone and Railway should
verify the custom-domain TXT records.

## Railway Domains

Railway custom domains are configured for:

| Domain | Traffic record | Verification host |
| --- | --- | --- |
| `hyperyap.com` | CNAME `hyperyap.com` -> `d9qs201m.up.railway.app` | TXT `_railway-verify.hyperyap.com` |
| `www.hyperyap.com` | CNAME `www.hyperyap.com` -> `qvv1bgf7.up.railway.app` | TXT `_railway-verify.www.hyperyap.com` |

Cloudflare records were created as DNS-only so Railway can validate ownership
and serve HTTPS directly.

## Provider API Notes

### Cloudflare

Use the Cloudflare v4 API with the bearer token already stored in the local
credential inventory. Do not print token values.

Common calls:

```text
GET /client/v4/user/tokens/verify
GET /client/v4/zones?name=hyperyap.com
POST /client/v4/zones
POST /client/v4/zones/{zone_id}/dns_records
```

For Railway domains, add the DNS records returned by Railway:

- apex domain usually needs Railway's CNAME flattening target
- `www` can point to the Railway target or redirect at Cloudflare
- Railway also returns a TXT verification record that must be present

### Namecheap

Use Namecheap's XML API from a whitelisted client IP. Required fields are:

- `ApiUser`
- `ApiKey`
- `UserName`
- `ClientIp`
- `Command`
- `SLD`
- `TLD`

To delegate the domain to Cloudflare:

```text
namecheap.domains.dns.setCustom
SLD=hyperyap
TLD=com
NameServers=hazel.ns.cloudflare.com,kaiser.ns.cloudflare.com
```

Do not switch Namecheap nameservers until Cloudflare has enough DNS records to
serve either the Railway site or an intentional temporary placeholder.

### Railway

The local Railway CLI session can expire. The Railway GraphQL API token in the
local credential inventory is the reliable path for API reads and mutations.

Useful GraphQL mutations:

- `projectCreate`
- `serviceCreate`
- `deploymentTriggerCreate`
- `serviceInstanceDeploy`
- `serviceDomainCreate`
- `customDomainCreate`
- `environmentPatchCommit`

The site is a static service with a deployment trigger root directory of
`website/`.

## Verification Checklist

Before declaring the domain live:

1. Railway deployment status is `SUCCESS`.
2. Railway-provided service domain returns the HyperYap homepage.
3. `hyperyap.com` and `www.hyperyap.com` records exist in Cloudflare.
4. Railway TXT verification record exists in Cloudflare.
5. Namecheap nameservers are set to Cloudflare.
6. `https://hyperyap.com/` returns `200`.
7. `http://hyperyap.com/` redirects to HTTPS.
8. `https://www.hyperyap.com/` redirects or resolves intentionally.
9. The live page contains no analytics, trackers, remote transcription endpoint,
or unexpected third-party scripts.
76 changes: 76 additions & 0 deletions website/api.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HyperYap Local API</title>
<meta name="description" content="Use HyperYap's local HTTP API to transcribe WAV files on your own machine.">
<link rel="canonical" href="https://hyperyap.com/api.html">
<link rel="icon" href="/assets/app-icon.png">
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<header class="site-header">
<nav class="nav" aria-label="Primary">
<a class="brand" href="/">
<img src="/assets/app-icon.png" alt="" width="32" height="32">
<span>HyperYap</span>
</a>
<div class="nav-links">
<a href="/">Home</a>
<a href="/privacy.html">Privacy</a>
<a href="/security.html">Security</a>
<a href="https://github.com/avalonreset/hyperyap">GitHub</a>
</div>
</nav>
</header>

<main class="page-main">
<article class="content-page">
<p class="eyebrow">Experimental integration surface</p>
<h1>Local HTTP API</h1>
<p class="lede">
HyperYap can expose a localhost-only transcription endpoint while the
desktop app is open. It is intended for local tools that need a private
speech-to-text engine.
</p>

<section>
<h2>Enable it</h2>
<ol>
<li>Open HyperYap.</li>
<li>Go to Settings, then System.</li>
<li>Enable Local API.</li>
<li>Use the configured localhost port. The default is <code>4800</code>.</li>
</ol>
</section>

<section>
<h2>Endpoint</h2>
<p><code>POST http://127.0.0.1:4800/api/transcribe</code></p>
<p>Send a multipart form field named <code>audio</code> containing a WAV file.</p>
<pre class="code-panel"><code>curl -X POST http://127.0.0.1:4800/api/transcribe \
-F "audio=@recording.wav;type=audio/wav"</code></pre>
</section>

<section>
<h2>Response</h2>
<pre class="code-panel"><code>{
"text": "Hello everyone, here is the complete transcript..."
}</code></pre>
<p>Errors return a JSON object with an <code>error</code> message.</p>
</section>

<section>
<h2>Security model</h2>
<ul>
<li>The API listens on localhost.</li>
<li>CORS is not enabled.</li>
<li>Requests are processed sequentially through the local transcription engine.</li>
<li>Audio files must be WAV and no larger than the app limit.</li>
</ul>
</section>
</article>
</main>
</body>
</html>
Binary file added website/assets/app-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/assets/banner.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/assets/logo-hyper.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/assets/logo-yap.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading