# Aether API V3 Frontend Integration Guide (Svelte/TypeScript) This guide explains how to update or create frontend functions to interact with the new **Aether API V3 CRUD** and **Action** endpoints. V3 introduces a nested URL structure, a powerful POST-based search, and specialized "Action" routes for binary data. --- ## 1. Key Differences (V2 vs V3) | Feature | CRUD V2 (Legacy) | CRUD V3 (Modern) | | ------------------ | --------------------- | ---------------------------------------------------- | | **Base Prefix** | `/v2/crud` | `/v3/crud` | | **List Suffix** | Uses `/list` | **No suffix** (e.g., `/v3/crud/journal/`) | | **Nested Path** | Not supported in URL | **Supported** (e.g., `/v3/crud/journal/{id}/entry/`) | | **View Selection** | `tbl_alt`, `mdl_alt` | **`view` parameter** (e.g., `?view=enriched`) | | **Complex Search** | Limited to GET `jp` | **POST `/search`** (Unlimited size + Hybrid params) | | **Full-Text** | Manual column names | **Reserved `q` property** in SearchQuery | --- ## 2. Authentication and Security (Mandatory) As of January 2026, the V3 architecture enforces strict **Multi-Tenant Isolation** and **Machine Authorization**. Most requests require two levels of validation. ### A. The "Entry Ticket" (API Key) **Mandatory for all requests.** Every request must provide a valid `x-aether-api-key` in the header. This identifies the application or script. * **Header:** `x-aether-api-key: ` * **Status Code:** `403 Forbidden` if missing, invalid, or expired. ### B. The "Visa" (Account Context) Once the API Key is validated, you must specify the context of your request. 1. **Standard User Access**: Provide the `x-account-id` (the random string ID). * **Header:** `x-account-id: ` 2. **Administrative Bypass**: For authorized scripts needing global access. * **Header:** `x-no-account-id: bypass` 3. **Guest / Anonymous Access**: Provide a **Safe Guest JWT**. * **Header:** `x-aether-api-key: ` (No Account Header) * **Query Param:** `?jwt=` --- ## 3. Implementing V3 CRUD Functions ### A. List & Single Object (GET) ```ts // GET /v3/crud/journal/{id}?view=enriched export async function get_ae_obj_v3({ api_cfg, obj_type, obj_id, view = 'default' }) { const endpoint = `/v3/crud/${obj_type}/${obj_id}`; return await get_object({ api_cfg, endpoint, params: { view } }); } ``` ### B. Advanced & Hybrid Search (POST) ```ts // POST /v3/crud/{obj_type}/search export async function search_ae_obj_v3({ api_cfg, obj_type, search_query, enabled = 'enabled' }) { const endpoint = `/v3/crud/${obj_type}/search`; return await post_object({ api_cfg, endpoint, params: { enabled }, data: search_query }); } ``` --- ## 4. Hosted File Management (Modern V3 Actions) V3 uses specialized **"Action"** routes for binary operations to separate processing logic from standard metadata CRUD. ### A. Upload Action **Path**: `POST /v3/action/hosted_file/upload` **Format**: `multipart/form-data` | Field | Type | Required | Description | | :--- | :--- | :--- | :--- | | `file_list` | File[] | Yes | One or more files to upload. | | `account_id` | String | Yes | Random ID of the owner account. | | `link_to_type`| String | Yes | Object type to link (e.g., `archive_content`). | | `link_to_id` | String | Yes | Random ID of the object to link. | **Query Parameters:** - `allowed_extensions`: Whitelist check (e.g., `?allowed_extensions=png&allowed_extensions=jpg`). - `delay_ms`: Simulate network delay for UI testing. **Features:** - **Automatic Deduplication:** API checks SHA256 hashes. If a file exists on the server, it reuses the record and creates a new link instead of a duplicate upload. - **Relational Integrity:** Automatically creates `hosted_file_link` records. ### B. Download & Streaming Action **Path**: `GET /v3/action/hosted_file/{id}/download` **Features:** - **Streaming:** Supports standard `Range` headers for large files and video seeking. - **Auth Bypass:** Use `?site_key=` to download without an API Key header or JWT (useful for public kiosks). - **Testing:** Supports `delay_ms` query parameter. ### C. Deletion & Cleanup Action **Path**: `DELETE /v3/action/hosted_file/{id}` | Parameter | Type | Default | Description | | :--- | :--- | :--- | :--- | | `link_to_type`| Query | null | The type of the link to remove. | | `link_to_id` | Query | null | The random ID of the link to remove. | | `rm_orphan` | Query | false | If true, physically delete file if no links remain. | | `method` | Query | `hide` | Cleanup method: `hide`, `disable`, or `delete` (hard). | | `fake_delete` | Query | false | **Testing Mode:** Verifies file/record existence without modification. | --- ## 5. Hosted File Management (Legacy) The following endpoints are maintained for backward compatibility but should be migrated to V3 Actions. | Method | Endpoint | Description | | :--- | :--- | :--- | | `POST` | `/hosted_file/upload_files` | Legacy multi-upload. | | `GET` | `/hosted_file/{id}/download` | Legacy download. | | `GET` | `/hosted_file/{id}/stream` | Legacy buffered streamer. | | `DELETE` | `/hosted_file/{id}` | Legacy deletion. | --- ## 6. The "ID Vision" Standard (2026) V3 uses a **String-Only ID Vision**. The frontend NEVER handles or stores database integers. 1. **Automatic Mapping:** Internal `id_random` fields are mapped to `id` and `account_id` in JSON responses. 2. **Intelligent Resolution:** You can send random string IDs back to the API in any `*_id` field; the API resolves them to integers before database insertion. --- ## 7. Structured Error Handling V3 returns machine-readable error objects in `meta.details` for failures. **Common Categories:** - `database_duplicate`: Non-unique value (Code 1062). - `database_constraint`: Foreign key violation (Codes 1451, 1452). - `database_schema`: Invalid column name (Codes 1054, 1146). - `validation`: Pydantic validation failed (Check `details` for field-specific errors). --- ## 8. Data Store Cascading Lookup (V3) V3 provides a specialized endpoint for retrieving configuration or content snippets by a human-friendly `code`. This uses a **hierarchical fallback** logic to find the best fit for the current context. ### A. The V3 Lookup Endpoint **Path:** `GET /v3/data_store/code/{code}` **Query Parameters:** | Parameter | Type | Required | Description | | :--- | :--- | :--- | :--- | | `for_type` | String | No | Parent object type (e.g., `event`, `person`). | | `for_id` | String | No | Parent object random ID. | | `limit` | Integer | No | **Dynamic Return:** Default `1` (returns single object). If `> 1`, returns a list. | ### B. Cascading Logic (Specificity) The API automatically resolves the "best fit" record in the following order: 1. **Record Specific:** Matches `for_type` + `for_id` (and account). 2. **Account Specific:** Matches the `x-account-id` header. 3. **Global Default:** Matches `code` where `account_id` is `NULL`. ### C. Example Implementation ```ts // GET /v3/data_store/code/event_launcher_main_info?for_type=event&for_id=nmBfuGFeR0k&limit=1 export async function get_data_store_v3({ api_cfg, code, for_type, for_id, limit = 1 }) { const endpoint = `/v3/data_store/code/${code}`; const params = { for_type, for_id, limit }; return await get_object({ api_cfg, endpoint, params }); } ```