Files
In shortUpload, retrieve, and manage multimodal files with the 10xGraph TypeScript client.
- 5 min read
- 11 sections
- Updated
- v0.10.0
- Markdown
The file methods on TenxGraphClient upload binary files to the server, then fetch the file, its metadata or a usable access URL. An upload returns a file_id and a url that you place in a MediaRef inside an ImageBlock, AudioBlock or DocumentBlock. For the task-oriented walkthrough, see Files and multimodal.
Package: 10xgraph-client
Import: import { TenxGraphClient } from '10xgraph-client';
Upload flow
- Call
uploadFile(file)with aFile,Blob, or{ data: Blob; filename: string }object. - Receive a
file_idand aurlin the response. - Embed the access URL (or
file_id) inside aMediaRefin the appropriate content block. - Send the message containing the block via
invoke()orstream().
uploadFile(file)
Upload a file to the server.
Endpoint: POST /v1/files/upload
// From a browser file input
const input = document.querySelector<HTMLInputElement>('input[type=file]')!;
const file = input.files![0];
const response = await client.uploadFile(file);
// From a Blob with a custom filename
const blob = new Blob([imageBytes], { type: 'image/png' });
const response = await client.uploadFile({ data: blob, filename: 'screenshot.png' });Accepted input types
| Type | How file is named |
|---|---|
File |
Uses file.name automatically. |
Blob |
Fallback filename 'upload' is used. Specify { data: blob, filename: '...' } if the name matters. |
{ data: Blob; filename: string } |
Uses the filename field. |
FileUploadResponse
interface FileUploadResponse {
data: {
file_id: string; // Unique identifier for the uploaded file
mime_type: string; // Detected MIME type (e.g. 'image/jpeg')
size_bytes: number; // File size in bytes
filename: string; // Name as stored on the server
extracted_text: string | null; // Text extracted from documents, or null
url: string; // Access URL, use this in MediaRef
direct_url?: string | null; // Direct URL (e.g. S3 presigned URL) if cloud-backed
direct_url_expires_at?: number | null; // Unix timestamp (seconds) when direct_url expires
};
metadata?: {
request_id: string;
timestamp: string;
message: string;
};
}Use the response in a message:
const upload = await client.uploadFile(imageFile);
// Reference by URL (simplest)
const imageBlock = new ImageBlock(
new MediaRef('url', upload.data.url),
'Uploaded image'
);
// Reference by file_id (more portable; the server resolves the URL)
const mediaRef = new MediaRef('file_id');
mediaRef.file_id = upload.data.file_id;
mediaRef.mime_type = upload.data.mime_type;
const imageMsg = new Message('user', [
new TextBlock('What is in this image?'),
new ImageBlock(mediaRef),
]);
const result = await client.invoke([imageMsg]);getFile(fileId)
Download a file by its file_id. Returns a raw Blob.
Endpoint: GET /v1/files/{fileId}
const blob = await client.getFile('file-abc123');
const url = URL.createObjectURL(blob);
// Render in an <img> tag or downloadParameters
| Parameter | Type | Description |
|---|---|---|
fileId |
string |
The file ID returned by uploadFile(). |
getFileInfo(fileId)
Fetch metadata about a stored file without downloading its contents.
Endpoint: GET /v1/files/{fileId}/info
const info = await client.getFileInfo('file-abc123');
console.log(info.data.mime_type); // 'application/pdf'
console.log(info.data.size_bytes); // 204800
console.log(info.data.extracted_text); // Extracted text, or nullFileInfoResponse
interface FileInfoResponse {
data: {
file_id: string;
mime_type: string;
size_bytes: number;
filename?: string | null;
extracted_text: string | null;
direct_url?: string | null;
direct_url_expires_at?: number | null;
};
metadata?: ResponseMetadata;
}getFileAccessUrl(fileId)
Get the best access URL for a file. For cloud-backed storage (S3, GCS, Azure) this returns a time-limited signed URL. For local or memory-backed storage it returns the normal API file route.
Endpoint: GET /v1/files/{fileId}/url
const result = await client.getFileAccessUrl('file-abc123');
console.log(result.data.url); // The best URL to use right now
console.log(result.data.expires_at); // Unix timestamp (seconds), or null if permanent
console.log(result.data.mime_type);FileAccessUrlResponse
interface FileAccessUrlResponse {
data: {
file_id: string;
url: string;
expires_at?: number | null; // Unix timestamp in seconds; null = no expiry
mime_type: string;
};
metadata?: ResponseMetadata;
}getMultimodalConfig()
Fetch the server’s multimodal configuration: which storage backend is active, the max upload size, and how documents are handled.
Endpoint: GET /v1/config/multimodal
const config = await client.getMultimodalConfig();
console.log(config.data.media_storage_type); // 'memory' | 'local' | 'cloud'
console.log(config.data.media_max_size_mb); // 25 by default (MEDIA_MAX_SIZE_MB)
console.log(config.data.document_handling); // 'extract_text' | 'pass_raw' | 'skip'MultimodalConfigResponse
interface MultimodalConfigResponse {
data: {
media_storage_type: string; // Storage backend identifier
media_max_size_mb: number; // Maximum file size in megabytes
document_handling: string; // 'extract_text' | 'pass_raw' | 'skip'
};
metadata?: ResponseMetadata;
}Supported MIME types
By default the server accepts any content type. An operator can restrict uploads with the MEDIA_ALLOWED_CONTENT_TYPES setting (comma-separated entries such as image/*,application/pdf); a rejected type returns status 415. Separately, the graph can only use types that the underlying LLM supports. Typical choices:
| Category | MIME types |
|---|---|
| Images | image/jpeg, image/png, image/gif, image/webp |
| Audio | audio/mpeg, audio/wav, audio/ogg, audio/webm |
| Video | video/mp4, video/webm |
| Documents | application/pdf, text/plain, text/markdown |
Call getMultimodalConfig() to confirm the active storage settings and size limit before uploading.
Complete example: image Q&A
import {
TenxGraphClient,
Message,
ImageBlock,
TextBlock,
MediaRef,
} from '10xgraph-client';
const client = new TenxGraphClient({ baseUrl: 'http://localhost:8000' });
async function askAboutImage(imageFile: File, question: string) {
// 1. Upload the image
const upload = await client.uploadFile(imageFile);
// 2. Build a multimodal message
const userMsg = new Message('user', [
new TextBlock(question),
new ImageBlock(
new MediaRef('url', upload.data.url),
imageFile.name
),
]);
// 3. Invoke and return the answer
const result = await client.invoke([userMsg]);
const answer = result.messages
.filter(m => m.role === 'assistant')
.flatMap(m => m.content)
.filter(b => b.type === 'text')
.map(b => (b as any).text)
.join('');
return answer;
}Common errors
| Error | Cause | Fix |
|---|---|---|
TenxGraphError with statusCode 413 |
File exceeds media_max_size_mb. |
Check getMultimodalConfig() and reduce file size. |
TenxGraphError with statusCode 415 |
The server restricts content types and yours is not allowed. | Upload an allowed type, or ask the operator to adjust MEDIA_ALLOWED_CONTENT_TYPES. |
NotFoundError (statusCode 404) |
file_id not found, or not visible to the current user. |
Re-upload the file or check the ID. |
| Signed URL expired | expires_at is in the past. |
Call getFileAccessUrl() to refresh the URL. |
What you learned
uploadFile()acceptsFile,Blob, or{ data, filename }. It returns afile_idandurl.- Reference uploaded files in messages via
MediaRef('url', url)orMediaRef('file_id')withfile_idset. getFileAccessUrl()refreshes cloud-backed signed URLs; the expiry is a Unix timestamp in seconds.getMultimodalConfig()tells you the storage backend and max file size.
Next step
See reference/client/auth to learn how to configure authentication for the client.