Investigation · 2026-10-21 live third-party reseller tripo3d.uk not affiliated with Tripo

Somebody else's 3D model, your prepaid credits

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.

Entry shell
3,396 B, one file
JS chunks
49 1.32 MB
Client routes
22 8 of them /admin
Base generation
5 credits
Key-pool floor
6,000 credits
Own payment code
0 lines
The operator's own notice

The 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:

模型生成后确定没问题最好当天下载,要不然会无法下载,放了多天的模型提交任务报错,无法下载等等情况大部分原因都是后台账号积分消耗完导致的,这种情况请各位用户重新提交图片生成模型或者点击缩略图上的紫色复用按钮,复用完成之后用新开的模型副本提交任务。GET https://tripo3d.uk/api/announcement · 555 B · sha256 81cf692e…788d

"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."

01 · What the domain actually is

FieldValueWhy it matters
Registered2026-07-03 (RDAP registration event)Four months old at the time of this teardown
Expires2027-07-03One-year term; no long commitment behind the service
RegistrarCloudflare, 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
NStara / christian.ns.cloudflare.comProxied; the origin answers with server: nginx/1.31.3
TLSLet's Encrypt CN=tripo3d.uk, issued 2026-10-02, 90-dayShort-lived cert recycled by automation, not an EV/business identity
Last-Modified on shellMon, 14 Sep 2026 11:43:40 GMTBuild shipped mid-September, matches the announcement timestamp
Official sitestripo3d.ai (global, Cloudflare 403 challenge) · tripo3d.com (Chinese)Neither links to .uk; no affiliation is claimed anywhere on the clone

02 · The product is Tripo's app, re-skinned

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:

/ /login /register /workspace/generate /workspace/image /workspace/fill-parts /workspace/retopology /workspace/rigging /workspace/segmentation /workspace/smart-segment /workspace/texture /workspace/texture-edit /workspace/texture-pbr /workspace/texture-upscale /admin /admin/users /admin/keys /admin/batch-keys /admin/logs /admin/subservers /admin/models /admin/config

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.

The copy, running

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.

tripo3d.uk · archived 21 Oct 2026 open full screen ↗

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.

03 · The meter: 5 / 10 / 15

Every generation is priced in the site's own credits, and the number is baked into the frontend rather than returned by the API:

function H(W){return p.quad?"15 积分":O()?"10 积分":"5 积分"}chunk referenced by the entry bundle — credit cost per submit

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 actionLocal creditsToggle that triggers it
Base generate5plain submit, default texture size
Texture / quality on10textureSize, textureFormat, faceLimit changed
Quad / symmetry / flatten15quad, 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).

04 · The supply side is a pool of borrowed keys

/admin/keys is not a pricing page — it is a key farm. Its own copy says so:

管理 Tripo API Key,系统自动负载均衡调用 号池总余额: … 阈值: … · 自动补充: 已开启 / 已关闭 名称 | 余额 | 并发 | 优先级 | 调用/成功 | 状态 | 到期 | 操作 🤖 获取 Keyadmin chunk — key-pool console strings

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.

visitor → tripo3d.uk (Nuxt SPA, own login) → own credit balance ↓ /api/task (cost deducted client-side first) key pool [key A: bal, conc, prio, expiry] [key B: bal, conc, prio, expiry] ← auto-fetch below 6,000 [key C: …] ↓ developers.tripo3d.ai (1 credit = US$0.01, Stripe)

05 · Where the money comes from

LineHow it is collectedEvidence in the build
1 · Prepaid credits
the main line
Users buy credits, every generation burns 5–15 of them; balance is the only gatecredit-bar title="积分余额"; if(balance < cost) abort in every workspace chunk
2 · Card keys, off-siteMoney 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 studiosBatch 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

06 · Unit economics, computed

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 callUpstream cr.Upstream US$Local cr.Break-even / local cr.
Text→3D, no texture10$0.105$0.020 · HK$0.16
Image→3D, no texture20$0.205$0.040 · HK$0.31
Image→3D + standard texture30$0.305$0.060 · HK$0.47
Quad retopo on top35$0.3515$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.

07 · Failure modes

Symptom a user seesCauseWho pays
"无法下载" on a model from last weekPool account it was generated under is drained or rotatedUser — credits already spent, file unrecoverable
Task errors on resubmitKey hit its concurrency cap or expiry date shown in /admin/keysUser — 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 allShell 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

08 · Evidence

ArtifactSizesha256 (first 16)
Served shell GET /3,396 B09c0734a9755e6ed
Eager bundle /_nuxt/Vd8lgA-y.js201,767 B465b107156620176
Largest lazy chunk DggncBCI.js (model viewer)862,093 B5d36ef8cf41f7a1c
All chunks pulled (49 files)1,320,125 Bmanifest in bundle
/api/announcement response555 B81cf692e79a0e8ee
/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)
Open the evidence bundle Hash manifest Raw announcement JSON Raw shell bytes Build spec

09 · What a buyer is actually buying

Not a licence — a balance. Credits are an unsecured prepayment recorded in a database owned by an unnamed operator on a four-month-old domain, redeemable only through keys they rent from Tripo and may lose at any time. The site's own banner states that when the pool empties, paid generations fail and are not refunded. Your account, prompts and uploaded images sit on their server, and their API sees all of it.

If the goal is cheap 3D models

  • Official tripo3d.com (Chinese) / tripo3d.ai — free tier, then Stripe credits at the same $0.01 list price the reseller buys at.
  • You keep the generations; nothing expires because someone else's pool ran dry.
  • No third party gets your prompts or your credential pair.

If the goal is understanding the genre

  • This is the shared-key arbitrage pattern: re-skin a vendor's app, meter it in your own currency, run a key pool, recurse into 分站.
  • The tell is always the same — no payment gateway in the build, an announcement about the backend account running out, and an admin screen full of upstream keys.
  • Cheap because the float is other people's money; fragile for exactly the same reason.

10 · Method

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.