File Download API¶
Overview¶
The PrimeThink API provides a simple endpoint for downloading files directly by their path in live apps. This endpoint supports the three-tier storage hierarchy (@public, @liveapp, chat root) and automatically enforces access control based on the file location.
For detailed information about file storage locations and access control, see File Storage Hierarchy.
Endpoint¶
This endpoint streams file content with proper MIME types for browser display and downloading.
URL Structure¶
Parameters: - chat_id (UUID, required): The unique identifier of the chat - document_path (string, required): The file path, which can be: - Simple filename: demo.pdf - Nested path: folder/subfolder/file.js - @public prefix: @public/brochure.pdf - @liveapp prefix: @liveapp/template.json
Response Format¶
Success Response: - Status: 200 OK - Content-Type: Proper MIME type (e.g., application/pdf, image/png, text/plain) - Content-Disposition: inline; filename="filename.ext" - Body: File content streamed directly
Error Responses: - 401 Unauthorized: Authentication required - 403 Forbidden: User not in chat - 404 Not Found: File doesn't exist
Usage Examples¶
Example 1: Download Public File (No Authentication)¶
Files in the @public folder are accessible without authentication.
Request:
curl "https://api.example.com/api/v1/live_apps/a48f5a26-14f7-4737-ae7c-19651b981aaf/@public/brochure.pdf"
Response:
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: inline; filename="brochure.pdf"
[PDF binary content]
What Happens: 1. System recognizes @public prefix 2. Looks for file in root.public storage 3. Streams file content (no auth required) 4. Browser displays PDF inline
Example 2: Download Simple Filename (Searches Multiple Locations)¶
When you provide just a filename, the system searches in priority order: @public → @liveapps → chat root.
Request:
curl -H "Authorization: Bearer <token>" \
"https://api.example.com/api/v1/live_apps/a48f5a26-14f7-4737-ae7c-19651b981aaf/report.xlsx"
Response:
HTTP/1.1 200 OK
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Disposition: inline; filename="report.xlsx"
[Excel binary content]
What Happens: 1. System searches in order: @public → @liveapps → chat root 2. Finds file in @liveapps 3. Verifies user is authenticated 4. Streams file content 5. Browser triggers download or displays file
Example 3: Download Nested Path (Chat-Specific)¶
Nested paths skip the @public and @liveapps search and go directly to the chat root.
Request:
curl -H "Authorization: Bearer <token>" \
"https://api.example.com/api/v1/live_apps/a48f5a26-14f7-4737-ae7c-19651b981aaf/projects/2024/analysis.csv"
Response:
HTTP/1.1 200 OK
Content-Type: text/csv
Content-Disposition: inline; filename="analysis.csv"
[CSV content]
What Happens: 1. System recognizes nested path (contains /) 2. Skips @public and @liveapps search 3. Goes directly to chat root: root.projects.2024 4. Verifies user is authenticated AND in chat 5. Streams file content
Example 4: Download @liveapp File¶
Files in the @liveapp folder require authentication but not chat membership.
Request:
curl -H "Authorization: Bearer <token>" \
"https://api.example.com/api/v1/live_apps/a48f5a26-14f7-4737-ae7c-19651b981aaf/@liveapp/template.json"
Response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Disposition: inline; filename="template.json"
{
"name": "Template",
"version": "1.0"
}
What Happens: 1. System recognizes @liveapp prefix 2. Looks for file in root.liveapps storage 3. Verifies user is authenticated (group membership) 4. Does NOT check chat membership 5. Streams file content
Example 5: Error - File Not Found¶
Request:
curl "https://api.example.com/api/v1/live_apps/a48f5a26-14f7-4737-ae7c-19651b981aaf/nonexistent.pdf"
Response:
Example 6: Error - Authentication Required¶
Request:
Response:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"detail": "Authentication required to access this document"
}
File Path Rules¶
Valid Path Formats¶
✅ Simple filename:
✅ Nested path:
✅ @public prefix:
✅ @liveapp prefix:
Invalid Path Formats¶
❌ Empty path:
❌ Only special prefix without filename:
❌ Multiple slashes:
Authentication¶
No Authentication Required:¶
- Files in
@publicfolder - Example:
@public/brochure.pdf
Bearer Token Required:¶
- Files in
@liveappfolder - Files in chat root
- Nested paths
Header Format:
Token Contains: - User ID - Group ID - Expiration time
Browser Integration¶
Direct File Access in HTML¶
Public File:
Protected File (with JavaScript):
async function downloadFile(chatId, filePath) {
const token = localStorage.getItem('auth_token');
const response = await fetch(
`https://api.example.com/api/v1/live_apps/${chatId}/${filePath}`,
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
if (response.ok) {
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filePath.split('/').pop();
document.body.appendChild(a);
a.click();
a.remove();
}
}
Display PDF in iframe:
<iframe
src="https://api.example.com/api/v1/live_apps/{chat_id}/@public/document.pdf"
width="100%"
height="600px">
</iframe>
MIME Type Support¶
The endpoint automatically detects and sets the correct MIME type:
| File Extension | MIME Type | Browser Behavior |
|---|---|---|
| application/pdf | Display inline | |
| .png, .jpg | image/png, image/jpeg | Display inline |
| .json | application/json | Display inline |
| .txt | text/plain | Display inline |
| .csv | text/csv | Download |
| .xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | Download |
| .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document | Download |
| .zip | application/zip | Download |
Performance Considerations¶
Streaming¶
- Files are streamed (not loaded entirely into memory)
- Supports large files efficiently
- Progressive download for browsers
Caching¶
- Responses include appropriate cache headers
- Browser can cache public files
- Protected files have short cache lifetime
CDN Integration¶
- Public files can be served via CDN
- Protected files served directly from API
Security Features¶
Automatic Access Control¶
- @public files: No checks (public access)
- @liveapp files: Verifies authentication token
- Chat files: Verifies authentication + chat membership
Rate Limiting¶
- Applied per user/token
- Prevents abuse
- Configurable limits
Token Validation¶
- JWT tokens verified on each request
- Expired tokens rejected
- Invalid tokens return 401
Common Use Cases¶
1. Public Marketing Materials¶
Store: @public/brochure.pdf
Access: https://api.example.com/api/v1/live_apps/{chat_id}/@public/brochure.pdf
Auth: None required
2. Group Templates¶
Store: @liveapp/email-template.html
Access: https://api.example.com/api/v1/live_apps/{chat_id}/@liveapp/email-template.html
Auth: Bearer token required
3. Chat Attachments¶
Store: attachments/2024/invoice.pdf
Access: https://api.example.com/api/v1/live_apps/{chat_id}/attachments/2024/invoice.pdf
Auth: Bearer token + chat membership required
4. Live App Assets¶
Store: @liveapp/config.json
Access from live app JavaScript:
const response = await fetch(
`/api/v1/live_apps/${chatId}/@liveapp/config.json`,
{ headers: { 'Authorization': `Bearer ${token}` }}
);
Auth: Bearer token required
Error Handling¶
Best Practices for Clients:¶
async function downloadFile(chatId, filePath, authToken) {
try {
const response = await fetch(
`https://api.example.com/api/v1/live_apps/${chatId}/${filePath}`,
{
headers: authToken ? { 'Authorization': `Bearer ${authToken}` } : {}
}
);
if (response.status === 401) {
// Redirect to login
window.location.href = '/login';
return;
}
if (response.status === 403) {
// Show error: user not in chat
alert('You do not have access to this file');
return;
}
if (response.status === 404) {
// File not found
alert('File not found');
return;
}
if (response.ok) {
// Success - process file
const blob = await response.blob();
return blob;
}
} catch (error) {
console.error('Download failed:', error);
alert('Download failed. Please try again.');
}
}
Summary¶
The file download endpoint provides: - ✅ Direct file access via simple URLs - ✅ Automatic access control based on storage location - ✅ Browser-compatible streaming with proper MIME types - ✅ Flexible authentication (public, group, chat-specific) - ✅ Smart file lookup (searches @public → @liveapps → chat root) - ✅ Secure by default with automatic permission enforcement
Perfect for building file sharing features, live apps, and document management systems.