API authentication and keys
How API keys work: creating them, scopes, expiry, revoking, and how they differ from your TJA_ license key.
Every authenticated call to /api/v1 carries an API key. A key stands in for your account the way a browser session does, but it is meant for scripts: no cookies, no sign-in page, no expiry unless you ask for one.
Keys are created and revoked in Account → Connections, behind the Create API key button in the API keys section of that tab.
Sending the key
Preferred — a bearer token:
curl -s https://threejsassets.com/api/v1/me \
-H "Authorization: Bearer tja_live_…"Equivalent — the X-API-Key alias, for clients that reserve Authorization for something else:
curl -s https://threejsassets.com/api/v1/me \
-H "X-API-Key: tja_live_…"If both are present, the Authorization header wins. Send the key as a header only: never in a query string, never in client-side JavaScript, never committed to a repository.
An API key is not your TJA_ license key
These are two different credentials and they are not interchangeable. This is the single most common mix-up, so it is worth being blunt about:
| API key | License key | |
|---|---|---|
| Looks like | tja_live_… | TJA_XXXX-XXXX-… |
| Identifies | your account | one purchase |
| Used with | /api/v1/*, as a header | /api/download, in the JSON body |
| Created by | you, in Connections | issued automatically with an order |
| How many | up to 10 at a time | one per order |
Passing a TJA_ license key as Authorization: Bearer does not work. It is rejected before any lookup happens and you get:
{
"error": {
"code": "invalid_api_key",
"message": "That API key isn't valid. Check it was copied in full, or create a new one in your account's Connections tab.",
"request_id": "5f3c9a10-2d6b-4b2e-9f77-1c0a8de41b52"
}
}If you see invalid_api_key and your credential starts with TJA_, you are on the wrong endpoint: license keys belong to the older /api/download route described in Downloading your packs. The reverse also holds — an API key is not accepted there.
The API never returns a license key in full. /v1/orders shows a masked preview only.
The key is shown exactly once
When you create a key, the full value appears in the create dialog, with a Copy button next to it. It is stored only as a hash, so nobody — including support — can display it again once you close that dialog.
If you lose a key, revoke it and create a replacement. There is no "show key" and no recovery.
A key looks like this:
tja_live_9f2cKp3xQm7RvL0aZs4Td8Bn1YhE6Wug_4kR7pq
└───┬───┘└──────────────┬─────────────┘ └──┬──┘
prefix random secret checksumThe tja_live_ prefix makes keys easy to spot in a config file or a secret scanner. The trailing checksum catches a truncated copy-paste before anything else is checked.
Scopes
Each key carries a set of scopes. Both are selected by default, which is what most people want; narrowing them is how you make a key that is worthless to a thief.
| Scope | Grants |
|---|---|
catalog:read | /v1/me, /v1/packs, /v1/assets, /v1/orders |
downloads:read | /v1/packs/:slug/download, /v1/assets/:slug/download |
A key with only catalog:read can inventory your library but cannot pull a single byte of a file. Calling a download endpoint with it returns 403 insufficient_scope:
{
"error": {
"code": "insufficient_scope",
"message": "This key is missing the \"downloads:read\" scope. Create a new key with it enabled.",
"request_id": "5f3c9a10-2d6b-4b2e-9f77-1c0a8de41b52"
}
}Scopes cannot be edited after creation. To change them, create a new key and revoke the old one.
Expiry
When you create a key you choose how long it lives:
- Never expires (the default)
- 90 days
- 1 year
A key with an expiry stops working the moment it passes — calls return 401 expired_api_key. Fourteen days before that happens we email you, so a build server does not fail at 3am with no warning.
Pick a TTL for keys you hand to someone else or paste into a third-party CI system. Pick "never" for a key you control and can revoke yourself.
Revoking a key
Open Account → Connections and select Revoke next to the key. Revocation is immediate and permanent; the next call with that key returns 401 revoked_api_key.
Revoke a key when:
- it has been committed to a repository or pasted into a chat;
- a machine or contractor no longer needs access;
- the Connections tab's Recent API downloads list shows a download you did not make.
Revoking a key never affects your purchases, your license keys, or your other keys. You can always revoke, even while API access is otherwise unavailable to your account.
Limits and good practice
- Up to 10 active keys per account. Revoke one to make room for another.
- One key per machine or job, named after it. That way revoking is surgical, and
/v1/metells you which one is calling. - Store keys in a secret manager or environment variable, not in source.
TJA_API_KEYis the name our examples use. - Rotate by overlap: create the new key, deploy it, then revoke the old one.
Who can use the API
API access requires a purchase — buy any pack or lifetime access and the Connections tab opens up. If access is unavailable for your account you will see a notice explaining why in the Connections tab, and calls return 403 api_disabled or 403 not_eligible. Existing keys are left intact in that case; they simply fail until access returns.
Partner access
Listing our catalog on your own site needs no key and no account at all — the public /v1/catalog/* endpoints are open, as the endpoint reference explains. What listings do need is a visible credit: "by ThreeJS Assets" on each card is the style we prefer, and a single "Assets by ThreeJS Assets" per page also works — both are shown, with copy-paste snippets, on threejsassets.com/partner. A key only enters the picture when you want to download or import actual model files, which live on the authenticated /v1/assets routes.
If you are on a free account and want that, request access through the form on threejsassets.com/partner. Approval is manual — a person reads every request and replies by email, so there is no instant grant. Once you are approved, the Connections tab opens up and you create keys the normal way; a free account's keys cover free-tier files only.