Complete reference for the Listener Price Oracle (LPO) and Listener Report Service (LRS)
All API requests require a Bearer token in the Authorization header.
Authorization: Bearer YOUR_API_KEY
Your API key is provided after subscribing. Keep it secret — it identifies your account for billing and rate limiting.
The LPO delivers real-time cryptocurrency prices with sub-2ms cached responses. Prices are sourced from 6 persistent WebSocket feeds (Coinbase, Gemini, Kraken, Gate.io, Crypto.com, OKX) — 150 prewarmed assets pushed in real-time with zero REST polling. REST fallback (Gemini → Coinbase → Kraken) activates only if all WebSocket feeds for an asset are stale.
Returns the current price for a cryptocurrency asset.
| Parameter | Type | Required | Description |
|---|---|---|---|
asset | string | Required | Asset symbol (e.g. btc, eth, sol). Case-insensitive. |
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://api.cpmp-site.org/price?asset=btc"
Returns current prices for multiple cryptocurrency assets in a single request. Fetch up to 30 assets at once — perfect for portfolio dashboards, watchlists, and batch operations. The entire batch counts as 1 request against your rate limits and monthly quota, rewarding efficient API usage.
/prices call with 30 assets counts as 1 request — not 30. Partners and developers who batch their requests are being good API citizens, and we reward that efficiency. Available on all tiers including Free.
| Field | Type | Required | Description |
|---|---|---|---|
assets | string[] | Required | Array of asset symbols (e.g. ["BTC", "ETH", "SOL"]). Case-insensitive. Maximum 30 assets per request. Duplicates are automatically deduplicated. |
curl -X POST -H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"assets": ["BTC", "ETH", "SOL", "DOGE", "XRP"]}' \
"https://api.cpmp-site.org/prices"
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/prices] [200]",
"status_code": 200,
"endpoint": "/prices",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbts/v1",
"timestamp": "2026-05-28T20:32:08Z",
"data": {
"prices": {
"BTC": {
"exchange": "coinbase-ws",
"cached": true,
"cache_age_seconds": 0.082,
"timestamp": 1780000328,
"price": "73551.36"
},
"ETH": {
"exchange": "coinbase-ws",
"cached": true,
"cache_age_seconds": 0.081,
"timestamp": 1780000328,
"price": "2016.48"
},
"SOL": {
"exchange": "coinbase-ws",
"cached": true,
"cache_age_seconds": 0.217,
"timestamp": 1780000328,
"price": "82.36"
},
"DOGE": {
"exchange": "coinbase-ws",
"cached": true,
"cache_age_seconds": 4.501,
"timestamp": 1780000324,
"price": "0.09983"
},
"XRP": {
"exchange": "coinbase-ws",
"cached": true,
"cache_age_seconds": 1.389,
"timestamp": 1780000327,
"price": "1.3207"
}
},
"asset_count": 5,
"resolved_count": 5,
"failed": [],
"latency_ms": 0,
"duration_ms": 12,
"monthly_usage": 4521,
"monthly_limit": 100000,
"usage_pct": 4.52,
"usage_warning": "",
"usage_status": "✅"
},
"error": ""
}
data)| Field | Type | Description |
|---|---|---|
prices | object | Map of asset symbol → price data. Each entry contains exchange, cached, cache_age_seconds, timestamp, and price. |
asset_count | int | Number of unique assets requested (after deduplication) |
resolved_count | int | Number of assets successfully resolved |
failed | string[] | Array of asset symbols that could not be resolved (empty on full success) |
latency_ms | int | Sum of exchange lookup latencies for cache misses (0 if all cached) |
duration_ms | int | Total wall-clock processing time |
monthly_usage | int | Number of requests used this month |
monthly_limit | int | Maximum requests allowed per month for your tier |
usage_pct | float | Current usage as a percentage of monthly limit |
usage_warning | string | Graduated warning: "green" (≥85%), "yellow" (≥90%), "red" (≥95%), or "" |
usage_status | string | Visual indicator: ✅, ✅🟡, ✅⚠️, or ✅🔴 |
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/prices] [200]",
...
"data": {
"prices": {
"BTC": { "exchange": "coinbase-ws", "cached": true, ... },
"ETH": { "exchange": "coinbase-ws", "cached": true, ... }
},
"asset_count": 3,
"resolved_count": 2,
"failed": ["FAKECOIN"],
...
}
}
prices, and every asset that didn't in failed. One round-trip, useful data on the first call, no client-side retry logic required. Partial failures don't break your batch.
{
"status": "🛑 [LPO] [us-east-2] [BeastMain] [/prices] [400]",
"status_code": 400,
"endpoint": "/prices",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbts/v1",
"timestamp": "2026-05-28T20:32:23Z",
"data": null,
"error": "🛑 [LPO] [us-east-2] [BeastMain] [/prices] [400] Maximum 30 assets per request"
}
["BTC", "btc", "Btc"], the response will contain a single "BTC" entry. Asset symbols are normalized to uppercase and deduplicated before processing.
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/price] [200]",
"status_code": 200,
"endpoint": "/price",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbts/v1",
"timestamp": "2026-04-12T14:23:01Z",
"data": {
"usage_status": "✅",
"api_key_id": "key_abc123",
"asset": "BTC",
"price": "83421.57",
"source": "coinbase-ws",
"timestamp": 1744466581,
"readable_timestamp": "2026-04-12T14:23:01Z",
"latency_ms": 0,
"duration_ms": 0,
"cached": true,
"cache_duration_seconds": 4.2,
"monthly_usage": 42,
"monthly_limit": 1000,
"usage_pct": 4.2,
"usage_warning": "",
"ip_address": "203.0.113.42"
},
"error": ""
}
{
"status": "✅ [LPO] [us-east-2] [BeastMirror] [/price] [200]",
"status_code": 200,
"endpoint": "/price",
"cluster_node": "BeastMirror",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbts/v1",
"timestamp": "2026-04-12T14:23:15Z",
"data": {
"usage_status": "✅",
"api_key_id": "key_abc123",
"asset": "ETH",
"price": "3187.44",
"source": "kraken",
"timestamp": 1744466595,
"readable_timestamp": "2026-04-12T14:23:15Z",
"latency_ms": 38,
"duration_ms": 38,
"cached": false,
"cache_duration_seconds": 0,
"monthly_usage": 43,
"monthly_limit": 1000,
"usage_pct": 4.3,
"usage_warning": "",
"ip_address": "203.0.113.42"
},
"error": ""
}
As monthly usage approaches the query limit, the data.usage_status field includes graduated warning indicators. Thresholds are runtime-tunable via application parameters.
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/price] [200]",
...
"data": {
"usage_status": "✅🟡",
...
"monthly_usage": 855,
"monthly_limit": 1000,
"usage_pct": 85.5,
"usage_warning": "green",
...
},
"error": ""
}
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/price] [200]",
...
"data": {
"usage_status": "✅⚠️",
...
"monthly_usage": 910,
"monthly_limit": 1000,
"usage_pct": 91.0,
"usage_warning": "yellow",
...
},
"error": ""
}
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/price] [200]",
...
"data": {
"usage_status": "✅🔴",
...
"monthly_usage": 960,
"monthly_limit": 1000,
"usage_pct": 96.0,
"usage_warning": "red",
...
},
"error": ""
}
data.monthly_usage approaches data.monthly_limit, the response includes graduated indicators at three configurable thresholds:
✅🟡 — Heads up: usage is climbing✅⚠️ — Caution: approaching your limit✅🔴 — Critical: near your monthly limitusage_warning field is an empty string ("") when usage is below the green threshold. The usage_pct field is always present. Both fields appear in every response — the JSON schema is always consistent. Thresholds are configurable via usage_warning_green_pct, usage_warning_yellow_pct, and usage_warning_red_pct application parameters.
The /price endpoint returns the standard 12-field UME envelope. Price data is nested inside the data field:
| Field | Type | Description |
|---|---|---|
status | string | Color-coded bracket line: ✅ [LPO] [us-east-2] [BeastMain] [/price] [200] |
status_code | int | HTTP status code as integer |
endpoint | string | The URL path that handled the request |
cluster_node | string | Container that served the request (BeastMain, BeastMirror, BeastLRS) |
region | string | AWS region — us-east-2 |
language | string | ISO 639-1 language code for human-readable content |
timestamp | string | RFC 3339 UTC timestamp of response generation |
data | object | Price data payload (see below). null on error. |
error | string | Empty string on success. Full bracketed error message on failure. |
data)| Field | Type | Description |
|---|---|---|
usage_status | string | ✅ on success, ✅🟡 at green warning, ✅⚠️ at yellow warning, ✅🔴 at red warning |
api_key_id | string | Your API key |
asset | string | Uppercase asset symbol |
price | string | Current price in USD (formatted to 9 decimal places, trailing zeros trimmed) |
source | string | Price source tag. WebSocket (real-time): coinbase-ws, gemini-ws, kraken-ws, gateio-ws, cryptocom-ws, okx-ws. REST fallback: coinbase, gemini, kraken, gateio, cryptocom, okx. |
timestamp | int64 | Unix timestamp of the price |
readable_timestamp | string | RFC3339 formatted timestamp |
latency_ms | int64 | Time to fetch price from exchange (0 on cache hit) |
duration_ms | int64 | Total request processing time including validation |
cached | bool | Whether the response was served from cache |
cache_duration_seconds | float64 | Age of cached value in seconds (0 if live fetch) |
monthly_usage | int | Number of queries used this month |
monthly_limit | int | Maximum queries allowed per month for your tier |
usage_pct | float64 | Current usage as a percentage of monthly limit (always present) |
usage_warning | string | Graduated warning level: "green" (≥85%), "yellow" (≥90%), "red" (≥95%), or "" (empty string when below green threshold). Always present. |
ip_address | string | Client IP address |
The LRS provides access to your API usage history and aggregated statistics. Included with every subscription tier.
Returns paginated usage log entries for your API key.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
api_key_id | string | Optional | — | Filter by API key ID |
asset | string | Optional | — | Filter by asset symbol (e.g. BTC) |
start_date | string | Optional | 93 days ago | Start date in YYYY-MM-DD format |
end_date | string | Optional | Today | End date in YYYY-MM-DD format |
cached | bool | Optional | — | Filter by cache status: true or false |
page | int | Optional | 1 | Page number |
page_size | int | Optional | 100 | Records per page (max 1000) |
format | string | Optional | json | Output format: json, csv, tsv, text |
# JSON (default)
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://lrs.cpmp-site.org/reports/usage?asset=BTC&page=1&page_size=50"
# CSV download
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://lrs.cpmp-site.org/reports/usage?format=csv" -o usage.csv
# Tab-delimited
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://lrs.cpmp-site.org/reports/usage?format=tsv" -o usage.tsv
# Plain text
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://lrs.cpmp-site.org/reports/usage?format=text"
Returns aggregated statistics for a date range.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
api_key_id | string | Optional | — | Filter by API key ID |
start_date | string | Optional | 30 days ago | Start date in YYYY-MM-DD format |
end_date | string | Optional | Today | End date in YYYY-MM-DD format |
format | string | Optional | json | Output format: json, csv, tsv, text |
| Format | Content-Type | Use Case |
|---|---|---|
json | application/json | Default. Best for programmatic consumption and APIs. |
csv | text/csv | Comma-separated. Import into Excel, Google Sheets, or any CSV-compatible tool. |
tsv | text/tab-separated-values | Tab-delimited. Ideal for databases, ETL pipelines, and tools that handle commas in data. |
text | text/plain | Human-readable plain text. Good for quick terminal review or log files. |
{
"logs": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"api_key_id": "key_abc123",
"asset": "BTC",
"price": 83421.57,
"source": "coinbase",
"cached": true,
"latency_ms": 7,
"duration_ms": 7,
"ip_address": "203.0.113.42",
"timestamp": 1744466581,
"readable_timestamp": "2026-04-12T14:23:01Z",
"cache_age_seconds": 4.2
}
],
"total_count": 1482,
"page": 1,
"page_size": 100,
"filters": {
"asset": "BTC"
}
}
id,api_key_id,asset,price,source,cached,latency_ms,duration_ms,ip_address,timestamp,readable_timestamp,cache_age_seconds
a1b2c3d4-e5f6-7890-abcd-ef1234567890,key_abc123,BTC,83421.57000000,coinbase,true,7,7,203.0.113.42,1744466581,2026-04-12T14:23:01Z,4.200
LRS Usage Report — Page 1 | Page Size 100 | Total Records 1482
================================================================================
[2026-04-12T14:23:01Z] a1b2c3d4... | Asset: BTC | Price: 83421.57000000 | Source: coinbase | Cached: true | Latency: 7ms | IP: 203.0.113.42
{
"total_requests": 14820,
"cache_hit_rate": 91.4,
"avg_latency_ms": 9.3,
"by_asset": {
"BTC": 6210,
"ETH": 4105,
"SOL": 2380,
"DOGE": 1240,
"XRP": 885
},
"by_source": {
"coinbase": 13540,
"kraken": 1180,
"gemini": 100
},
"date_range": {
"start": "2026-03-13",
"end": "2026-04-12"
}
}
LRS Summary Report — 2026-03-13 to 2026-04-12
============================================================
Total Requests : 14820
Cache Hit Rate : 91.40%
Avg Latency : 9.30ms
By Asset:
BTC 6210
ETH 4105
SOL 2380
By Source:
coinbase 13540
kraken 1180
gemini 100
The Trinity Beast LPO serves 150 prewarmed assets across 6 exchanges via persistent WebSocket connections. Each exchange maintains 25 unique assets with zero overlap — every asset is served by exactly one exchange. Prices arrive in real-time (push-based) before any request is made.
| Exchange | Source Tag | WebSocket Endpoint | Pair Suffix | Assets |
|---|---|---|---|---|
| Coinbase | coinbase-ws | wss://advanced-trade-ws.coinbase.com | USD | 25 |
| Gemini | gemini-ws | wss://ws.gemini.com | USD | 25 |
| Kraken | kraken-ws | wss://ws.kraken.com/v2 | USD | 25 |
| Gate.io | gateio-ws | wss://api.gateio.ws/ws/v4/ | USDT | 25 |
| Crypto.com | cryptocom-ws | wss://stream.crypto.com/exchange/v1/market | USD | 25 |
| OKX | okx-ws | wss://ws.okx.com:8443/ws/v5/public | USDT | 25 |
BTC · ETH · SOL · DOGE · XRP · LINK · DOT · LTC · AVAX · UNI · PEPE · XLM · ETC · ICP · RENDER · BONK · BCH · JASMY · AXS · CHZ · STORJ · ZEC · DASH · CGLD · NEAR
AAVE · ATOM · ARB · CRV · GRT · FIL · SHIB · BAT · LRC · MASK · ANKR · SKL · API3 · QNT · HYPE · LPT · HNT · UMA · JTO · CTX · POL · PNUT · POPCAT · DRIFT · CUBE
NANO · SC · LSK · KAVA · BICO · RARI · OCEAN · CFG · CQT · ALGO · FET · FLOW · XTZ · QTUM · ICX · ASTR · ENJ · EGLD · COTI · MINA · GLMR · MOVR · KSM · TEER · CRO
BNB · TRX · APT · SEI · INJ · OP · SUI · VET · HBAR · SAND · MANA · S · CHR · FLR · THETA · CELR · REEF · DENT · HOT · POND · IOTX · ALICE · SUPER · FLUX · ONE
TON · WLD · APE · BLUR · IMX · ENS · LDO · SNX · COMP · 1INCH · SUSHI · GALA · MAGIC · ORDI · PIXEL · RUNE · ARKM · DYM · GMX · CRO · TAO · AGLD · AR · AUDIO · POL
TIA · JUP · STRK · PYTH · W · ZRO · PENDLE · ONDO · WIF · FLOKI · NOT · AEVO · ENA · ETHFI · TURBO · NEIRO · DOGS · HMSTR · EIGEN · BOME · KAITO · GRASS · BANANA · ACE · TNSR
| Priority | Source | Source Tag | Timeout | Weight |
|---|---|---|---|---|
| 1 | Gemini | gemini | 120ms | 0.15 |
| 2 | Coinbase | coinbase | 100ms | 0.50 |
| 3 | Kraken | kraken | 80ms | 0.35 |
REST fallback is rarely triggered — with 6 WebSocket feeds pushing prices in real-time, the cache hit rate is 98.5%+. REST sources are only consulted when an asset's WebSocket price is older than the cache_ttl_seconds threshold (currently 300 seconds).
GET /asset-categories endpoint for a category-grouped listing of all available assets. The GET /exchanges endpoint returns the full exchange configuration including WebSocket endpoints and asset mappings.
| Indicator | Meaning | When It Appears |
|---|---|---|
| ✅ | Success | Every successful price response (usage below green threshold) |
| ✅🟡 | Success with green warning | Monthly usage is at or above 85% of your limit (configurable via usage_warning_green_pct) |
| ✅⚠️ | Success with yellow warning | Monthly usage is at or above 90% of your limit (configurable via usage_warning_yellow_pct) |
| ✅🔴 | Success with red warning | Monthly usage is at or above 95% of your limit (configurable via usage_warning_red_pct) |
| ⚠️ | Rate limit warning | Monthly query limit reached or QPS rate limit exceeded |
| 🛑 | Error | Invalid request, authentication failure, or server error |
All error responses use the unified response envelope with color-coded bracket convention. The status field shows the indicator and origin metadata. The error field contains the full bracketed message.
{
"status": "🛑 [LPO] [us-east-2] [BeastMain] [/price] [401]",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbts/v1",
"status_code": 401,
"endpoint": "/price",
"cluster_node": "BeastMain",
"region": "us-east-2",
"timestamp": "2026-04-26T16:20:03Z",
"error": "🛑 [LPO] [us-east-2] [BeastMain] [/price] [401] Missing required API key parameter"
}
{
"status": "🛑 [LPO] [us-east-2] [BeastMirror] [/price] [429]",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbts/v1",
"error": "🛑 [LPO] [us-east-2] [BeastMirror] [429] ⚠️ Monthly query limit reached. You have used 1000 of 1000 allowed queries this month. Upgrade your plan for higher limits.",
"code": 429,
"region": "us-east-2",
"cluster_node": "BeastMirror"
}
| HTTP Status | Meaning | Common Cause |
|---|---|---|
400 | Bad Request | Missing or invalid asset parameter. |
401 | Unauthorized | Missing, invalid, or revoked API key. |
429 | Too Many Requests | Monthly query limit reached or QPS rate limit exceeded. Message includes your current usage and limit. |
500 | Internal Server Error | All price sources (WebSocket + REST) failed or database connectivity issue. |
503 | Service Unavailable | ElastiCache health check failed. |
| Tier | Requests/Month | LRS Included | Price |
|---|---|---|---|
| Free | 1,000 | 10 reports/month | $0/mo |
| Pro | 50,000 | 10 reports/month | $30/mo |
| Enterprise | 500,000 | 10 reports/month | $100/mo |
| Unlimited | Unlimited | Unlimited | $300/mo |
| Lifetime | Unlimited forever | Unlimited forever | $3,000 one-time |
| AWS Partner | Unlimited — no rate limiting | Unlimited | $0 — always free |
| Service | Protocol | Endpoint | Port |
|---|---|---|---|
| LPO (Price API) | HTTPS | https://api.cpmp-site.org | 443 |
| LRS (Reports) | HTTPS | https://lrs.cpmp-site.org | 443 |
| LPO (UDP) | UDP | udp.cpmp-site.org | 2679 |
| LRS (UDP) | UDP | udp.cpmp-site.org | 2680 |
| PrivateLink (LPO) | TCP | VPC Endpoint → NLB | 8080 |
| PrivateLink (LRS) | TCP | VPC Endpoint → NLB | 9090 |
| Method | Path | Description |
|---|---|---|
GET | /exchanges | Public exchange asset list for demo dropdown |
GET | /asset-categories | Asset categories for demo dropdown NEW |
GET | /map/pins | Mission impact map pins |
POST | /translate | Real-time text translation (AWS Translate, cached in ElastiCache) |
GET | /search | Full-text document search (Valkey-indexed, multi-lingual) NEW |
POST | /support/submit | Submit support ticket |
GET | /support/tickets | List tickets by email |
GET | /support/ticket/{ticket_number} | View ticket detail |
GET | /support/resolve | One-click ticket resolve via email link. Query: ?token=.... Single-use, 30-day TTL. NEW |
POST | /demo/register | Demo lead registration NEW |
POST | /partner/apply | Partner application submission |
GET | /partner/status | Partner application status check |
POST | /newsletter/subscribe | Newsletter subscribe |
GET | /newsletter/unsubscribe | Newsletter unsubscribe |
GET | /newsletter/resubscribe | Newsletter resubscribe |
GET | /admin/bootstrap-key | One-time admin key setup |
GET | /checkout | Public checkout redirect (Stripe Payment Link) NEW |
GET | /public/status | Public system status — nodes, feeds, uptime (no auth) |
GET | /public/cluster | Public ECS cluster stats — per-node metrics, cache hit rates (no auth) NEW |
| Method | Path | Description |
|---|---|---|
GET | /admin/config | View application parameters |
GET | /admin/setup-demo | Setup demo API key |
GET | /admin/invalidate-key | Invalidate API key cache |
GET | /admin/demo-mode | Toggle demo/performance mode |
GET | /admin/system-mode | Switch system profile |
GET | /admin/reload-params | Force parameter reload |
GET | /admin/profiles | List system profiles NEW |
GET | /admin/stress-stats | Real-time 24-counter metrics |
GET | /admin/stress-reset | Reset metrics counters |
GET | /admin/cluster-stats | Cluster-wide aggregated metrics NEW |
POST | /admin/build-search-index | Rebuild full-text search index from all 32 docs NEW |
GET | /admin/feed-status | Price feed status (all 6 exchanges) |
GET | /admin/usage-analytics | Usage log analytics |
GET | /admin/adaptive-stats | Adaptive governor stats |
GET | /admin/db-insights | PostgreSQL self-observability (cache hit, top queries, scan health) NEW |
GET | /admin/exchange-feeds | List exchange configurations |
POST | /admin/exchange-feeds/save | Create/update exchange |
POST | /admin/exchange-feeds/toggle | Enable/disable exchange |
DELETE | /admin/exchange-feeds | Remove exchange |
GET | /admin/exchange-assets | List asset mappings |
POST | /admin/exchange-assets/save | Create/update asset mappings |
POST | /admin/exchange-assets/toggle | Flip enabled/prewarm on single asset NEW |
DELETE | /admin/exchange-assets | Remove asset mappings |
POST | /admin/eam/sync | Sync EAM → application_parameters NEW |
GET | /admin/eam/audit | Start 4-layer prewarm audit (async) NEW |
GET | /admin/eam/audit?poll=1 | Poll for audit results NEW |
POST | /admin/eam/discover | Start asset discovery for exchange (async) NEW |
GET | /admin/eam/discover?exchange=okx&poll=1 | Poll for discovery results NEW |
GET | /admin/partner-applications | List partner applications |
POST | /admin/partner-applications/{id}/status | Update application status |
POST | /admin/sql | Execute SQL (read/write) NEW |
POST | /admin/sql-batch | Execute SQL batch (DDL allowed) NEW |
POST | /admin/valkey | Execute ElastiCache commands NEW |
GET | /admin/payment-links | List payment links NEW |
POST | /admin/payment-links/save | Create/update payment link NEW |
POST | /admin/payment-links/toggle | Enable/disable payment link NEW |
POST | /admin/test-refund-email | Send test refund email (dummy data, any language) NEW |
POST | /admin/test-finalize-email | Send test translation completion email with per-language cost breakdown NEW |
| Method | Path | Description |
|---|---|---|
GET | /admin/newsletter/templates | List templates |
GET | /admin/newsletter/templates/{id} | Get template |
POST | /admin/newsletter/templates | Save template |
DELETE | /admin/newsletter/templates/{id} | Delete template |
GET | /admin/newsletter/newsletters | List newsletters |
GET | /admin/newsletter/newsletters/{id} | Get newsletter |
POST | /admin/newsletter/newsletters | Save newsletter |
POST | /admin/newsletter/newsletters/{id}/status | Toggle status |
POST | /admin/newsletter/newsletters/{id}/send | Send newsletter |
GET | /admin/newsletter/subscribers | List subscribers |
| Method | Path | Description |
|---|---|---|
GET | /admin/email/templates | List email templates |
GET | /admin/email/templates/{id} | Get template |
POST | /admin/email/templates | Save template |
DELETE | /admin/email/templates/{id} | Delete template |
GET | /admin/email/senders | List senders |
POST | /admin/email/senders | Save sender |
DELETE | /admin/email/senders/{id} | Delete sender |
GET | /admin/email/drafts | List drafts |
GET | /admin/email/drafts/{id} | Get draft |
POST | /admin/email/drafts | Save draft |
DELETE | /admin/email/drafts/{id} | Delete draft |
POST | /admin/email/drafts/{id}/send | Send email |
| Method | Path | Description |
|---|---|---|
GET | /support/admin/stats | Ticket statistics — counts by status (total, new, open, in_progress, awaiting_customer, resolved, closed) |
GET | /support/admin/tickets | List all tickets. Filters: ?status=, ?category=, ?email=. Ordered by updated_at DESC |
GET | /support/admin/tickets/{id} | Full ticket detail by UUID — includes all replies (internal notes visible), translations, preferred_lang |
POST | /support/admin/tickets/{id}/update | Update ticket fields. Body: {"status":"...", "category":"..."} (at least one required) |
POST | /support/admin/tickets/{id}/reply | Add reply. Body: {"author":"...", "message":"...", "is_internal": false}. Auto-translates + emails customer |
GET | /support/admin/ticket/{ticket_number} | Full ticket by ticket number — includes AutoOps Bedrock analysis from Valkey |
| Method | Path | Description |
|---|---|---|
GET | /dashboard/api/support/tickets | List authenticated user's tickets. Scoped to session email. Ordered by most recent. |
GET | /dashboard/api/support/tickets/{ticket_number} | Ticket detail with reply thread. Excludes internal admin notes. Shows translated replies in customer's language. |
POST | /dashboard/api/support/tickets/{ticket_number}/reply | Post customer reply. Body: {"message":"..."}. Max 10,000 chars. Auto-translates to English. Notifies admin. |
POST | /dashboard/api/support/tickets/{ticket_number}/resolve | Mark own ticket as resolved. Notifies admin. Closed tickets cannot be resolved. |
| Method | Path | Description |
|---|---|---|
GET | /dashboard/api/admin/support/tickets | List all tickets system-wide. Filters: ?status=, ?category=. Limit 200. Ordered by created_at DESC. |
GET | /dashboard/api/admin/support/tickets/{id} | Full ticket detail by UUID — includes all replies (internal notes visible), customer IP, email. |
POST | /dashboard/api/admin/support/tickets/{id}/reply | Post admin reply. Body: {"message":"...", "is_internal": false}. Translates + emails customer. Includes one-click resolve link. |
POST | /dashboard/api/admin/support/tickets/{id}/status | Update ticket status. Body: {"status":"open"}. Valid: new, open, in_progress, awaiting_customer, resolved, closed. Audit-logged. |
| Method | Path | Description |
|---|---|---|
GET | /dashboard/api/admin/analytics | Usage analytics from Aurora. ?mode=detail (default, paginated rows) or ?mode=summary (aggregates via a single GROUPING SETS query with p50/p95/p99 latency percentiles). Date filters: ?start_date=, ?end_date=. CSV export via ?format=csv. |
GET | /dashboard/api/admin/daily-rollup | Per-day usage rollup served from the mv_usage_daily materialized view (fast, never scans usage_logs). ?days= (default 30, max 93). Returns totals, latency percentiles, cache-hit rate, cardinality, and a last_refreshed timestamp. NEW |
Both LPO and LRS support UDP for low-latency, connectionless access. UDP is ideal for high-frequency price polling where occasional packet loss is acceptable.
Send a UDP datagram to udp.cpmp-site.org:2679 with your API key and asset.
# Python UDP example
import socket, json
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
request = json.dumps({"api_key": "YOUR_API_KEY", "asset": "btc"}).encode()
sock.sendto(request, ("udp.cpmp-site.org", 2679))
data, addr = sock.recvfrom(4096)
print(json.loads(data))
Send a UDP datagram to udp.cpmp-site.org:2680 for usage reports and summaries.
# Python UDP example
import socket, json
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
request = json.dumps({"api_key": "YOUR_API_KEY", "type": "summary"}).encode()
sock.sendto(request, ("udp.cpmp-site.org", 2680))
data, addr = sock.recvfrom(65535)
print(json.loads(data))
| Method | Use Case | Latency |
|---|---|---|
| HTTPS (ALB) | Standard API access from any client | ~50ms |
| UDP (NLB) | High-frequency polling, low-latency price feeds | ~10ms |
| PrivateLink (NLB) | Private VPC-to-VPC access, no public internet | ~5ms |
Enterprise subscribers can connect via AWS PrivateLink. Both LPO (TCP 8080) and LRS (TCP 9090) are available through the same PrivateLink endpoint. Create a VPC endpoint in your AWS account pointing to our PrivateLink service.
Usage logs are written to Aurora Serverless v2 by the LPO in real-time. A nightly sync job (1 AM EST) copies usage data from Aurora to ElastiCache for fast LRS report generation. Reports reflect data up to the previous day's sync.
Every HTTP endpoint in The Trinity Beast returns a consistent JSON envelope. This makes responses self-reporting — each response tells you which endpoint handled the request, which ECS container answered, and which AWS region served it.
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/health] [200]",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbts/v1",
"status_code": 200,
"endpoint": "/health",
"cluster_node": "BeastMain",
"region": "us-east-2",
"timestamp": "2026-04-26T16:20:03Z",
"data": { "message": "Health Check - OK" }
}
{
"status": "🛑 [LPO] [us-east-2] [BeastMain] [/price] [401]",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbts/v1",
"status_code": 401,
"endpoint": "/price",
"cluster_node": "BeastMain",
"region": "us-east-2",
"timestamp": "2026-04-26T16:20:03Z",
"error": "🛑 [LPO] [us-east-2] [BeastMain] [/price] [401] Missing required API key parameter"
}
Every response uses a color-coded emoji indicator followed by bracketed origin metadata. This convention matches the usage logs, application logs, and subscriber-facing error messages — consistent across all messaging.
| Indicator | Color | Meaning | HTTP Codes |
|---|---|---|---|
| ✅ | Green | Success | 200, 201 |
| 🛑 | Red | Error | 400, 401, 403, 404, 429, 500, 503 |
| ⚠️ | Yellow | Warning / Redirect | 3xx |
| ✅🔴 | Green + Red | Success with critical warning (usage ≥ 95%) | 200 (with usage_warning: "red") |
| ✅⚠️ | Green + Yellow | Success with caution warning (usage ≥ 90%) | 200 (with usage_warning: "yellow") |
| ✅🟡 | Green + Gold | Success with green warning (usage ≥ 85%) | 200 (with usage_warning: "green") |
| ℹ️ | Blue | Informational | Used in logs |
| 🟠 | Amber | Debug | Used in logs |
OK, OK - NOTE: usage above 85%, OK - WARNING: approaching monthly query limit, OK - CRITICAL: near monthly query limit, and ERROR. This setting applies to both LPO and LRS responses for your API key.
The bracket format self-reports the origin of every message at a glance:
INDICATOR [SERVICE] [REGION] [NODE] [ENDPOINT] [CODE] message
Example: 🛑 [LPO] [us-east-2] [BeastMirror] [/admin/config] [403] Invalid admin key
This convention is used consistently across:
status field (unified envelope)error field (error messages)StandardErrorResponse)usage_logs table)| Field | Type | Description |
|---|---|---|
status | string | Color-coded bracket line: ✅ [LPO] [us-east-2] [BeastMain] [/health] [200] |
language | string | ISO 639-1 language code declaring the language of all human-readable content in this response (e.g., "en", "ja", "es"). Determined by the user's api_lang setting. Default: "en". |
status_code | int | HTTP status code as an integer for programmatic parsing |
endpoint | string | The URL path that handled the request (self-reporting) |
cluster_node | string | Which ECS container answered: BeastMain, BeastMirror, or BeastLRS |
region | string | AWS region — us-east-2 |
timestamp | string | RFC 3339 UTC timestamp of when the response was generated |
data | object | The actual response payload (omitted on errors) |
error | string | Full bracketed error message with indicator (only present on errors) |
/price endpoint uses the standard 12-field UME envelope. Price data is nested inside the data field. All endpoints — including /price — return the same envelope shape.
flowchart LR
A["Client Request"] --> B["⚖️ ALB / NLB"]
B --> C{"ECS Container"}
C --> D["BeastMain"]
C --> E["BeastMirror"]
C --> F["BeastLRS"]
D --> G["WriteJSON / WriteError"]
E --> G
F --> G
G --> H["Unified Envelope"]
H --> I["status: ok | error"]
H --> J["endpoint: /path"]
H --> K["cluster_node: BeastX"]
H --> L["region: us-east-2"]
H --> M["timestamp: RFC3339"]
H --> N["data / error payload"]
style A fill:#334155,stroke:#475569,color:#cbd5e1
style B fill:#334155,stroke:#475569,color:#cbd5e1
style C fill:#2d4a5e,stroke:#475569,color:#cbd5e1
style D fill:#2d4a5e,stroke:#475569,color:#cbd5e1
style E fill:#2d4a5e,stroke:#475569,color:#cbd5e1
style F fill:#2d4a5e,stroke:#475569,color:#cbd5e1
style G fill:#3d3455,stroke:#475569,color:#cbd5e1
style H fill:#FF9900,stroke:#cc7a00,color:#0f172a
style I fill:#1e293b,stroke:#475569,color:#94a3b8
style J fill:#1e293b,stroke:#475569,color:#94a3b8
style K fill:#1e293b,stroke:#475569,color:#94a3b8
style L fill:#1e293b,stroke:#475569,color:#94a3b8
style M fill:#1e293b,stroke:#475569,color:#94a3b8
style N fill:#1e293b,stroke:#475569,color:#94a3b8
Comprehensive inventory of every registered route across The Trinity Beast services.
| Method | Path | Auth | Service | Category | Description |
|---|---|---|---|---|---|
| 🏥 Health & Status | |||||
GET | /health | None | LPO | Health | Health check |
GET | /health | None | LRS | Health | Health check |
| Price | |||||
GET | /price | Bearer | LPO | Price | Fetch real-time crypto price |
| Reports | |||||
GET | /reports/usage | Bearer | LRS | Reports | Usage detail report |
GET | /reports/summary | Bearer | LRS | Reports | Usage summary report |
GET | /reports/report-usage | Bearer | LRS | Reports | Report access detail |
GET | /reports/report-summary | Bearer | LRS | Reports | Report access summary |
| Public | |||||
GET | /exchanges | None | LPO | Exchange Mgmt | Exchange asset list |
GET | /asset-categories | None | LPO | Exchange Mgmt | Asset categories for demo dropdown |
GET | /map/pins | None | LPO | System | Mission impact map pins |
POST | /translate | None | LPO | Translation | Real-time text translation via AWS Translate (ElastiCache cached) |
GET | /search | None | LPO | Search | Full-text document search — query + lang params, returns ranked results with snippets |
POST | /support/submit | None | LPO | Support | Submit support ticket |
GET | /support/tickets | None | LPO | Support | List tickets by email |
GET | /support/ticket/{ticket_number} | None | LPO | Support | View ticket detail |
POST | /demo/register | None | LPO | System | Demo lead registration |
POST | /partner/apply | None | LPO | Partners | Partner application |
GET | /partner/status | None | LPO | Partners | Partner application status |
POST | /newsletter/subscribe | None | LPO | Newsletter | Newsletter subscribe |
GET | /newsletter/unsubscribe | None | LPO | Newsletter | Newsletter unsubscribe |
GET | /newsletter/resubscribe | None | LPO | Newsletter | Newsletter resubscribe |
GET | /admin/bootstrap-key | None | LPO | System | One-time admin key setup |
| Admin — System | |||||
GET | /admin/config | Admin Key | LPO | System | View application parameters |
GET | /admin/setup-demo | Admin Key | LPO | System | Setup demo API key |
GET | /admin/invalidate-key | Admin Key | Both | System | Invalidate API key cache |
GET | /admin/demo-mode | Admin Key | LPO | System | Toggle demo/performance mode |
GET | /admin/system-mode | Admin Key | LPO | System | Switch system profile |
GET | /admin/reload-params | Admin Key | LPO | System | Force parameter reload |
GET | /admin/profiles | Admin Key | LPO | System | List system profiles |
| Method | Path | Auth | Service | Category | Description |
|---|---|---|---|---|---|
| 📈 Admin — Metrics & Monitoring | |||||
GET | /admin/stress-stats | Admin Key | LPO | Metrics | Real-time 24-counter metrics |
GET | /admin/stress-reset | Admin Key | LPO | Metrics | Reset metrics counters |
GET | /admin/cluster-stats | Admin Key | LPO | Metrics | Cluster-wide aggregated metrics |
GET | /admin/feed-status | Admin Key | LPO | Metrics | Price feed status (all 6 exchanges) |
GET | /admin/usage-analytics | Admin Key | LPO | Metrics | Usage log analytics |
GET | /admin/adaptive-stats | Admin Key | LPO | Metrics | Adaptive governor stats |
GET | /admin/db-insights | Admin Key | LPO | Metrics | PostgreSQL self-observability — cache hit ratio, top queries, scan health |
POST | /admin/db-insights/reset | Admin Key | LPO | Metrics | Reset pg_stat_statements baseline for a clean measurement window |
| Method | Path | Auth | Service | Category | Description |
|---|---|---|---|---|---|
| 🔄 Admin — Exchange Management | |||||
GET | /admin/exchange-feeds | Admin Key | LPO | Exchange Mgmt | List exchange configurations |
POST | /admin/exchange-feeds/save | Admin Key | LPO | Exchange Mgmt | Create/update exchange |
POST | /admin/exchange-feeds/toggle | Admin Key | LPO | Exchange Mgmt | Enable/disable exchange |
DELETE | /admin/exchange-feeds | Admin Key | LPO | Exchange Mgmt | Remove exchange |
GET | /admin/exchange-assets | Admin Key | LPO | Exchange Mgmt | List asset mappings |
POST | /admin/exchange-assets/save | Admin Key | LPO | Exchange Mgmt | Create/update asset mappings |
DELETE | /admin/exchange-assets | Admin Key | LPO | Exchange Mgmt | Remove asset mappings |
| Method | Path | Auth | Service | Category | Description |
|---|---|---|---|---|---|
| 🎫 Admin — Support | |||||
GET | /support/admin/stats | Admin Key | LPO | Support | Ticket statistics |
GET | /support/admin/tickets | Admin Key | LPO | Support | List all tickets |
GET | /support/admin/tickets/{id} | Admin Key | LPO | Support | View ticket detail |
POST | /support/admin/tickets/{id} | Admin Key | LPO | Support | Update ticket |
POST | /support/admin/tickets/{id}/reply | Admin Key | LPO | Support | Add reply |
| 🤝 Admin — Partners | |||||
GET | /admin/partner-applications | Admin Key | LPO | Partners | List applications |
POST | /admin/partner-applications/{id}/status | Admin Key | LPO | Partners | Update status |
| 📰 Admin — Newsletter | |||||
GET | /admin/newsletter/templates | Admin Key | LPO | Newsletter | List templates |
GET | /admin/newsletter/templates/{id} | Admin Key | LPO | Newsletter | Get template |
POST | /admin/newsletter/templates | Admin Key | LPO | Newsletter | Save template |
DELETE | /admin/newsletter/templates/{id} | Admin Key | LPO | Newsletter | Delete template |
GET | /admin/newsletter/newsletters | Admin Key | LPO | Newsletter | List newsletters |
GET | /admin/newsletter/newsletters/{id} | Admin Key | LPO | Newsletter | Get newsletter |
POST | /admin/newsletter/newsletters | Admin Key | LPO | Newsletter | Save newsletter |
POST | /admin/newsletter/newsletters/{id}/status | Admin Key | LPO | Newsletter | Toggle status |
POST | /admin/newsletter/newsletters/{id}/send | Admin Key | LPO | Newsletter | Send newsletter |
GET | /admin/newsletter/subscribers | Admin Key | LPO | Newsletter | List subscribers |
| ✉️ Admin — Email | |||||
GET | /admin/email/templates | Admin Key | LPO | List email templates | |
GET | /admin/email/templates/{id} | Admin Key | LPO | Get template | |
POST | /admin/email/templates | Admin Key | LPO | Save template | |
DELETE | /admin/email/templates/{id} | Admin Key | LPO | Delete template | |
GET | /admin/email/senders | Admin Key | LPO | List senders | |
POST | /admin/email/senders | Admin Key | LPO | Save sender | |
DELETE | /admin/email/senders/{id} | Admin Key | LPO | Delete sender | |
GET | /admin/email/drafts | Admin Key | LPO | List drafts | |
GET | /admin/email/drafts/{id} | Admin Key | LPO | Get draft | |
POST | /admin/email/drafts | Admin Key | LPO | Save draft | |
DELETE | /admin/email/drafts/{id} | Admin Key | LPO | Delete draft | |
POST | /admin/email/drafts/{id}/send | Admin Key | LPO | Send email | |
| 💳 Checkout & Payments | |||||
GET | /checkout | None | LPO | Checkout | Redirect to Stripe Payment Link |
GET | /admin/payment-links | Admin Key | LPO | Checkout | List payment links |
POST | /admin/payment-links/save | Admin Key | LPO | Checkout | Create/update payment link |
POST | /admin/payment-links/toggle | Admin Key | LPO | Checkout | Enable/disable payment link |
| 🗄️ Admin — Database & Cache | |||||
POST | /admin/sql | Admin Key | LPO | Database | Execute SQL (read/write) |
POST | /admin/sql-batch | Admin Key | LPO | Database | Execute SQL batch (DDL allowed) |
POST | /admin/valkey | Admin Key | LPO | Cache | Execute ElastiCache commands |
| UDP Protocol | |||||
| UDP | :2679 | Bearer (in JSON body) | LPO | Price | Price queries |
| UDP | :2680 | Bearer (in JSON body) | LRS | Reports | Report queries |
These endpoints expose operational metrics for the public Infrastructure Live page. No authentication required. Safe for public consumption — sensitive internals (DB pools, internal IPs, config) are stripped.
Returns a curated system status snapshot — node health, feed connections, uptime, and cache hit rate. Designed for the public dashboard. Reads from ElastiCache for sub-millisecond response.
Cache: public, max-age=3
| Field | Type | Description |
|---|---|---|
status | string | "operational" when all systems healthy |
system.nodes | int | Total expected nodes (4) |
system.nodes_healthy | int | Nodes currently reporting |
system.node_names | []string | Names of healthy nodes (BeastMain, BeastMirror, BeastLRS, BeastWebhook) |
system.uptime | string | Human-readable uptime (e.g., "4d 12h") |
system.cache_hit_pct | float | Cluster-wide cache hit percentage |
feeds[] | array | Per-exchange WebSocket feed status |
feeds[].exchange | string | Exchange name (e.g., "Coinbase") |
feeds[].connected | bool | WebSocket connection active |
feeds[].assets | int | Number of assets cached from this feed |
curl https://api.cpmp-site.org/public/status
Returns per-node ECS cluster metrics — the same operational data as /admin/cluster-stats but stripped of sensitive internals. Reads from ElastiCache (each container publishes its stats every 3 seconds).
Cache: public, max-age=5
| Field | Type | Description |
|---|---|---|
status | string | "ok" |
nodes_found | int | Nodes currently reporting |
nodes_expected | int | Expected node count (4) |
region | string | AWS region (us-east-2) |
nodes[] | array | Per-node metrics |
nodes[].name | string | Node name (BeastMain, BeastMirror, BeastLRS, BeastWebhook) |
nodes[].role | string | "LPO + LRS" or "Push Delivery" |
nodes[].uptime_seconds | float | Seconds since container start |
nodes[].tcp_requests | int | Total TCP requests served |
nodes[].udp_requests | int | Total UDP requests served |
nodes[].lrs_requests | int | Total LRS report requests |
nodes[].syncmap_hit_pct | float | Local sync.Map cache hit rate (%) |
nodes[].cache_hit_pct | float | Combined cache hit rate (sync.Map + ElastiCache) (%) |
nodes[].errors_5xx | int | Server errors since start |
nodes[].errors_4xx | int | Client errors since start |
nodes[].rate_limit_hits | int | Rate limit rejections since start |
aggregated | object | Cluster-wide totals (same fields summed across all nodes) |
curl https://api.cpmp-site.org/public/cluster
{
"status": "ok",
"nodes_found": 4,
"nodes_expected": 4,
"region": "us-east-2",
"nodes": [
{
"name": "BeastMain",
"role": "LPO + LRS",
"uptime_seconds": 86412.3,
"tcp_requests": 1247,
"udp_requests": 0,
"lrs_requests": 83,
"syncmap_hit_pct": 99.2,
"cache_hit_pct": 99.8,
"errors_5xx": 0,
"errors_4xx": 12,
"rate_limit_hits": 0
}
],
"aggregated": {
"tcp_requests": 3891,
"udp_requests": 0,
"lrs_requests": 249,
"syncmap_hit_pct": 99.1,
"cache_hit_pct": 99.7,
"rate_limit_hits": 0,
"errors_5xx": 0,
"errors_4xx": 34,
"bg_work_dropped": 0
}
}
Returns infrastructure-wide operational metrics aggregated from CloudWatch, Valkey, AWS ECS, and other AWS service APIs. Powers the Infrastructure Live page. The aggregated payload is cached in Valkey for 60 seconds; the standard response envelope is rebuilt on every request, so cache hits and misses are identical in shape.
Cache: public, max-age=60 (Valkey payload: 60s)
Envelope: Like every TBI response, this endpoint returns the standard 12-field Unified Messaging Envelope (UME). The fields documented below are the contents of the data object. Because this is a public, no-auth endpoint, api_key_id is "" (empty string, always present — never omitted).
data object)| Field | Type | Description |
|---|---|---|
cloudfront.requests_24h | int | CloudFront requests in last 24h |
cloudfront.bytes_24h | int | Bytes downloaded in last 24h |
cloudfront.bytes_human | string | Human-readable bytes (e.g., "1.4 GB") |
waf.alb_blocked_24h | int | ALB WAF blocked requests (24h) |
waf.alb_allowed_24h | int | ALB WAF allowed requests (24h) |
waf.cf_blocked_24h | int | CloudFront WAF blocked requests (24h) |
sqs.visible | int | Messages visible in usage log queue |
sqs.in_flight | int | Messages currently being processed |
lambda.receipt | object | Receipt Lambda stats (invocations_24h, errors_24h) |
lambda.writer | object | Queued Writer Lambda stats |
sync.last_run | string | Last nightly sync timestamp |
sync.status | string | "success" or "failed" |
sync.duration | string | Sync execution time |
sync.search_index | object | Search index stats (languages, sections) |
guardduty.active_findings | int | Active GuardDuty findings |
alarms.total | int | Total CloudWatch alarms configured |
alarms.alarm | int | Alarms currently in ALARM state |
honeypot.total_hits | int | Total honeypot trap hits |
honeypot.auto_blocked | int | IPs auto-blocked by honeypot |
cache.engine | string | "valkey" |
cache.version | string | Valkey version (e.g., "7.2.4") |
cache.items | int | Total keys in Valkey (DBSIZE) |
cache.hit_rate | float | All-time cache hit rate (%) |
cache.memory_used | string | Human-readable memory usage (e.g., "3.03G") |
autoops.lambdas | object | Per-function invocation counts (24h) |
autoops.step_functions | object | Step Function execution counts (24h) |
autoops.self_heal_count | int | Self-heal actions this month |
autoops.last_threat | string | Current threat level (NONE, LOW, MEDIUM, HIGH, CRITICAL) |
services.cluster | string | ECS cluster name |
services.total_desired | int | Total desired task count across all 4 services |
services.total_running | int | Total running task count across all 4 services |
services.total_pending | int | Total pending task count (non-zero during deployments) |
services.all_healthy | bool | true when all services are ACTIVE with running == desired and pending == 0 |
services.services[] | array | Per-service breakdown — name, status, desired, running, pending, healthy, task_family |
curl https://api.cpmp-site.org/public/infrastructure
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/public/infrastructure] [200]",
"status_code": 200,
"endpoint": "/public/infrastructure",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi/v1",
"timestamp": "2026-05-30T17:00:00Z",
"data": {
"cloudfront": { "requests_24h": 1095, "bytes_24h": 17114513, "bytes_human": "16 MB" },
"waf": { "alb_blocked_24h": 1186, "alb_allowed_24h": 3302, "cf_blocked_24h": 0 },
"sqs": { "visible": 0, "in_flight": 0 },
"lambda": {
"receipt": { "state": "Active", "last_deployed": "", "invocations_24h": 0, "errors_24h": 0 },
"writer": { "state": "Active", "last_deployed": "", "invocations_24h": 141, "errors_24h": 0 }
},
"sync": {
"last_run": "May 30 01:00AM",
"status": "success",
"duration": "783.351423ms",
"new_logs": "154 new logs loaded",
"search_index": { "languages": 12, "sections": 3150 }
},
"guardduty": { "active_findings": 0, "status": "active" },
"alarms": { "total": 17, "ok": 16, "alarm": 1, "insufficient_data": 0 },
"honeypot": { "active": true, "endpoints": 12, "total_hits": 22, "auto_blocked": 77, "pending_queue": 0 },
"autoops": {
"active": true,
"lambdas": {
"notify_invocations_24h": 14,
"self_heal_invocations_24h": 61,
"waf_action_invocations_24h": 3,
"honeypot_processor_invocations_24h": 288,
"bedrock_analyze_invocations_24h": 288,
"raima_support_invocations_24h": 11,
"digest_invocations_24h": 1,
"total_invocations_24h": 666,
"total_errors_24h": 0
},
"step_functions": { "executions_24h": 62, "succeeded_24h": 62, "failed_24h": 0 },
"eventbridge": {
"rules": [
{ "name": "tbi-ops-alarm-trigger", "schedule": "", "pattern": "CloudWatch alarm → ALARM", "target": "Step Function: health-check-heal" },
{ "name": "tbi-ops-honeypot-queue-processor", "schedule": "rate(5 minutes)", "pattern": "", "target": "Lambda: honeypot-processor" }
],
"total": 6
},
"waf_blocked_by_ops": 0,
"self_heal_count": 0,
"last_threat": "LOW"
},
"cache": {
"engine": "valkey",
"version": "7.2.6",
"items": 38675,
"hit_rate": 65.7,
"memory_used": "1.42G",
"memory_percent": 0.0,
"cpu_percent": 3.0
},
"services": {
"cluster": "trinity-beast-fargate-cluster",
"total_desired": 4,
"total_running": 4,
"total_pending": 0,
"all_healthy": true,
"services": [
{ "name": "trinity-beast-main-service", "status": "ACTIVE", "desired": 1, "running": 1, "pending": 0, "healthy": true, "task_family": "trinity-beast-main-task" }
]
},
"translation": {
"active": true,
"daily_spend_usd": 0,
"daily_limit_usd": 600,
"active_jobs": 0,
"queue_depth": 0,
"cost_per_pair_usd": 1.65,
"daily_input_tokens": 0,
"daily_output_tokens": 0,
"daily_token_limit": 50000000
}
},
"error": ""
}
The services.services[] array contains one object per Fargate service (4 total — abbreviated to one above). Each eventbridge.rules[] entry always carries both schedule and pattern; the field that does not apply to a given rule is an empty string, never omitted — consistent with the UME "no omitempty" rule.
All admin endpoints require the X-Admin-Key header. The admin key is established via the one-time /admin/bootstrap-key endpoint on first deployment.
X-Admin-Key: YOUR_ADMIN_KEY
Endpoints for managing application configuration, demo mode, system profiles, and parameter reloading.
| Method | Path | Description |
|---|---|---|
GET | /admin/config | View all application parameters and their current values |
GET | /admin/setup-demo | Create or reset the demo API key for the live demo page |
GET | /admin/invalidate-key | Invalidate a cached API key in ElastiCache (forces re-fetch from Aurora) |
GET | /admin/demo-mode | Toggle between demo mode (synthetic prices) and performance mode (live feeds) |
GET | /admin/system-mode | Switch the active system profile (e.g., production, maintenance, demo) |
GET | /admin/reload-params | Force an immediate reload of application parameters from the database |
GET | /admin/profiles | List all available system profiles and their configurations |
Real-time observability into The Trinity Beast runtime performance, price feed health, and adaptive governor behavior.
| Method | Path | Description |
|---|---|---|
GET | /admin/stress-stats | 24-counter real-time metrics: requests, errors, cache hits, latency percentiles, goroutines, memory |
GET | /admin/stress-reset | Reset all runtime metrics counters to zero |
GET | /admin/cluster-stats | Aggregated metrics across all ECS containers in the cluster |
GET | /admin/feed-status | WebSocket and REST feed status for all 6 exchanges (Coinbase, Gemini, Kraken, Gate.io, Crypto.com, OKX) |
GET | /admin/usage-analytics | Aggregated usage log analytics with breakdowns by asset, source, and time period |
GET | /admin/adaptive-stats | Adaptive governor statistics — current thresholds, adjustment history, and feed health scores |
GET | /admin/db-insights | PostgreSQL self-observability — buffer-cache hit ratio, top queries by total time and call count (from pg_stat_statements), and per-table sequential-vs-index scan health |
POST | /admin/db-insights/reset | Reset the pg_stat_statements baseline so a clean measurement window can begin (e.g., before/after an optimization A/B) |
Full CRUD for exchange feed configurations and asset symbol mappings. Changes take effect immediately — no restart required.
| Method | Path | Description |
|---|---|---|
GET | /admin/exchange-feeds | List all exchange configurations with connection status |
POST | /admin/exchange-feeds/save | Create or update an exchange configuration |
POST | /admin/exchange-feeds/toggle | Enable or disable an exchange without removing its configuration |
DELETE | /admin/exchange-feeds | Permanently remove an exchange configuration |
GET | /admin/exchange-assets | List all asset symbol mappings across exchanges. Returns id, asset, exchange_name, exchange_symbol, enabled, prewarm, category. Optional ?exchange=coinbase filter. |
POST | /admin/exchange-assets/save | Create or update asset symbol mappings for an exchange. Accepts enabled, prewarm, and category per asset. |
POST | /admin/exchange-assets/toggle | Flip enabled and/or prewarm on a single asset row. Only the fields provided are updated. Body: {"exchange_name":"okx","asset":"BANANA","prewarm":false} |
DELETE | /admin/exchange-assets | Remove asset symbol mappings. ?exchange=gemini&asset=APE removes one; ?exchange=gemini removes all for that exchange. |
POST | /admin/eam/sync | Sync EAM → application_parameters. Writes per-exchange CSV params and master prewarm_assets_list from all enabled=true, prewarm=true rows. Follow with /admin/force-deploy-params to activate. |
GET | /admin/eam/audit | Start a 4-layer prewarm audit in the background (async). Returns 202 immediately. Layers: live exchange API prices, EAM ↔ param drift, master list parity, LPO smoke test. Results cached in Valkey 24h. |
GET | /admin/eam/audit?poll=1 | Poll for audit results. Returns {"ready":false} while running, {"ready":true,"result":{...}} when complete. |
POST | /admin/eam/discover | Start async discovery of uncovered assets for an exchange, ranked by 24h volume. Body: {"exchange":"okx","limit":18}. Returns 202 immediately. Results cached in Valkey 10 min. |
GET | /admin/eam/discover?exchange=okx&poll=1 | Poll for discovery results. Returns top N uncovered assets with price, 24h volume, and exchange symbol — filtered against the full EAM collection across all exchanges. |
Direct database and cache access for administrative operations. These endpoints execute commands against Aurora Serverless v2 and ElastiCache.
| Method | Path | Description |
|---|---|---|
POST | /admin/sql | Execute a single SQL statement (SELECT, INSERT, UPDATE, DELETE) |
POST | /admin/sql-batch | Execute multiple SQL statements in sequence (DDL allowed — CREATE TABLE, ALTER, etc.) |
POST | /admin/valkey | Execute ElastiCache (Valkey) commands — GET, SET, DEL, KEYS, HGETALL, etc. |
/admin/sql, /admin/sql-batch, and /admin/valkey endpoints execute commands directly against production databases. Use with care.
/admin/sql: The endpoint accepts an optional args array for safe parameter binding. When present, the query uses PostgreSQL placeholders ($1, $2, …) bound to the array values instead of string interpolation. The parameter is backward-compatible — omitting args preserves the exact prior behavior.
{
"query": "SELECT COUNT(*) AS count FROM usage_logs WHERE asset = $1",
"args": ["BTC"],
"mode": "read"
}
| Method | Path | Description |
|---|---|---|
GET | /support/admin/stats | Ticket statistics — open, closed, average response time |
GET | /support/admin/tickets | List all support tickets with filtering and pagination |
GET | /support/admin/tickets/{id} | View full ticket detail including all replies |
POST | /support/admin/tickets/{id} | Update ticket status, priority, or assignment |
POST | /support/admin/tickets/{id}/reply | Add an admin reply to a ticket (triggers email notification via SES) |
| Method | Path | Description |
|---|---|---|
GET | /admin/partner-applications | List all partner applications with status filtering |
POST | /admin/partner-applications/{id}/status | Approve, reject, or request more info on a partner application |
Full newsletter lifecycle management — templates, composition, subscriber management, and sending via SES.
| Method | Path | Description |
|---|---|---|
GET | /admin/newsletter/templates | List all newsletter templates |
GET | /admin/newsletter/templates/{id} | Get a specific template by ID |
POST | /admin/newsletter/templates | Create or update a newsletter template |
DELETE | /admin/newsletter/templates/{id} | Delete a newsletter template |
GET | /admin/newsletter/newsletters | List all newsletters with status |
GET | /admin/newsletter/newsletters/{id} | Get a specific newsletter by ID |
POST | /admin/newsletter/newsletters | Create or update a newsletter |
POST | /admin/newsletter/newsletters/{id}/status | Toggle newsletter active/inactive status |
POST | /admin/newsletter/newsletters/{id}/send | Send newsletter to all active subscribers via SES |
GET | /admin/newsletter/subscribers | List all newsletter subscribers with status |
Direct email composition and sending — templates, verified senders, draft management, and delivery via SES.
| Method | Path | Description |
|---|---|---|
GET | /admin/email/templates | List all email templates |
GET | /admin/email/templates/{id} | Get a specific email template |
POST | /admin/email/templates | Create or update an email template |
DELETE | /admin/email/templates/{id} | Delete an email template |
GET | /admin/email/senders | List verified sender identities |
POST | /admin/email/senders | Add or update a sender identity |
DELETE | /admin/email/senders/{id} | Remove a sender identity |
GET | /admin/email/drafts | List all email drafts |
GET | /admin/email/drafts/{id} | Get a specific draft |
POST | /admin/email/drafts | Create or update an email draft |
DELETE | /admin/email/drafts/{id} | Delete an email draft |
POST | /admin/email/drafts/{id}/send | Send an email draft via SES |
Diagnostic endpoints for verifying email rendering without triggering real payment processing or translation jobs.
| Method | Path | Description |
|---|---|---|
POST | /admin/test-refund-email | Send a test refund confirmation email with dummy data. Supports type: translation or subscription. Supports lang: en, es, pt, fr, de, ru, hi, ur, ar, ja, zh, it. |
POST | /admin/test-finalize-email | Send a test translation completion notification email with mock data. Verifies the per-language cost breakdown table (sqsLangDetails) renders correctly. Three scenarios: succeeded, partial, failed. No Bedrock calls, no translation jobs — SES only. |
{
"email": "recipient@example.com",
"lang": "ur",
"type": "translation"
}
{
"status": "sent",
"email": "recipient@example.com",
"lang": "ur",
"type": "translation",
"subject": "رقم کی واپسی کی تصدیق — Trinity-Beast-API-Reference.html"
}
Sends a mock translation completion email with realistic dummy data. The email includes the full stats bar (documents, languages, succeeded/failed counts, duration, cost/fee/total, state badge) and the Cost by Language table showing per-language Bedrock token usage and cost. Subject line is prefixed with [TEST] and a purple banner at the top makes it immediately clear this is not a real alert.
{
"email": "recipient@example.com",
"scenario": "succeeded"
}
// scenario values:
// "succeeded" — 2 docs × 11 langs, all 22 pairs succeeded, full cost breakdown table
// "partial" — 2 docs × 11 langs, 16/22 pairs succeeded, 3 failed pairs listed, partial cost table
// "failed" — 1 doc × 3 langs, all failed, no cost table, CRITICAL badge
{
"status": "sent",
"email": "recipient@example.com",
"scenario": "partial",
"subject": "[TEST] Translation Complete: 2 docs × 11 langs — 16/22 pairs PARTIAL"
}
Internal admin endpoints for the document translation pipeline. All require the X-Admin-Key header. Full documentation: AutoOps Translation Engine.
| Method | Path | Description |
|---|---|---|
POST | /admin/translate | Submit a translation job. Accepts docs (array, max 6), langs ("all" or array), model, options (force, delta, skip_search_rebuild, skip_validation), protected_terms. Enforces $600/day dollar cap and 50M token/day cap. Returns job_id. |
| Method | Path | Description |
|---|---|---|
GET | /admin/translate/status/{job_id} | Full job state — Valkey primary (live progress), Aurora fallback (completed jobs) |
GET | /admin/translate/queue | All active and queued jobs |
GET | /admin/translate/history | Last 50 completed jobs from Aurora |
GET | /admin/translate/health | System health — queue depth, active jobs, daily spend, daily token counts (input/output/limit), last completed job |
| Method | Path | Description |
|---|---|---|
POST | /admin/translate/cancel/{job_id} | Stop a running job — halts Step Function, leaves already-deployed translations live |
POST | /admin/translate/retry-failed/{job_id} | Re-submit only the failed pairs from a previous job |
The submit handler enforces two independent daily caps. Either can trigger a 429:
| Cap | Valkey Key | Limit | Reset |
|---|---|---|---|
| Dollar cap | autoops:bedrock:spend:daily | $600/day | 24h TTL auto-reset |
| Token cap | autoops:bedrock:tokens:input:daily + autoops:bedrock:tokens:output:daily | 50M combined tokens/day | 24h TTL auto-reset |
Emergency kill switch: SET autoops:bedrock:kill 1 in Valkey — halts all translation operations immediately.
The dashboard exposes 8 support endpoints split into two groups: Customer (authenticated via Bearer token, scoped to the user's own tickets) and Admin (Bearer token + admin role, system-wide access). All responses use the standard 12-field UME envelope.
These endpoints are scoped to the authenticated user's email. Customers can only see and interact with their own tickets. Internal admin notes are never exposed.
GET /dashboard/api/support/ticketsList the authenticated user's support tickets, ordered by most recent. Limited to 50.
Authentication: Bearer token (session cookie)
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/dashboard/api/support/tickets] [200]",
"status_code": 200,
"endpoint": "/dashboard/api/support/tickets",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi-dashboard/v1",
"timestamp": "2026-05-17T19:00:00Z",
"data": {
"tickets": [
{
"ticket_number": "TKT-20260517-A3F2",
"subject": "API key not working after renewal",
"status": "open",
"created_at": "2026-05-17T14:30:00Z"
}
]
},
"error": ""
}
GET /dashboard/api/support/tickets/{ticket_number}Full ticket detail with reply thread. Excludes internal admin notes. Shows translated replies in the customer's language.
Authentication: Bearer token (session cookie). Must own the ticket.
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/dashboard/api/support/tickets/TKT-20260517-A3F2] [200]",
"status_code": 200,
"endpoint": "/dashboard/api/support/tickets/TKT-20260517-A3F2",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi-dashboard/v1",
"timestamp": "2026-05-17T19:00:00Z",
"data": {
"ticket": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ticket_number": "TKT-20260517-A3F2",
"name": "Jane Developer",
"category": "technical",
"subject": "API key not working after renewal",
"message": "I renewed my subscription yesterday but my API key returns 403...",
"status": "open",
"preferred_lang": "en",
"created_at": "2026-05-17T14:30:00Z",
"updated_at": "2026-05-17T15:45:00Z"
},
"replies": [
{
"id": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
"author_type": "admin",
"message": "I've checked your key — it looks like the cache hadn't refreshed yet. Should be working now.",
"created_at": "2026-05-17T15:45:00Z"
}
]
},
"error": ""
}
POST /dashboard/api/support/tickets/{ticket_number}/replyPost a customer reply. Max 10,000 characters. Auto-translates to English for admin readability. Notifies admin via email. Re-opens tickets in awaiting_customer or resolved state.
Authentication: Bearer token (session cookie). Must own the ticket.
Request body:
{
"message": "Thanks, it's working now! One more question — can I add more assets to my plan?"
}
Response:
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/dashboard/api/support/tickets/TKT-20260517-A3F2/reply] [200]",
"status_code": 200,
"endpoint": "/dashboard/api/support/tickets/TKT-20260517-A3F2/reply",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi-dashboard/v1",
"timestamp": "2026-05-17T19:10:00Z",
"data": {
"reply_id": "c4d5e6f7-a8b9-0123-4567-890abcdef123",
"message": "Reply posted"
},
"error": ""
}
Errors: 400 if message is empty or exceeds 10,000 chars. 400 if ticket is closed. 404 if ticket not found or not owned by user.
POST /dashboard/api/support/tickets/{ticket_number}/resolveMark own ticket as resolved. Notifies admin. Closed tickets cannot be resolved (already terminal). Idempotent — resolving an already-resolved ticket returns success.
Authentication: Bearer token (session cookie). Must own the ticket.
Request body: Empty {}
Response:
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/dashboard/api/support/tickets/TKT-20260517-A3F2/resolve] [200]",
"status_code": 200,
"endpoint": "/dashboard/api/support/tickets/TKT-20260517-A3F2/resolve",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi-dashboard/v1",
"timestamp": "2026-05-17T19:15:00Z",
"data": {
"message": "Ticket marked resolved",
"status": "resolved"
},
"error": ""
}
System-wide ticket management. Admin can see all tickets, all replies (including internal notes), customer IPs, and full audit trail. Requires admin role on the session.
GET /dashboard/api/admin/support/ticketsList all tickets system-wide. Supports filtering by status and category. Limited to 200 results, ordered by created_at DESC.
Authentication: Bearer token + admin role
Query parameters:
| Param | Type | Description |
|---|---|---|
status | string | Filter by status: new, open, in_progress, awaiting_customer, resolved, closed |
category | string | Filter by category: billing, technical, api-access, rate-limit, feature-request, bug-report, account, general |
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/dashboard/api/admin/support/tickets] [200]",
"status_code": 200,
"endpoint": "/dashboard/api/admin/support/tickets",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi-dashboard/v1",
"timestamp": "2026-05-17T19:00:00Z",
"data": {
"tickets": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ticket_number": "TKT-20260517-A3F2",
"name": "Jane Developer",
"email": "jane@example.com",
"category": "technical",
"subject": "API key not working after renewal",
"status": "open",
"created_at": "2026-05-17T14:30:00Z",
"updated_at": "2026-05-17T15:45:00Z"
}
]
},
"error": ""
}
GET /dashboard/api/admin/support/tickets/{id}Full ticket detail by UUID. Includes all replies (internal notes visible), customer IP, email, preferred language, and English translation of the original message.
Authentication: Bearer token + admin role
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/dashboard/api/admin/support/tickets/a1b2c3d4-e5f6-7890-abcd-ef1234567890] [200]",
"status_code": 200,
"endpoint": "/dashboard/api/admin/support/tickets/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi-dashboard/v1",
"timestamp": "2026-05-17T19:00:00Z",
"data": {
"ticket": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ticket_number": "TKT-20260517-A3F2",
"name": "Jane Developer",
"email": "jane@example.com",
"category": "technical",
"subject": "API key not working after renewal",
"message": "I renewed my subscription yesterday but my API key returns 403...",
"message_en": "I renewed my subscription yesterday but my API key returns 403...",
"preferred_lang": "en",
"status": "open",
"client_ip": "203.0.113.50",
"created_at": "2026-05-17T14:30:00Z",
"updated_at": "2026-05-17T15:45:00Z"
},
"replies": [
{
"id": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
"author": "CoryDeanKalani@CPMP-Site.org",
"author_type": "admin",
"message": "I've checked your key — it looks like the cache hadn't refreshed yet. Should be working now.",
"is_internal": false,
"created_at": "2026-05-17T15:45:00Z"
},
{
"id": "d5e6f7a8-b9c0-1234-5678-90abcdef1234",
"author": "CoryDeanKalani@CPMP-Site.org",
"author_type": "admin",
"message": "Note: key cache was stale due to recent deploy. Forced invalidation.",
"is_internal": true,
"created_at": "2026-05-17T15:44:00Z"
}
]
},
"error": ""
}
POST /dashboard/api/admin/support/tickets/{id}/replyPost an admin reply. Auto-translates to customer's language and emails them. Includes a one-click resolve link in the email (single-use, 30-day TTL). Internal notes (is_internal: true) are never shown to the customer or emailed. First reply auto-advances status from new to open.
Authentication: Bearer token + admin role
Request body:
{
"message": "I've checked your key — it looks like the cache hadn't refreshed yet. Should be working now.",
"is_internal": false
}
Response:
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/dashboard/api/admin/support/tickets/a1b2c3d4/reply] [200]",
"status_code": 200,
"endpoint": "/dashboard/api/admin/support/tickets/a1b2c3d4/reply",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi-dashboard/v1",
"timestamp": "2026-05-17T19:10:00Z",
"data": {
"reply_id": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
"message": "Reply posted"
},
"error": ""
}
Errors: 400 if message is empty. 404 if ticket not found.
POST /dashboard/api/admin/support/tickets/{id}/statusUpdate a ticket's status. Audit-logged with the admin's email. Valid statuses: new, open, in_progress, awaiting_customer, resolved, closed.
Authentication: Bearer token + admin role
Request body:
{
"status": "in_progress"
}
Response:
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/dashboard/api/admin/support/tickets/a1b2c3d4/status] [200]",
"status_code": 200,
"endpoint": "/dashboard/api/admin/support/tickets/a1b2c3d4/status",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi-dashboard/v1",
"timestamp": "2026-05-17T19:12:00Z",
"data": {
"message": "Status updated",
"status": "in_progress"
},
"error": ""
}
Errors: 400 if status is invalid. 404 if ticket not found.
Tickets follow a lifecycle with automatic transitions:
| Transition | Trigger |
|---|---|
new → open | First admin reply |
awaiting_customer → open | Customer replies |
resolved → open | Customer replies (re-opens) |
Any → resolved | Customer clicks resolve (dashboard or email link) |
| Any → any valid status | Admin sets status manually |
Note: Closed tickets cannot be replied to by customers. They must open a new ticket.
GET /dashboard/api/admin/daily-rollupReturns per-day usage aggregates served from the mv_usage_daily materialized view in Aurora. Because the data is precomputed, this endpoint is fast and never scans the full usage_logs table. The view is refreshed every 5 minutes by the pg_cron job tbi-mv-usage-daily-refresh running natively inside Aurora; the last_refreshed field tells consumers how current the data is.
Authentication: Bearer token + admin role
| Parameter | Type | Description |
|---|---|---|
days | int | Number of days to return. Default 30, maximum 93 (matches the usage-log retention window). |
Response:
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/dashboard/api/admin/daily-rollup] [200]",
"status_code": 200,
"endpoint": "/dashboard/api/admin/daily-rollup",
"cluster_node": "BeastMain",
"region": "us-east-2",
"language": "en",
"api_key_id": "ak_demo123",
"ip_address": "203.0.113.42",
"agent_profile_arn": "arn:tbi:us-east-2:211998422884:agent-profile/tbi-dashboard/v1",
"timestamp": "2026-05-30T23:30:00Z",
"data": {
"days": [
{
"day": "2026-05-30",
"total_requests": 4821,
"avg_latency_ms": 12.4,
"p50_latency_ms": 9,
"p95_latency_ms": 38,
"p99_latency_ms": 71,
"cached_requests": 4603,
"cache_hit_rate_pct": 95.48,
"distinct_assets": 142,
"distinct_api_keys": 6,
"distinct_sources": 6,
"distinct_nodes": 3
}
],
"count": 1,
"last_refreshed": "2026-05-30T23:26:00Z"
},
"error": ""
}
Notes: days is always an array (empty [] when no data, never null). last_refreshed reflects the most recent materialized-view refresh, not the request time.
AI-powered document translation with sentinel preprocessing and multi-layer validation. Translates technical documentation while preserving code blocks, Mermaid diagrams, brand terms, and all technical identifiers. Choose from three AI agents based on your needs.
Authentication: All translation endpoints require a valid API key via X-API-Key header, Authorization: Bearer, or ?api_key= query parameter. Only paid tiers (pro, enterprise, unlimited, lifetime) can access the translation service. Translation-specific API keys (service_type: translation) are required — price-only keys are rejected with 403.
GET /translate/modelsReturns the available AI agents with token-based pricing information. Public — no authentication required.
{
"status_code": 200,
"data": {
"models": [
{
"id": "claude-haiku-3.5",
"name": "Claude Haiku 3.5",
"tier": "Good",
"input_rate_per_1m": 1.0,
"output_rate_per_1m": 5.0,
"estimated_cost_per_pair": 0.03,
"speed": "fast",
"quality": "good",
"description": "Fast and affordable. Best for Latin-script languages and straightforward documents."
},
{
"id": "claude-sonnet-4.6",
"name": "Claude Sonnet 4.6",
"tier": "Better",
"input_rate_per_1m": 3.0,
"output_rate_per_1m": 15.0,
"estimated_cost_per_pair": 0.08,
"speed": "moderate",
"quality": "excellent",
"description": "Balanced speed and quality. Handles complex scripts and technical documents well. Default choice."
},
{
"id": "claude-opus-4",
"name": "Claude Opus 4",
"tier": "Best",
"input_rate_per_1m": 5.0,
"output_rate_per_1m": 25.0,
"estimated_cost_per_pair": 0.05,
"speed": "slow",
"quality": "exceptional",
"description": "Highest quality translations. Best for critical documents and complex grammar."
}
],
"default": "claude-sonnet-4.6",
"pricing_note": "Rates are per 1M tokens. estimated_cost_per_pair is for a typical 50KB document (one language). Actual cost depends on document size and content density."
}
}
| Field | Type | Description |
|---|---|---|
input_rate_per_1m | float | Cost per 1 million input tokens (USD) |
output_rate_per_1m | float | Cost per 1 million output tokens (USD) |
estimated_cost_per_pair | float | Estimated Bedrock cost for one language pair on a typical 50KB document |
POST /translate/quoteSubmit a document URL and target languages to receive an instant price quote. The engine fetches and analyzes your document (size, chunks, code blocks, diagrams) and returns a detailed cost breakdown.
{
"doc_url": "https://your-site.com/docs/api-reference.html",
"langs": ["es", "fr", "de", "ja", "zh"],
"model": "claude-sonnet-4.6"
}
| Field | Type | Required | Description |
|---|---|---|---|
doc_url | string | Yes | URL to the source document (must be publicly accessible). Max 500 KB. |
langs | string[] | Yes | Array of target language codes (e.g., ["es","ja","ar"]). Maximum 12 languages per quote. 35 validated languages with production-tested sentinel configurations; any of Claude's 300+ supported languages can be requested by ISO 639-1 code. |
model | string | No | AI agent to use. One of: claude-haiku-3.5, claude-sonnet-4.6 (default), claude-opus-4. |
{
"status_code": 200,
"data": {
"quote_id": "qt-a1b2c3d4e5f6",
"doc_name": "api-reference.html",
"languages": ["es", "fr", "de", "ja", "zh"],
"model": "claude-sonnet-4.6",
"analysis": {
"size_bytes": 63488,
"estimated_chunks": 4,
"difficulty": "moderate",
"code_blocks": 12,
"diagrams": 2
},
"pricing": {
"estimated_input_tokens": 21700,
"estimated_output_tokens": 16492,
"input_rate_per_1m": 3.0,
"output_rate_per_1m": 15.0,
"cost_per_pair": 0.31,
"pairs": 5,
"subtotal": 1.57,
"markup_pct": 30,
"total_price": 2.04,
"per_language": [
{
"lang": "es",
"model": "claude-haiku-3.5",
"estimated_input_tokens": 21700,
"estimated_output_tokens": 16492,
"bedrock_cost": 0.05,
"infra_cost": 0.14,
"pair_subtotal": 0.19,
"pair_with_markup": 0.24
},
{
"lang": "ja",
"model": "claude-sonnet-4.6",
"estimated_input_tokens": 21700,
"estimated_output_tokens": 16492,
"bedrock_cost": 0.31,
"infra_cost": 0.14,
"pair_subtotal": 0.45,
"pair_with_markup": 0.59
}
]
},
"expires_at": "2026-05-23T15:00:00Z",
"accept_url": "/translate/accept/qt-a1b2c3d4e5f6"
}
}
Per-language breakdown: When the engine auto-routes languages to different agents (e.g., Haiku for Latin-script languages, Sonnet for CJK/RTL), the per_language array shows the exact cost per target language. If you specify a model explicitly, all languages use that model and the per-language costs are uniform.
Quote expiry: Quotes are valid for 24 hours. After expiry, submit a new quote request. Pricing may change if Bedrock costs are updated.
GET /translate/quote/{quote_id}Retrieve the details of an existing quote, including its current state (pending, accepted, expired).
{
"status_code": 200,
"data": {
"quote_id": "qt-a1b2c3d4e5f6",
"doc_url": "https://your-site.com/docs/api-reference.html",
"doc_name": "api-reference.html",
"languages": ["es", "fr", "de", "ja", "zh"],
"model": "claude-sonnet-4.6",
"analysis": {
"size_bytes": 63488,
"estimated_chunks": 4,
"difficulty": "moderate",
"code_blocks": 12,
"diagrams": 2
},
"pricing": {
"estimated_input_tokens": 21700,
"estimated_output_tokens": 16492,
"input_rate_per_1m": 3.0,
"output_rate_per_1m": 15.0,
"cost_per_pair": 0.31,
"pairs": 5,
"subtotal": 1.57,
"markup_pct": 30,
"total_price": 2.04
},
"state": "pending",
"expires_at": "2026-05-23T15:00:00Z",
"accepted_at": "",
"job_id": ""
}
}
GET /translate/quotesList all quotes for the authenticated API key, ordered by most recent. Limited to 30.
{
"status_code": 200,
"data": {
"quotes": [
{
"quote_id": "qt-a1b2c3d4e5f6",
"doc_name": "api-reference.html",
"lang_count": 5,
"total_price": 11.05,
"model": "claude-sonnet-4.6",
"state": "accepted",
"expires_at": "2026-05-23T15:00:00Z",
"job_id": "019e4b8a37bc-abc123"
},
{
"quote_id": "qt-f6e5d4c3b2a1",
"doc_name": "architecture-guide.html",
"lang_count": 3,
"total_price": 6.45,
"model": "claude-haiku-3.5",
"state": "pending",
"expires_at": "2026-05-23T18:00:00Z",
"job_id": ""
}
],
"count": 2
}
}
POST /translate/accept/{quote_id}Accept a pending quote and begin translation. Your payment method on file is charged the quoted amount. Translation starts immediately upon acceptance.
{
"status_code": 200,
"data": {
"job_id": "019e4b8a37bc-abc123",
"state": "queued",
"quote_id": "qt-a1b2c3d4e5f6",
"model": "claude-sonnet-4.6",
"total_price": 11.05,
"pairs": 5,
"message": "Translation job started. You will receive an email when complete."
}
}
| Status | Condition |
|---|---|
400 | Quote has already been accepted |
400 | Quote has expired (24h TTL) |
402 | Payment failed — no valid payment method on file |
404 | Quote not found or does not belong to this API key |
Job tracking: After acceptance, use the job_id to check progress via your Account Dashboard or the GET /dashboard/api/translate/status/{job_id} endpoint. You'll also receive an email notification when the job completes.
POST /translate/accept-batchAccept multiple pending quotes in a single transaction. A single Stripe PaymentIntent is created for the batch total. Each quote becomes a separate translation job. Maximum 6 quotes per batch.
{
"quote_ids": [
"qt-a1b2c3d4e5f6",
"qt-b2c3d4e5f6a7",
"qt-c3d4e5f6a7b8"
]
}
| Field | Type | Required | Description |
|---|---|---|---|
quote_ids | array | Yes | Array of quote IDs to accept. Minimum 1, maximum 6. |
{
"status_code": 200,
"data": {
"batch_total": 33.15,
"jobs": [
{
"job_id": "019e4b8a37bc-abc123",
"quote_id": "qt-a1b2c3d4e5f6",
"state": "queued",
"pairs": 5,
"price": 11.05
},
{
"job_id": "019e4b8a37bc-def456",
"quote_id": "qt-b2c3d4e5f6a7",
"state": "queued",
"pairs": 3,
"price": 8.40
},
{
"job_id": "019e4b8a37bc-ghi789",
"quote_id": "qt-c3d4e5f6a7b8",
"state": "queued",
"pairs": 6,
"price": 13.70
}
],
"payment_intent_id": "pi_3abc123def456",
"message": "3 translation jobs started. You will receive an email when each completes."
}
}
| Status | Condition |
|---|---|
400 | No quote_ids provided or array is empty |
400 | More than 6 quotes in a single batch |
400 | One or more quotes already accepted or expired |
402 | Payment failed — no valid payment method on file |
404 | One or more quotes not found or do not belong to this API key |
Batch behavior: All quotes must belong to the same API key and be in pending state. If any quote in the batch fails validation, the entire batch is rejected (no partial acceptance). Each accepted quote spawns an independent translation job. A single HTML receipt email is sent summarizing all jobs in the batch.
35 validated languages with production-tested sentinel configurations. Any additional language Claude supports can be requested.
| Code | Language | Code | Language | Code | Language |
|---|---|---|---|---|---|
es | Spanish | hi | Hindi | ko | Korean |
pt | Portuguese | ur | Urdu | tr | Turkish |
fr | French | ar | Arabic | pl | Polish |
de | German | ja | Japanese | nl | Dutch |
ru | Russian | zh | Chinese | sv | Swedish |
it | Italian | bn | Bengali | th | Thai |
vi | Vietnamese | id | Indonesian | ro | Romanian |
POST /admin/translate/refund/{quote_id}Issues a full or partial refund for a completed translation purchase. Admin-only — requires X-Admin-Key header. Refunds are processed via Stripe and the customer receives a confirmation email automatically.
| Parameter | Type | Description |
|---|---|---|
quote_id | string | The quote ID from the original translation purchase (e.g., qt-a1b2c3d4e5f6) |
POST /admin/translate/refund/qt-a1b2c3d4e5f6
X-Admin-Key: your-admin-key
Content-Type: application/json
{
"amount": 5.00,
"reason": "Customer unsatisfied with Japanese translation quality"
}
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | No | Partial refund amount in USD. If omitted or equal to the original charge, a full refund is issued. |
reason | string | No | Reason for the refund. Included in the customer's refund confirmation email and stored as metadata on the Stripe refund. |
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/admin/translate/refund/qt-a1b2c3d4e5f6] [200]",
"status_code": 200,
"data": {
"status": "refunded",
"quote_id": "qt-a1b2c3d4e5f6",
"refund_id": "re_1234567890",
"refund_amount": 10.75,
"original_amount": 10.75,
"partial": false,
"stripe_status": "succeeded"
},
"error": ""
}
Validation rules:
accepted state (already paid)pending, expired, or already refundedCustomers can configure up to 150 brand terms that are automatically protected during every translation job. These terms are never translated or transliterated — they appear exactly as written in every target language. Terms are managed via the dashboard API and apply to all future translation jobs for the account.
GET /dashboard/api/protected-termsReturns the customer's current list of protected brand terms. Requires dashboard Bearer token authentication.
{
"status_code": 200,
"data": {
"terms": ["Acme Corp", "DataForge", "CloudSync API", "John Smith"],
"count": 4,
"limit": 150
},
"error": ""
}
PUT /dashboard/api/protected-termsReplaces the customer's entire brand terms list. Requires dashboard Bearer token authentication.
PUT /dashboard/api/protected-terms
Authorization: Bearer your-session-token
Content-Type: application/json
{
"terms": ["Acme Corp", "DataForge", "CloudSync API", "John Smith", "SyncEngine"]
}
| Field | Type | Required | Description |
|---|---|---|---|
terms | array of strings | Yes | The complete list of brand terms to protect. Replaces any existing terms. |
{
"status_code": 200,
"data": {
"message": "Saved 5 brand terms",
"terms": ["Acme Corp", "DataForge", "CloudSync API", "John Smith", "SyncEngine"],
"count": 5,
"limit": 150
},
"error": ""
}
Limits & validation:
Authenticated dashboard endpoints for translation spend tracking, refund history, and job completion notifications. All require Bearer token authentication via the dashboard session.
GET /dashboard/api/translate/spendReturns translation spend aggregated by month and model for the last 6 months. Customers see only their own spend; admins see all accounts.
{
"status_code": 200,
"data": {
"summary": {
"total_revenue_usd": 247.50,
"total_bedrock_cost_usd": 89.30,
"total_jobs": 18,
"total_pairs": 142
},
"months": [
{
"month": "2026-05",
"revenue_usd": 132.00,
"bedrock_cost_usd": 48.20,
"jobs": 10,
"pairs": 78,
"by_model": {
"claude-haiku-3.5": {"jobs": 3, "pairs": 24, "cost_usd": 9.60},
"claude-sonnet-4.6": {"jobs": 6, "pairs": 48, "cost_usd": 79.20},
"claude-opus-4": {"jobs": 1, "pairs": 6, "cost_usd": 43.20}
}
}
]
},
"error": ""
}
GET /dashboard/api/translate/refundsReturns refund history for translation purchases. Admin-only — non-admin accounts receive 403.
{
"status_code": 200,
"data": {
"refunds": [
{
"refunded_at": "2026-05-22T14:30:00Z",
"quote_id": "qt-a1b2c3d4e5f6",
"doc_name": "api-reference.html",
"customer_email": "user@example.com",
"original_amount": 11.05,
"refund_amount": 11.05,
"state": "refunded"
}
],
"count": 1
},
"error": ""
}
GET /dashboard/api/translate/notificationsReturns unread notification count and recent completed job summaries for the authenticated user's translation API key.
{
"status_code": 200,
"data": {
"unread_count": 2,
"notifications": [
{
"job_id": "019e5bdc36a5-c87d32a56bc39bee",
"completed_at": "2026-05-24T21:25:00Z",
"state": "succeeded",
"docs": ["Trinity-Beast-Translation-Service.html"],
"langs": 11,
"succeeded_pairs": 11,
"failed_pairs": 0
}
]
},
"error": ""
}
POST /dashboard/api/translate/notifications/seenMarks all notifications as seen. Resets the badge count to 0. No request body required.
{
"status_code": 200,
"data": {
"message": "Notifications marked as seen"
},
"error": ""
}
Polling behavior: The dashboard SPA polls /dashboard/api/translate/notifications every 60 seconds. The seen state is stored in Valkey at dashboard:notifications:seen:{api_key_id} with a 30-day TTL. Only translation job completions generate notifications — quotes, cancellations, and in-progress updates do not.
Automated multi-lingual JSON key translation for the website's internationalization system. Detects missing keys across all 11 target languages and fills them via Amazon Bedrock (Claude) or manual injection. The website serves language JSON from Valkey via GET /public/lang/{code} — this endpoint keeps all languages in sync with English.
Detects missing keys and translates them. Bedrock mode is async (fire-and-forget) — returns a job ID immediately and processes in the background. Manual mode and dry-run are synchronous.
| Property | Value |
|---|---|
| Endpoint | POST /admin/translate-i18n-keys |
| Auth | X-Admin-Key header |
| Content-Type | application/json |
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | "bedrock" | "bedrock" (async, AI-powered) or "manual" (sync, pre-translated values) |
namespace | string | "*" | Target namespace prefix (e.g., "translate", "docLibrary", "*" for all) |
target_langs | string[] | ["all"] | ["all"] or specific codes like ["es","pt","fr"] |
dry_run | bool | false | If true, report missing keys without writing |
keys | object | null | Manual mode only — pre-translated key/value pairs per language |
sync_s3 | bool | false | Reserved — sync updated JSON to S3 after translation |
POST /admin/translate-i18n-keys
X-Admin-Key: {admin_key}
Content-Type: application/json
{
"namespace": "translate",
"target_langs": ["all"]
}
{
"status": "✅ [LPO] [us-east-2] [BeastMain] [/admin/translate-i18n-keys] [202]",
"status_code": 202,
"data": {
"status": "accepted",
"job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"mode": "bedrock",
"namespace": "translate",
"source_keys": 62,
"target_langs": ["es","pt","fr","de","ru","hi","ur","it","ar","ja","zh"],
"message": "Translation job started. Poll /admin/translate-i18n-keys/status/{job_id} for progress."
}
}
POST /admin/translate-i18n-keys
X-Admin-Key: {admin_key}
Content-Type: application/json
{
"namespace": "*",
"dry_run": true,
"target_langs": ["es","ja"]
}
{
"data": {
"status": "dry_run",
"namespace": "*",
"source_keys": 1583,
"languages": [
{"lang": "es", "missing_keys": ["dailyReports.loadError", "..."], "status": "dry_run"},
{"lang": "ja", "missing_keys": ["dailyReports.loadError", "..."], "status": "dry_run"}
]
}
}
POST /admin/translate-i18n-keys
X-Admin-Key: {admin_key}
Content-Type: application/json
{
"mode": "manual",
"namespace": "translate",
"target_langs": ["all"],
"keys": {
"translate.hero.title": {
"es": "Motor de Traducción",
"pt": "Motor de Tradução",
"fr": "Moteur de Traduction",
"de": "Übersetzungsmaschine",
"ru": "Движок перевода",
"hi": "अनुवाद इंजन",
"ur": "ترجمہ انجن",
"it": "Motore di Traduzione",
"ar": "محرك الترجمة",
"ja": "翻訳エンジン",
"zh": "翻译引擎"
}
}
}
Poll the status of an async Bedrock translation job. Jobs are stored in Valkey with a 24-hour TTL.
| Property | Value |
|---|---|
| Endpoint | GET /admin/translate-i18n-keys/status/{job_id} |
| Auth | X-Admin-Key header |
{
"data": {
"job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "completed",
"mode": "bedrock",
"namespace": "translate",
"source_keys": 62,
"target_langs": ["es","pt","fr","de","ru","hi","ur","it","ar","ja","zh"],
"started_at": "2026-05-22T19:10:00Z",
"completed_at": "2026-05-22T19:12:34Z",
"total_translated": 682,
"languages": [
{"lang": "es", "translated": 62, "status": "ok"},
{"lang": "pt", "translated": 62, "status": "ok"},
{"lang": "fr", "translated": 62, "status": "ok"}
]
}
}
| Code | Language | Code | Language |
|---|---|---|---|
es | Spanish | ar | Arabic |
pt | Portuguese | ja | Japanese |
fr | French | zh | Chinese (Simplified) |
de | German | it | Italian |
ru | Russian | hi | Hindi |
ur | Urdu |
lang:en from Valkey (source of truth for all i18n keys)translate.hero.title)lang:{code} and identifies missing keysGET /public/lang/{code}us.anthropic.claude-sonnet-4-6)i18n:job:{job_id} with 24-hour TTLbash scripts/kcc.sh push-langs to sync Valkey → S3 if needed