API reference
Every endpoint, request examples, input and output shapes, error codes, rate limits.
On this page
Getting started
Tools
Account
Reference
Overview
REST over HTTPS. Every /api/v1/* endpoint is synchronous —
you upload, the server processes, the response body is the result. No queues, no polling, no webhooks.
Base URL: https://low-poly.com/api/v1
| Endpoint | Purpose | Returns | Cost |
|---|---|---|---|
POST /tools/reduce | Decimate a mesh | binary (mesh) | 1 credit |
POST /tools/convert | Format swap | binary (mesh) | 1 credit |
POST /tools/lod | LOD levels bundle | application/zip | 1 / level |
POST /tools/pivot | Recenter pivot | binary (mesh) | 1 credit |
POST /tools/batch | Process many files | application/zip | 1 / success |
GET /me | Account info | application/json | free |
Endpoint paths on this page are shown relative to the base URL. For example, /tools/reduce resolves to https://low-poly.com/api/v1/tools/reduce.
Authentication
Send your key as a bearer token in the Authorization header.
Create and rotate keys on your API keys page.
Missing or invalid keys return 401 unauthorized.
Authorization: Bearer lp_live_xxxxxxxxxxxxxxxxxxxxxxxx
Supported formats
Maximum upload size is 100 MB per file. The output format defaults to the input extension when omitted.
| Extension | Name | Read | Write |
|---|---|---|---|
glb | GLB | yes | yes |
gltf | glTF | yes | yes |
obj | OBJ | yes | yes |
fbx | FBX | yes | yes |
3ds | 3DS | yes | yes |
blend | Blender | yes | — |
POST /tools/reduce
Decimate a mesh while preserving its silhouette (meshoptimizer).
Content-Type: multipart/form-data
Request parameters
- filebinaryrequired
Input mesh. The extension must match a supported format.
- rationumber 0.05–1.0optional default:
0.25Fraction of triangles to keep.
0.25= keep 25%. - formatstringoptional default:
input formatOutput format. One of
glb,gltf,obj,fbx,3ds.
Response
200 OK — application/octet-stream, body is the processed mesh.
- X-Tris-In
- Input triangle count
- X-Tris-Out
- Output triangle count
- X-Credits-Cost
- Credits charged for this call
- X-Credits-Remaining
- Credits left on the account
- X-RateLimit-*
- Standard rate-limit headers (see Rate limits)
curl -X POST https://low-poly.com/api/v1/tools/reduce \
-H "Authorization: Bearer lp_live_..." \
-F "file=@dragon.glb" \
-F "ratio=0.25" \
-F "format=glb" \
-o dragon-low.glb
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="dragon-low.glb"
X-Tris-In: 184502
X-Tris-Out: 46125
X-Credits-Cost: 1
X-Credits-Remaining: 4819
POST /tools/convert
Format swap, no decimation. Same fields as /tools/reduce; ratio is forced to 1.0.
Content-Type: multipart/form-data
Request parameters
- filebinaryrequired
Input mesh.
- formatstringrequired
Target format. Must differ from the input to be useful.
Response
200 OK — application/octet-stream, body is the converted mesh. Same headers as /tools/reduce.
curl -X POST https://low-poly.com/api/v1/tools/convert \
-H "Authorization: Bearer lp_live_..." \
-F "file=@character.fbx" \
-F "format=glb" \
-o character.glb
POST /tools/lod
Generate several decimated levels from one model in a single call. Returns a ZIP, one file per ratio.
Content-Type: multipart/form-data
Request parameters
- filebinaryrequired
Input mesh.
- ratioscsv (0<r≤1)optional default:
0.6,0.3,0.15,0.05Comma-separated list of ratios, one per level. Clamped to
[0.005, 1.0]. - formatstringoptional default:
input formatOutput format applied to every level.
Response
200 OK — application/zip. Entries are named {stem}-lod{i}-r{ratio}.{ext}.
- X-Lod-Levels
- Number of LOD levels in the archive
- X-Credits-Cost
- Credits charged (1 per level)
- X-Credits-Remaining
- Credits left on the account
curl -X POST https://low-poly.com/api/v1/tools/lod \
-H "Authorization: Bearer lp_live_..." \
-F "file=@tree.glb" \
-F "ratios=0.6,0.3,0.15,0.05" \
-F "format=glb" \
-o tree-lod.zip
tree-lod0-r0.60.glb
tree-lod1-r0.30.glb
tree-lod2-r0.15.glb
tree-lod3-r0.05.glb
POST /tools/pivot
Recenter a model's pivot point.
Content-Type: multipart/form-data
Request parameters
- filebinaryrequired
Input mesh.
- modestringoptional default:
centerOne of
center(bounding-box center),origin(world origin),ground(XZ-centered, Y at minimum). - formatstringoptional default:
input formatOutput format.
Response
200 OK — application/octet-stream. X-Pivot-Mode echoes the applied mode; X-Credits-Cost / X-Credits-Remaining report billing.
curl -X POST https://low-poly.com/api/v1/tools/pivot \
-H "Authorization: Bearer lp_live_..." \
-F "file=@prop.glb" \
-F "mode=ground" \
-o prop-ground.glb
POST /tools/batch
Process many files in a single request. Returns a ZIP, one decimated file per input. Files that fail processing are skipped from the ZIP and reported in X-Batch-Error-List; you are billed only for successful files.
Content-Type: multipart/form-data
Request parameters
- files[]binary (repeated)required
Up to 500 files per batch.
- rationumber 0.05–1.0optional default:
0.25Decimation ratio applied to every file.
Response
200 OK — application/zip named batch.zip. Each entry is {originalName}-low.{ext}.
- X-Batch-Count
- Files submitted
- X-Batch-Succeeded
- Files that processed successfully
- X-Batch-Errors
- Files that failed processing
- X-Batch-Error-List
- JSON array of
{name, error}(empty when 0) - X-Credits-Cost
- Credits charged (1 per successful file)
- X-Credits-Remaining
- Credits left on the account
curl -X POST https://low-poly.com/api/v1/tools/batch \
-H "Authorization: Bearer lp_live_..." \
-F "files[]=@rock_01.obj" \
-F "files[]=@rock_02.obj" \
-F "files[]=@rock_03.obj" \
-F "ratio=0.3" \
-o rocks-low.zip
GET /me
Inspect the authenticated account: user, credit balance, key id. Does not consume credits.
Response
200 OK — application/json
curl https://low-poly.com/api/v1/me \
-H "Authorization: Bearer lp_live_..."
{
"user": {
"id": 42,
"email": "you@studio.com",
"name": "You"
},
"credits": {
"balance": 4820
},
"key": {
"id": 17
}
}
Rate limits
Per-key, per-minute. Every /api/v1/* response carries the standard rate-limit headers. /tools/lod and /tools/pivot are additionally capped at 30 calls/min each.
Hitting the cap returns 429 rate_limited.
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1763251200
Errors
All errors return JSON with a stable code string. Branch on code; message is for humans.
| Status | Code | When |
|---|---|---|
400 | missing_file | No file field, or upload error |
400 | unsupported_format | Extension not in the supported list |
400 | bad_mode | /tools/pivot: invalid mode value |
400 | missing_files | /tools/batch: no files |
400 | too_many | /tools/batch: more than 500 files |
401 | unauthorized | Missing or invalid bearer token |
402 | insufficient_credits | Account is out of credits |
413 | file_too_large | Upload exceeds the 100 MB limit |
429 | rate_limited | Per-minute cap exceeded |
500 | processing_failed | Mesh pipeline raised an error; message carries the detail |
{
"error": {
"code": "rate_limited",
"message": "Too many requests"
}
}
CORS
All /api/v1/* endpoints set permissive CORS headers (Access-Control-Allow-Origin: * by default). Browser uploads from your own domain work out of the box.