Skip to main content

File Extraction

Extract text from documents for processing:
POST /extract-pdf-text

Basic File Upload

curl -X POST https://api.trainlyai.com/extract-pdf-text \
  -F "file=@research_paper.pdf"
Response:
{
  "text": "Extracted content from the PDF...",
  "file_hash": "a1b2c3d4e5f6...",
  "size_bytes": 524288,
  "filename": "research_paper.pdf",
  "uploaded_at": 1609459200000
}

V1 File Upload

Upload files to user’s private subchat with OAuth:
POST /v1/me/chats/files/upload

Single File Upload

curl -X POST https://api.trainlyai.com/v1/me/chats/files/upload \
  -H "Authorization: Bearer <USER_OAUTH_ID_TOKEN>" \
  -H "X-App-ID: app_your_app_id" \
  -F "file=@document.pdf"

Text Content Upload

curl -X POST https://api.trainlyai.com/v1/me/chats/files/upload \
  -H "Authorization: Bearer <USER_OAUTH_ID_TOKEN>" \
  -H "X-App-ID: app_your_app_id" \
  -F "text_content=This is my document content..." \
  -F "content_name=My Notes.txt"

Upload with Scopes

curl -X POST https://api.trainlyai.com/v1/me/chats/files/upload \
  -H "Authorization: Bearer <USER_OAUTH_ID_TOKEN>" \
  -H "X-App-ID: app_your_app_id" \
  -F "file=@song.pdf" \
  -F 'scope_values={"playlist_id":"playlist_123","genre":"rock"}'

Bulk Upload

Upload multiple files at once:
POST /v1/me/chats/files/upload-bulk

Bulk File Example

curl -X POST https://api.trainlyai.com/v1/me/chats/files/upload-bulk \
  -H "Authorization: Bearer <USER_OAUTH_ID_TOKEN>" \
  -H "X-App-ID: app_your_app_id" \
  -F "files=@doc1.pdf" \
  -F "files=@doc2.pdf" \
  -F "files=@doc3.txt" \
  -F 'scope_values={"project_id":"proj_123"}'
Response:
{
  "success": true,
  "total_files": 3,
  "successful_uploads": 3,
  "failed_uploads": 0,
  "total_size_bytes": 1572864,
  "results": [
    {
      "filename": "doc1.pdf",
      "success": true,
      "file_id": "v1_user_abc_doc1.pdf_1609459200",
      "size_bytes": 524288,
      "processing_status": "completed"
    },
    {
      "filename": "doc2.pdf",
      "success": true,
      "file_id": "v1_user_abc_doc2.pdf_1609459201",
      "size_bytes": 524288,
      "processing_status": "completed"
    },
    {
      "filename": "doc3.txt",
      "success": true,
      "file_id": "v1_user_abc_doc3.txt_1609459202",
      "size_bytes": 524288,
      "processing_status": "completed"
    }
  ]
}

List Files

Get all files in user’s chat:
GET /v1/me/chats/files

List Example

curl -X GET https://api.trainlyai.com/v1/me/chats/files \
  -H "Authorization: Bearer <USER_OAUTH_ID_TOKEN>" \
  -H "X-App-ID: app_your_app_id"
Response:
{
  "success": true,
  "files": [
    {
      "file_id": "v1_user_xyz_document.pdf_1609459200",
      "filename": "document.pdf",
      "upload_date": "2024-01-01T12:00:00Z",
      "size_bytes": 524288,
      "chunk_count": 42
    },
    {
      "file_id": "v1_user_xyz_notes.txt_1609459300",
      "filename": "notes.txt",
      "upload_date": "2024-01-01T12:05:00Z",
      "size_bytes": 102400,
      "chunk_count": 8
    }
  ],
  "total_files": 2,
  "total_size_bytes": 626688
}

Upload with Scopes (Advanced)

Upload to specific chat with custom metadata:
POST /v1/{chat_id}/upload_with_scopes

Scoped Upload Example

curl -X POST https://api.trainlyai.com/v1/chat_abc123/upload_with_scopes \
  -H "Authorization: Bearer tk_your_api_key" \
  -F "file=@product_specs.pdf" \
  -F 'scope_values={"product_id":"prod_xyz","version":"2.0","category":"specs"}'

JavaScript Upload Examples

Single File with Progress

async function uploadFile(file, onProgress) {
  const formData = new FormData();
  formData.append("file", file);

  const xhr = new XMLHttpRequest();

  // Track upload progress
  xhr.upload.addEventListener("progress", (e) => {
    if (e.lengthComputable) {
      const percentComplete = (e.loaded / e.total) * 100;
      onProgress(percentComplete);
    }
  });

  return new Promise((resolve, reject) => {
    xhr.addEventListener("load", () => {
      if (xhr.status === 200) {
        resolve(JSON.parse(xhr.responseText));
      } else {
        reject(new Error(`Upload failed: ${xhr.status}`));
      }
    });

    xhr.addEventListener("error", () => reject(new Error("Upload error")));

    xhr.open("POST", "https://api.trainlyai.com/extract-pdf-text");
    xhr.send(formData);
  });
}

// Usage
uploadFile(myFile, (progress) => {
  console.log(`Upload ${progress.toFixed(2)}% complete`);
});

Bulk Upload with Retry

async function bulkUploadWithRetry(files, maxRetries = 3) {
  const results = [];

  for (const file of files) {
    let attempt = 0;
    let success = false;

    while (attempt < maxRetries && !success) {
      try {
        const formData = new FormData();
        formData.append("file", file);

        const response = await fetch(
          "https://api.trainlyai.com/v1/me/chats/files/upload",
          {
            method: "POST",
            headers: {
              Authorization: `Bearer ${userToken}`,
              "X-App-ID": appId,
            },
            body: formData,
          },
        );

        if (response.ok) {
          const result = await response.json();
          results.push({ file: file.name, success: true, data: result });
          success = true;
        } else {
          throw new Error(`HTTP ${response.status}`);
        }
      } catch (error) {
        attempt++;
        if (attempt === maxRetries) {
          results.push({
            file: file.name,
            success: false,
            error: error.message,
          });
        } else {
          // Exponential backoff
          await new Promise((resolve) =>
            setTimeout(resolve, Math.pow(2, attempt) * 1000),
          );
        }
      }
    }
  }

  return results;
}

Supported Formats

Documents

PDF, DOCX, TXT, MD, HTML

Data Files

CSV, JSON, YAML, XML

Code Files

JS, TS, PY, JAVA, C, C++, etc.

Error Handling

Common Upload Errors

try {
  const result = await uploadFile(file);
  console.log("Upload successful:", result);
} catch (error) {
  if (error.status === 413) {
    console.error("File too large (max 5MB)");
  } else if (error.status === 415) {
    console.error("Unsupported file type");
  } else if (error.status === 400) {
    console.error("Invalid file or malicious content detected");
  } else {
    console.error("Upload failed:", error.message);
  }
}

Best Practices

1

Validate Client-Side

Check file size and type before uploading to save bandwidth
2

Show Progress

Implement upload progress indicators for better UX
3

Handle Errors

Provide clear error messages and retry options
4

Batch When Possible

Use bulk upload endpoints for multiple files
5

Add Metadata

Use scopes to organize and filter documents