trqsh Control API
Manage cloud accounts, credentials, domains and reported usage. To start or stop a tunnel on a computer, use the separate local agent API.
Connect and authenticate
https://api.trqsh.uz/v1Append the endpoint path below. Send Authorization: Bearer YOUR_API_KEY or a dashboard access JWT. The same header carries either credential; a local control token does not authenticate here.
curl -fsS \ -H "Authorization: Bearer $TRQSH_API_KEY" \ "https://api.trqsh.uz/v1/me"$trqshHeaders = @{ Authorization = "Bearer $env:TRQSH_API_KEY" }Invoke-RestMethod -Uri "https://api.trqsh.uz/v1/me" -Headers $trqshHeadersSupply your real key through a private environment variable. /me works with API keys or JWTs; /account is a user-profile endpoint intended for dashboard JWTs.
Requests, responses and errors
- Send JSON bodies with
Content-Type: application/json. Replace path placeholders such as{id}with the returned resource ID. - Successful DELETE actions commonly return 204 with no body; do not parse them as JSON.
- Resource failures normally return
{"error":"message"}. Check the HTTP status before reading success fields. - 401 means missing/rejected credentials; 403 means a permission, plan or disabled-feature condition; 409 means a conflict; 429 means rate limiting.
- SSE endpoints return
text/event-stream. Read streamed event frames and reconnect when necessary.
Limits and required fields come from the checked-in contract. Deployed API versions can differ. Fetch the deployed OpenAPI document when building a client for a specific server. Development email auth and optional Stripe billing endpoints are conditional features.
Download deployed OpenAPIExample: reserve a hostname
curl -fsS \ -H "Authorization: Bearer $TRQSH_API_KEY" \ -H "Content-Type: application/json" \ -d '{"subdomain":"myapp"}' \ "https://api.trqsh.uz/v1/subdomains"A successful reservation returns 201. Start the actual tunnel with /http 3000 --subdomain myapp on the agent. Cloud GET /tunnels lists sessions reported by the edge; it does not launch your local app.
Authentication
/auth/signupNo Bearer authCreate an account (dev/email flow)
Test-only endpoint, disabled by default. Requires explicit TRQSH_DEV_AUTH=1 in development and is always forbidden in production. Public accounts use GitHub or Google with a verified email.
Request body · required · application/json
| Field | Type | Details |
|---|---|---|
emailrequired | string | format: email |
nameoptional | string | See full definition. |
{ "type": "object", "required": [ "email" ], "properties": { "email": { "type": "string", "format": "email" }, "name": { "type": "string" } }}Responses
200Account created200 response schema · application/json
Field Type Details useroptionalobject See full definition. orgoptionalobject See full definition. tokensoptionalTokens See full definition. AuthResponse · JSON Schema{ "type": "object", "properties": { "user": { "type": "object" }, "org": { "type": "object" }, "tokens": { "$ref": "#/components/schemas/Tokens" } }}403Email-only authentication is disabled409User already exists
/auth/loginNo Bearer authLog in (dev/email flow)
Test-only email login, disabled by default. Explicit development opt-in is required; production always rejects it. Use GitHub/Google OAuth or device approval.
Request body · required · application/json
| Field | Type | Details |
|---|---|---|
emailrequired | string | format: email |
nameoptional | string | See full definition. |
{ "type": "object", "required": [ "email" ], "properties": { "email": { "type": "string", "format": "email" }, "name": { "type": "string" } }}Responses
200Tokens200 response schema · application/json
Field Type Details useroptionalobject See full definition. orgoptionalobject See full definition. tokensoptionalTokens See full definition. AuthResponse · JSON Schema{ "type": "object", "properties": { "user": { "type": "object" }, "org": { "type": "object" }, "tokens": { "$ref": "#/components/schemas/Tokens" } }}401No such user403Development authentication is disabled
/auth/logoutNo Bearer authClear browser session cookies and revoke the supplied refresh token
Reads the refresh token from the browser cookie or JSON body. Existing short-lived access tokens expire normally. Does not revoke API keys.
Request body · optional · application/json
| Field | Type | Details |
|---|---|---|
refresh_tokenoptional | string | Refresh token to revoke; optional when the browser cookie is present |
{ "type": "object", "properties": { "refresh_token": { "type": "string", "description": "Refresh token to revoke; optional when the browser cookie is present" } }}Responses
200Signed out200 response schema · application/json
Field Type Details statusoptionalstring values: ok JSON Schema{ "type": "object", "properties": { "status": { "type": "string", "enum": [ "ok" ] } }}
/auth/refreshNo Bearer authExchange a refresh token for a new token pair
Request body · required · application/json
| Field | Type | Details |
|---|---|---|
refresh_tokenoptional | string | See full definition. |
{ "type": "object", "properties": { "refresh_token": { "type": "string" } }}Responses
200Tokens200 response schema · application/json
Field Type Details access_tokenoptionalstring See full definition. refresh_tokenoptionalstring See full definition. expires_inoptionalinteger See full definition. token_typeoptionalstring See full definition. Tokens · JSON Schema{ "type": "object", "properties": { "access_token": { "type": "string" }, "refresh_token": { "type": "string" }, "expires_in": { "type": "integer" }, "token_type": { "type": "string" } }}
/auth/providersNo Bearer authList configured public sign-in providers
Available in production; returns only provider names and no credentials or internal status.
Responses
200Configured OAuth providers200 response schema · application/json
Field Type Details providersoptionalstring[] See full definition. JSON Schema{ "type": "object", "properties": { "providers": { "type": "array", "items": { "type": "string", "enum": [ "github", "google" ] } } }}
/auth/oauth/{provider}No Bearer authBegin an OAuth flow (github|google)
Parameters
| Name / location | Type | Details |
|---|---|---|
providerpath · required | string | values: github, google |
Responses
302Redirect to the provider
/auth/oauth/{provider}/callbackNo Bearer authComplete a browser-bound OAuth flow with PKCE
Requires verified provider email and a stable provider ID. Redirects to the dashboard with a short-lived single-use exchange code; never returns tokens in a browser URL.
Parameters
| Name / location | Type | Details |
|---|---|---|
providerpath · required | string | |
codequery · required | string | |
statequery · required | string |
Responses
302Dashboard exchange or sign-in error redirect400Invalid browser state or PKCE binding
/auth/device/codeNo Bearer authStart a device-authorization flow (CLI/GUI login)
Responses
200Device + user codes200 response schema · application/json
Field Type Details device_codeoptionalstring See full definition. user_codeoptionalstring See full definition. verification_urioptionalstring See full definition. verification_uri_completeoptionalstring See full definition. intervaloptionalinteger See full definition. expires_inoptionalinteger See full definition. DeviceCode · JSON Schema{ "type": "object", "properties": { "device_code": { "type": "string" }, "user_code": { "type": "string" }, "verification_uri": { "type": "string" }, "verification_uri_complete": { "type": "string" }, "interval": { "type": "integer" }, "expires_in": { "type": "integer" } }}
/auth/device/approveBearer authApprove a device user code (browser, authenticated)
Request body · required · application/json
| Field | Type | Details |
|---|---|---|
user_codeoptional | string | See full definition. |
{ "type": "object", "properties": { "user_code": { "type": "string" } }}Responses
200Approved
/auth/device/tokenNo Bearer authPoll for the device API key
Request body · required · application/json
| Field | Type | Details |
|---|---|---|
device_codeoptional | string | See full definition. |
{ "type": "object", "properties": { "device_code": { "type": "string" } }}Responses
200API key200 response schema · application/json
Field Type Details api_keyoptionalstring See full definition. JSON Schema{ "type": "object", "properties": { "api_key": { "type": "string" } }}400authorization_pending | expired_token | invalid_device_code
Account
/accountBearer authThe authenticated user and their orgs
User profile for a dashboard JWT. API-key callers should use /me because they identify an organization rather than a user subject.
Responses
200Account404User profile not found for this principal
Profile & effective plan
/meBearer authProfile, organization, effective plan and usage for a JWT or API key
API-key callers receive the organization owner's profile. Expired paid grants use the effective Free plan.
Responses
200Account snapshot200 response schema · application/json
Field Type Details useroptionalobject See full definition. orgoptionalobject See full definition. planoptionalstring See full definition. plan_expires_atoptionalstring | null format: date-time via_api_keyoptionalboolean See full definition. usageoptionalobject See full definition. limitsoptionalobject See full definition. JSON Schema{ "type": "object", "properties": { "user": { "type": "object" }, "org": { "type": "object" }, "plan": { "type": "string" }, "plan_expires_at": { "type": [ "string", "null" ], "format": "date-time" }, "via_api_key": { "type": "boolean" }, "usage": { "type": "object" }, "limits": { "type": "object" } }}
API keys
/api-keysBearer authList API keys (prefixes only)
Responses
200Keys
/api-keysBearer authCreate an API key (plaintext returned once)
Request body · optional · application/json
| Field | Type | Details |
|---|---|---|
nameoptional | string | See full definition. |
{ "type": "object", "properties": { "name": { "type": "string" } }}Responses
201Created201 response schema · application/json
Field Type Details idoptionalstring See full definition. nameoptionalstring See full definition. prefixoptionalstring See full definition. api_keyoptionalstring Plaintext, shown once CreatedAPIKey · JSON Schema{ "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "prefix": { "type": "string" }, "api_key": { "type": "string", "description": "Plaintext, shown once" } }}
/api-keys/{id}Bearer authRevoke an API key
Parameters
| Name / location | Type | Details |
|---|---|---|
idpath · required | string |
Responses
204Revoked
Reserved subdomains
/subdomainsBearer authList reserved subdomains
Responses
200OK
/subdomainsBearer authReserve a subdomain (subject to plan limits)
Request body · optional · application/json
| Field | Type | Details |
|---|---|---|
subdomainoptional | string | See full definition. |
{ "type": "object", "properties": { "subdomain": { "type": "string" } }}Responses
201Reserved403Plan limit reached409Subdomain already taken
/subdomains/{id}Bearer authRelease a reserved subdomain
Parameters
| Name / location | Type | Details |
|---|---|---|
idpath · required | string |
Responses
204Released
Custom domains
/domainsBearer authList custom domains
Responses
200OK
/domainsBearer authAdd a custom domain (returns DNS verification instructions)
Request body · optional · application/json
| Field | Type | Details |
|---|---|---|
domainoptional | string | See full definition. |
{ "type": "object", "properties": { "domain": { "type": "string" } }}Responses
201Added403Plan does not allow custom domains
/domains/{id}/verifyBearer authVerify a custom domain via DNS TXT
Parameters
| Name / location | Type | Details |
|---|---|---|
idpath · required | string |
Responses
200Verified400DNS record not found yet
Usage
/usageBearer authUsage for the active org (last 30 days)
Responses
200OK
/usage/historyBearer authUsage time series for the active org (bucket=hour|day, days=N), for dashboard graphs
Parameters
| Name / location | Type | Details |
|---|---|---|
bucketquery · optional | string | values: hour, day |
daysquery · optional | integer |
Responses
200OK
Organizations
/orgsBearer authOrgs the caller belongs to
Responses
200OK
Tunnel sessions
/tunnelsBearer authLive (active) tunnel sessions for the organization
Read-only list reported by the edge, capped at 200 sessions. This endpoint does not create or stop a local tunnel.
Responses
200OK
/tunnels/historyBearer authPaginated tunnel-session history for the org (active + closed)
Parameters
| Name / location | Type | Details |
|---|---|---|
activequery · optional | boolean | Use true to return active sessions only |
limitquery · optional | integer | Page size, capped at 200default: 50; minimum: 1; maximum: 200 |
offsetquery · optional | integer | Number of sessions to skipdefault: 0; minimum: 0 |
Responses
200OK
Plans
/plansBearer authThe plan/quota catalog
Responses
200OK
/plans/publicNo Bearer authThe plan/quota catalog, unauthenticated (build-time consumption by the marketing site)
Responses
200OK
Regions
/regionsNo Bearer authThe edge PoP catalog (code, city, endpoint) for region selection
Responses
200OK
Location
/geoNo Bearer authDetect the caller's country and recommend the nearest edge region
Parameters
| Name / location | Type | Details |
|---|---|---|
ipquery · optional | string | Override IP (dev only) |
Responses
200OK
QR remote control
/remote/sessionsBearer authStart a /qr remote-control pairing session (CLI console, authenticated)
Responses
201Pairing code + viewer URL201 response schema · application/json
Field Type Details codeoptionalstring Pairing code — also the viewer URL's capability token urloptionalstring https://qr.<base>/<code> expires_atoptionalstring format: date-time RemoteSession · JSON Schema{ "type": "object", "properties": { "code": { "type": "string", "description": "Pairing code — also the viewer URL's capability token" }, "url": { "type": "string", "description": "https://qr.<base>/<code>" }, "expires_at": { "type": "string", "format": "date-time" } }}
/remote/sessions/{code}/agentBearer authConsole (agent) side event stream — inbound commands/presence/ended (SSE)
Parameters
| Name / location | Type | Details |
|---|---|---|
codepath · required | string |
Responses
200text/event-stream of RemoteEvent frames404No such session
/remote/sessions/{code}/publishBearer authConsole (agent) side — publish transcript lines or a state snapshot to viewers
Parameters
| Name / location | Type | Details |
|---|---|---|
codepath · required | string |
Request body · required · application/json
| Field | Type | Details |
|---|---|---|
typeoptional | string | values: lines, state, command, presence, ended |
linesoptional | string[] | See full definition. |
stateoptional | object | See full definition. |
commandoptional | string | See full definition. |
connectedoptional | boolean | See full definition. |
{ "type": "object", "description": "One envelope shape for both the agent and viewer streams; fields present depend on type.", "properties": { "type": { "type": "string", "enum": [ "lines", "state", "command", "presence", "ended" ] }, "lines": { "type": "array", "items": { "type": "string" } }, "state": { "type": "object", "properties": { "online": { "type": "boolean" }, "edge": { "type": "string" }, "tunnels": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "public_url": { "type": "string" }, "local_addr": { "type": "string" }, "status": { "type": "string" }, "requests": { "type": "integer" } } } } } }, "command": { "type": "string" }, "connected": { "type": "boolean" } }}Responses
204Delivered (fanned out to any connected viewers)404No such session
/remote/sessions/{code}/endBearer authConsole (agent) side — end the pairing early
Parameters
| Name / location | Type | Details |
|---|---|---|
codepath · required | string |
Responses
204Ended; viewers see a final "ended" event404No such session
/remote/sessions/{code}/viewerNo Bearer authPhone/browser side event stream — transcript/state/presence/ended (SSE, public)
No login: the code itself, embedded in the QR/link the console shows, is the capability. Replays recent transcript + the last known state on connect.
Parameters
| Name / location | Type | Details |
|---|---|---|
codepath · required | string |
Responses
200text/event-stream of RemoteEvent frames404No such session
/remote/sessions/{code}/commandNo Bearer authPhone/browser side — send a command to the paired console (public)
Parameters
| Name / location | Type | Details |
|---|---|---|
codepath · required | string |
Request body · required · application/json
| Field | Type | Details |
|---|---|---|
textrequired | string | maxLength: 240 |
{ "type": "object", "required": [ "text" ], "properties": { "text": { "type": "string", "maxLength": 240 } }}Responses
204Delivered to the attached console404No such session409No console is currently attached to this session
Optional billing integration
/billing/checkoutBearer authCreate a Stripe Checkout Session to subscribe to / change plan (Part 07)
Optional operator-enabled Stripe integration. The hosted website may use a manual contact-based upgrade flow instead.
Request body · required · application/json
| Field | Type | Details |
|---|---|---|
planrequired | string | values: pro, team, payg |
cadenceoptional | string | values: monthly, annual, metered; default: "monthly" |
{ "type": "object", "required": [ "plan" ], "properties": { "plan": { "type": "string", "enum": [ "pro", "team", "payg" ] }, "cadence": { "type": "string", "enum": [ "monthly", "annual", "metered" ], "default": "monthly" } }}Responses
200Checkout URL200 response schema · application/json
Field Type Details urloptionalstring See full definition. session_idoptionalstring See full definition. JSON Schema{ "type": "object", "properties": { "url": { "type": "string" }, "session_id": { "type": "string" } }}400Unknown/non-billable plan or no price configured503Stripe not configured
/billing/portalBearer authCreate a Stripe Customer-Portal session (manage/cancel/invoices)
Responses
200Portal URL200 response schema · application/json
Field Type Details urloptionalstring See full definition. JSON Schema{ "type": "object", "properties": { "url": { "type": "string" } }}400No subscription to manage yet503Stripe not configured
/billing/subscriptionBearer authThe caller org's current plan + subscription
Responses
200Subscription state200 response schema · application/json
Field Type Details planoptionalstring See full definition. billing_enabledoptionalboolean See full definition. subscriptionoptionalSubscription See full definition. JSON Schema{ "type": "object", "properties": { "plan": { "type": "string" }, "billing_enabled": { "type": "boolean" }, "subscription": { "$ref": "#/components/schemas/Subscription" } }}
/billing/webhooksNo Bearer authStripe webhook receiver (public; Stripe-Signature verified). Source of truth for plan state.
Parameters
| Name / location | Type | Details |
|---|---|---|
Stripe-Signatureheader · required | string |
Responses
200Processed (or duplicate ignored)400Invalid signature or payload503Webhook secret not configured
Named schemas
References such as #/components/schemas/Tokens refer to the definitions below. These are JSON Schema definitions, not credential values or example responses.
SignupRequest
| Field | Type | Details |
|---|---|---|
emailrequired | string | format: email |
nameoptional | string | See full definition. |
{ "type": "object", "required": [ "email" ], "properties": { "email": { "type": "string", "format": "email" }, "name": { "type": "string" } }}Tokens
| Field | Type | Details |
|---|---|---|
access_tokenoptional | string | See full definition. |
refresh_tokenoptional | string | See full definition. |
expires_inoptional | integer | See full definition. |
token_typeoptional | string | See full definition. |
{ "type": "object", "properties": { "access_token": { "type": "string" }, "refresh_token": { "type": "string" }, "expires_in": { "type": "integer" }, "token_type": { "type": "string" } }}AuthResponse
| Field | Type | Details |
|---|---|---|
useroptional | object | See full definition. |
orgoptional | object | See full definition. |
tokensoptional | Tokens | See full definition. |
{ "type": "object", "properties": { "user": { "type": "object" }, "org": { "type": "object" }, "tokens": { "$ref": "#/components/schemas/Tokens" } }}DeviceCode
| Field | Type | Details |
|---|---|---|
device_codeoptional | string | See full definition. |
user_codeoptional | string | See full definition. |
verification_urioptional | string | See full definition. |
verification_uri_completeoptional | string | See full definition. |
intervaloptional | integer | See full definition. |
expires_inoptional | integer | See full definition. |
{ "type": "object", "properties": { "device_code": { "type": "string" }, "user_code": { "type": "string" }, "verification_uri": { "type": "string" }, "verification_uri_complete": { "type": "string" }, "interval": { "type": "integer" }, "expires_in": { "type": "integer" } }}CreatedAPIKey
| Field | Type | Details |
|---|---|---|
idoptional | string | See full definition. |
nameoptional | string | See full definition. |
prefixoptional | string | See full definition. |
api_keyoptional | string | Plaintext, shown once |
{ "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "prefix": { "type": "string" }, "api_key": { "type": "string", "description": "Plaintext, shown once" } }}Subscription
| Field | Type | Details |
|---|---|---|
idoptional | string | See full definition. |
org_idoptional | string | See full definition. |
stripe_subscription_idoptional | string | See full definition. |
stripe_customer_idoptional | string | See full definition. |
planoptional | string | values: free, pro, team, payg |
statusoptional | string | values: active, trialing, past_due, canceled, incomplete |
current_period_endoptional | string | format: date-time |
cancel_at_period_endoptional | boolean | See full definition. |
{ "type": "object", "properties": { "id": { "type": "string" }, "org_id": { "type": "string" }, "stripe_subscription_id": { "type": "string" }, "stripe_customer_id": { "type": "string" }, "plan": { "type": "string", "enum": [ "free", "pro", "team", "payg" ] }, "status": { "type": "string", "enum": [ "active", "trialing", "past_due", "canceled", "incomplete" ] }, "current_period_end": { "type": "string", "format": "date-time" }, "cancel_at_period_end": { "type": "boolean" } }}RemoteSession
| Field | Type | Details |
|---|---|---|
codeoptional | string | Pairing code — also the viewer URL's capability token |
urloptional | string | https://qr.<base>/<code> |
expires_atoptional | string | format: date-time |
{ "type": "object", "properties": { "code": { "type": "string", "description": "Pairing code — also the viewer URL's capability token" }, "url": { "type": "string", "description": "https://qr.<base>/<code>" }, "expires_at": { "type": "string", "format": "date-time" } }}RemoteEvent
| Field | Type | Details |
|---|---|---|
typeoptional | string | values: lines, state, command, presence, ended |
linesoptional | string[] | See full definition. |
stateoptional | object | See full definition. |
commandoptional | string | See full definition. |
connectedoptional | boolean | See full definition. |
{ "type": "object", "description": "One envelope shape for both the agent and viewer streams; fields present depend on type.", "properties": { "type": { "type": "string", "enum": [ "lines", "state", "command", "presence", "ended" ] }, "lines": { "type": "array", "items": { "type": "string" } }, "state": { "type": "object", "properties": { "online": { "type": "boolean" }, "edge": { "type": "string" }, "tunnels": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "public_url": { "type": "string" }, "local_addr": { "type": "string" }, "status": { "type": "string" }, "requests": { "type": "integer" } } } } } }, "command": { "type": "string" }, "connected": { "type": "boolean" } }}