tripo3d.uk is not Tripo. It is a Nuxt re-skin of Tripo's own Studio app, served from an nginx box in front of Cloudflare, that bills users in its own "积分" (credits) and settles every generation through a pool of borrowed official Tripo API keys. There is no model, no inference and no payment gateway of its own — the business is the spread between what Tripo charges per API call and what a user pays per credit, plus a wholesale layer underneath it.
/adminThe whole model is admitted in one sentence on their banner endpoint — the pool runs dry and
the customer eats it. Verbatim from /api/announcement, updated 2026-09-16:
"Download the same day. Multi-day-old models error out or refuse to download, and the main reason is that the backend accounts' credits have run out — please resubmit, or hit the purple reuse button and submit a fresh copy."
| Field | Value | Why it matters |
|---|---|---|
| Registered | 2026-07-03 (RDAP registration event) | Four months old at the time of this teardown |
| Expires | 2027-07-03 | One-year term; no long commitment behind the service |
| Registrar | Cloudflare, Inc. [Tag = CLOUDFLARE] | Privacy-by-default, so no operator identity is published |
| Registrant validation | "Nominet was not able to match the registrant's name/address against a 3rd party source" (03-Jul-2026) | Registry itself could not verify who this is |
| NS | tara / christian.ns.cloudflare.com | Proxied; the origin answers with server: nginx/1.31.3 |
| TLS | Let's Encrypt CN=tripo3d.uk, issued 2026-10-02, 90-day | Short-lived cert recycled by automation, not an EV/business identity |
| Last-Modified on shell | Mon, 14 Sep 2026 11:43:40 GMT | Build shipped mid-September, matches the announcement timestamp |
| Official sites | tripo3d.ai (global, Cloudflare 403 challenge) · tripo3d.com (Chinese) | Neither links to .uk; no affiliation is claimed anywhere on the clone |
The shell is a stock Nuxt 3 build: an empty <div id="__nuxt">, a
window.__NUXT__ config with apiBase:"" (so every call goes to the same
origin — no upstream host is exposed), and 33 preload/prefetch hints naming 22 JS and 12 CSS files.
Pulling the chunks and grepping the route table gives the whole shape of the product without ever
logging in:
Those workspaces are Tripo Studio's feature set mapped one-to-one — generate, image, fill-parts,
retopology, rigging, segmentation, smart-segment, texture, texture-edit, texture-PBR,
texture-upscale. The interesting half is the second block: eight /admin routes — a hub plus seven screens — that no
customer ever sees, and they are the business.
This is the same build, re-served from this domain with the network cut. The one file I wrote
answers /api/announcement with the body captured from the origin (that notice is the
operator's own text, nothing here is my paraphrase) and fabricates the rest of the surface:
fetch, XHR, WebSocket and service-worker registration are
blocked, and every address it stopped is logged in window.__mirrorBlocked.
The login is part of the fabrication. Any username and any password are accepted — the
guard answers /api/auth/login locally, so the workspace renders with
128 credits that are a constant in mirror-guard.js, not an account.
That is the point: the paid screens are what the teardown is describing, and you cannot see them
on the real site without an account the operator sells.
A submitted job is a demo too: the guard keeps a timestamp, reports a rising percentage for
seven seconds, then puts a Khronos sample model on the stage — the duck, labelled DEMO —
so the viewer, the material presets and the export buttons can be used. Nothing was generated from
your picture and nothing was sent anywhere; the same local .glb is what 导出 hands
back.
Type anything into the two fields and you are in — that is the demo, not a hole in
their auth: the credential check never leaves this page. Upload a picture, press 生成模型,
and seven seconds later the stage loads the sample model — client-side routing works across all
twenty routes, including the eight /admin screens, all of them running on empty
stubs. Deep-linking and reloading a route 404s by design (there is no server behind this);
use open full screen ↗ and the in-app nav. The seven documented deltas to the shell are in
tripo3d-uk-mirror/MIRROR.md — no JS or CSS was edited, and the 49 chunks still hash
to the origin manifest.
Every generation is priced in the site's own credits, and the number is baked into the frontend rather than returned by the API:
The O() branch is the tell. It turns true when any of quad,
forceSymmetry, flattenBottom, faceLimit,
textureSize !== 4096 or textureFormat is touched — i.e. the local
"5 / 10 / 15" tiers are Tripo's own add-on ladder (HD texture, HD geometry, quad mesh, advanced
convert) re-priced, not a usage cost the operator measures.
| User action | Local credits | Toggle that triggers it |
|---|---|---|
| Base generate | 5 | plain submit, default texture size |
| Texture / quality on | 10 | textureSize, textureFormat, faceLimit changed |
| Quad / symmetry / flatten | 15 | quad, forceSymmetry, flattenBottom |
| Export | +N | "导出 FBX(N 积分)" — per-format charge; GLB is the free one |
The gate is client-side and absolute: if(balance < cost) → "积分不足 (需要 X,当前 Y)".
Nothing generates without a positive balance, and balance only moves two ways: a generation, or an
administrator typing a number into /admin/users (the panel reports "扣除成功 /
扣除失败", deduct succeeded / failed).
/admin/keys is not a pricing page — it is a key farm. Its own copy says so:
Each row is an official Tripo API key with its own balance, concurrency cap, priority and
expiry date. The pool has a floor of 6,000 credits and an auto-replenish switch — when the
total drops below the threshold it fetches more keys. A separate
/admin/subservers screen switches traffic mode between
"仅主服务器 / 仅子服务器 / 主+子混合" (main only / sub only / mixed) and reloads the sub-server
list, so the same upstream pool can be shared across several front-ends.
| Line | How it is collected | Evidence in the build |
|---|---|---|
| 1 · Prepaid credits the main line | Users buy credits, every generation burns 5–15 of them; balance is the only gate | credit-bar title="积分余额"; if(balance < cost) abort in every workspace chunk |
| 2 · Card keys, off-site | Money never touches the app. No gateway, no order table, no webhook — credits are added by hand after payment happens elsewhere (group chat / card-key shop) | Zero payment strings across 1.32 MB of JS; the only balance mutations are /admin/users and POST /admin/batch-keys/{id}/recharge ("充值成功") |
| 3 · API keys for studios | Batch image→3D sold as its own product: the operator issues keys, each with a balance and a usage counter, plus a downloadable Windows client | /admin/batch-keys · "管理批量图片转模型 API Key" · "客户端下载地址(含 Windows EXE)" · columns 积分余额 / 累计消耗 |
| 4 · Sub-dealers (分站) the real margin | Other operators run their own branded front-end against this pool and buy credits wholesale; the spread is earned twice, and volume arrives without marketing | /admin/subservers, /api/admin/subserver/auth, PUT /api/admin/subserver/mode |
Upstream list prices are public, so the floor price of one local credit can be derived instead of guessed. Tripo's developer tier is 1 credit = US$0.01; H-series generation runs 10 credits (text→3D, no texture) to 30 (image→3D with standard texture). Against a 5-credit base charge:
| Upstream call | Upstream cr. | Upstream US$ | Local cr. | Break-even / local cr. |
|---|---|---|---|---|
| Text→3D, no texture | 10 | $0.10 | 5 | $0.020 · HK$0.16 |
| Image→3D, no texture | 20 | $0.20 | 5 | $0.040 · HK$0.31 |
| Image→3D + standard texture | 30 | $0.30 | 5 | $0.060 · HK$0.47 |
| Quad retopo on top | 35 | $0.35 | 15 | $0.023 · HK$0.18 |
So a local credit that sells for HK$0.50–1.00 (the usual band for these panels) is roughly 1.1×–6× the upstream cost on the base tier — healthy gross margin, and the quad/texture tiers are pure markup because they charge 2–3× the local credits for add-ons that cost Tripo $0.05–0.10. Note what is not in this column: the site publishes no price list and has no checkout, which is why the number you actually pay is settled in a chat window and not here.
The margin has one structural weakness, and it is the one the operator advertises. A shared pool lets them sell more credits than the pool can serve — that is the float. When the pool empties, the shortfall is not absorbed by the business, it is absorbed by whoever was mid-task. The announcement at the top of this page is that policy written down.
| Symptom a user sees | Cause | Who pays |
|---|---|---|
| "无法下载" on a model from last week | Pool account it was generated under is drained or rotated | User — credits already spent, file unrecoverable |
| Task errors on resubmit | Key hit its concurrency cap or expiry date shown in /admin/keys | User — retry burns more credits |
| Site dies with 401s | /api/auth/refresh fails; the SPA forces re-login ("登录凭证已刷新,请重新上传") | User — and their balance lives on someone else's database |
| Nothing renders at all | Shell is 3.4 KB with an empty #__nuxt; all 1.32 MB comes from /_nuxt/* | Anyone — the app is unarchivable without the bundle, which is why the evidence bundle below exists |
| Artifact | Size | sha256 (first 16) |
|---|---|---|
Served shell GET / | 3,396 B | 09c0734a9755e6ed |
Eager bundle /_nuxt/Vd8lgA-y.js | 201,767 B | 465b107156620176 |
Largest lazy chunk DggncBCI.js (model viewer) | 862,093 B | 5d36ef8cf41f7a1c |
| All chunks pulled (49 files) | 1,320,125 B | manifest in bundle |
/api/announcement response | 555 B | 81cf692e79a0e8ee |
/api/auth/me, /api/user/balance unauthenticated | — | HTTP 401 {"code":401,"message":"missing token"} |
/api/health, /api/config | — | HTTP 404, JSON body (endpoints do not exist) |
Fetched the shell, parsed its modulepreload hints, pulled all 49 referenced chunks (1.32 MB),
grep'd the route table, the /api/ and /admin/ endpoint sets, credit-cost
branches and every Chinese string literal in the admin chunks. Cross-checked registration and DNS
against Nominet RDAP and whois.nic.uk, and upstream credit prices against
developers.tripo3d.ai/en/pricing (read 2026-10-21: 1 credit = US$0.01; H-series 10/20/30).
No account was created, no login attempted, no payment page exists to attempt.