# Free3D Plugin API Developer Guide

This guide describes how external plugins should use Free3D through the public browser-auth and direct static file pipeline.

## Flow

Use this sequence:

1. Start browser approval with `POST /api/apps/auth/start`
2. Poll until the plugin token is approved
3. Read the model file inventory through `GET /api/plugin/download/formats/{guid}`
4. Select the exact discovery variant you want to import
5. Request that exact direct file through `POST /api/plugin/download/direct`
6. Download the returned scene file plus `supportFiles`
7. Import into the current DCC scene

The exact selection tuple is:

- `format`
- `lod`
- `relativePath`
- `variant` when present

Treat that tuple as authoritative.

## Required scopes

- `account:read`
- `balance:read`
- `entitlements:read`
- `download:direct`
- `scene:import`

## Discovery route

`GET /api/plugin/download/formats/{guid}` returns:

- pricing state
- worker direct-file availability
- preview URLs
- `fbxVariants`
- `maxVariants`
- an `import` block with the canonical direct-download route

Each variant may include a `downloadRequest` object. Use it as the exact request body for the direct route when present.

Do not collapse multiple files with the same extension into one logical choice yourself. One model can expose `.fbx` or `.max` in multiple topology folders such as `1k`, `10k`, and `100k`.

## Direct route

`POST /api/plugin/download/direct`

Request body:

```json
{
  "guid": "product-guid",
  "format": "fbx",
  "lod": "100k",
  "variant": "static",
  "relativePath": "uploads_files_6372157_100k/example_static.fbx"
}
```

Response includes:

- `downloadUrl`
- `fileName`
- `contentType`
- `relativePath`
- `supportFiles`
- `import.sceneRelativePath`
- `import.assetsRootUrl`
- `import.searchPaths`

Interpretation rules:

- `downloadUrl` is already the final worker URL.
- `relativePath` is the canonical product-relative path for the selected scene file.
- `supportFiles[]` should be downloaded preserving their `relativePath`.
- `import.assetsRootUrl` should point at the selected topology folder root.
- `import.searchPaths` should be registered before import so textures resolve predictably.

## 3ds Max implementation notes

- Download the main FBX first.
- Download every `supportFiles[]` entry preserving `relativePath`.
- Register search paths before import so textures resolve cleanly.
- Import additively into the current scene.
- Keep material names unique per imported model GUID.
- Do not expect the worker to build a bundle at request time.
- Prefer `animated` FBX for characters and `static` FBX for static models when both exist.
- Prefer the selected topology from discovery instead of assuming `100k`.

## Forbidden assumptions

- No `POST /api/download/prepare`
- No prepared ZIP bundle
- No temporary worker cache key
- No fallback to ZIP when an exact file is missing
- No heuristic rebuild of `relativePath`
- No guessing topology from file extension alone

## Unity implementation notes

- Ship the plugin as a single editor script located at `Assets/Editor/free3d_online.cs`.
- Use the published update feed before startup import work so the editor script can self-update safely.
- Support public category and type filters from `/api-embeddings/filters` without inventing local category aliases.
- Prefer exact `fbxVariants` returned by discovery and preserve topology ordering `100k`, `10k`, `1k`.
- Download support textures preserving `relativePath` and build Unity-ready materials for Built-in Standard, URP Lit, and HDRP Lit.
- Never use `render_view`, poster, preview, or beauty renders as base color maps.

## Quick smoke test

```bash
curl -H "Authorization: Bearer $PLUGIN_TOKEN" \
  "https://free3d.online/api/plugin/download/formats/<guid>"

curl -X POST \
  -H "Authorization: Bearer $PLUGIN_TOKEN" \
  -H "Content-Type: application/json" \
  "https://free3d.online/api/plugin/download/direct" \
  -d '{"guid":"<guid>","format":"fbx","lod":"100k","variant":"static","relativePath":"uploads_files_6372157_100k/example_static.fbx"}'
```

If the direct route fails, fix the inventory or variant metadata. Do not reintroduce prepare-stage logic in the plugin.
