Floreal Logo
DocumentsUpload CVsDirect upload

Upload CV File Directly

Upload a CV file directly in a single request

This is the simplest upload method - send your CV file and metadata in one request, and get a fully processed document back.


How It Works

Single Request Upload:

  1. Send file as binary body + metadata in query parameters
  2. Document record created automatically
  3. CV analysis starts immediately
  4. Poll status endpoint for results

No presigned URLs needed - everything happens server-side.


Request Format

Query Parameters (Required)

ParameterTypeRequiredDescriptionExample
documentNamestringYesDisplay name for CVJohn Doe - Software Engineer
documentTypestringNoDocument category (default: cv)cv
documentDatestringYesCV date in MM-YYYY format11-2025

Headers (Required)

HeaderTypeRequiredDescriptionExample
X-API-KeystringYesYour API keyYOUR_API_KEY
Content-TypestringYesFile MIME typeapplication/pdf

Body

Send the raw file bytes as the request body (not form-data, not JSON).


Supported File Types

PDF - application/pdf (recommended) ✅ DOCX - application/vnd.openxmlformats-officedocument.wordprocessingml.documentDOC - application/mswordTXT - text/plain

Maximum file size: 10 MB

Note: DOC and DOCX files are automatically converted to PDF during processing.


Response

Success (201 Created)

{
  "documentId": "789e4567-e89b-12d3-a456-426614174000",
  "status": "uploading",
  "message": "Document uploaded and processing started",
  "documentUrl": "s3://bucket/companies/.../documents/.../resume.pdf",
  "file": {
    "name": "john_doe_resume.pdf",
    "size": 245760,
    "sizeFormatted": "240 KB",
    "contentType": "application/pdf"
  },
  "estimatedProcessingTime": "30 to 60 seconds",
  "statusEndpoint": "/v1/public/documents/789e4567-e89b-12d3-a456-426614174000",
  "nextSteps": [
    "Poll GET /v1/public/documents/789e4567-... to check processing status",
    "Document will be in 'completed' state when analysis is done"
  ]
}

Processing Pipeline

After upload, your CV goes through this automated workflow:

  1. Upload (0 to 5s) - File uploaded
  2. Extract (4 to 30s) - Text extraction from PDF
  3. Analyze (30 to 90s) - AI analysis (contact, skills, experience)
  4. Chunk and Embed (90 to 120) - Chunk, Store and Embed document

Total time: 30 to 90 seconds for most CVs (up to 120s for complex documents)


Complete Example

cURL

curl -X POST "https://api.floreal.ai/v1/public/documents/upload-direct?documentName=John%20Doe%20-%20Software%20Engineer&documentType=cv&documentDate=11-2025" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/pdf" \
  --data-binary @resume.pdf

JavaScript (Node.js)

const fs = require('fs');

// Read file
const fileBuffer = fs.readFileSync('./resume.pdf');

// Upload
const params = new URLSearchParams({
  documentName: 'John Doe - Software Engineer',
  documentType: 'cv',
  documentDate: '11-2025'
});

const response = await fetch(
  'https://api.floreal.ai/v1/public/documents/upload-direct?' + params,
  {
    method: 'POST',
    headers: {
      'X-API-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/pdf'
    },
    body: fileBuffer
  }
);

const result = await response.json();
console.log('✅ Uploaded! Document ID:', result.documentId);

// Poll for completion
const pollStatus = async (documentId) => {
  const status = await fetch(
    'https://api.floreal.ai/v1/public/documents/' + documentId,
    { headers: { 'Authorization': 'X-API-Key YOUR_API_KEY' } }
  ).then(r => r.json());

  console.log('Status:', status.status);

  if (status.status === 'completed') {
    console.log('✅ Processing complete!');
    console.log('Candidate:', status.contact);
    return status;
  }

  if (status.status === 'failed' || status.status === 'invalid') {
    console.error('❌ Processing failed:', status.error);
    return status;
  }

  // Still processing
  await new Promise(resolve => setTimeout(resolve, 5000));
  return pollStatus(documentId);
};

await pollStatus(result.documentId);

Python

import requests
import time

# Upload file
with open('resume.pdf', 'rb') as f:
    response = requests.post(
        'https://api.floreal.ai/v1/public/documents/upload-direct',
        params={
            'documentName': 'John Doe - Software Engineer',
            'documentType': 'cv',
            'documentDate': '11-2025'
        },
        headers={
            'X-API-Key': 'YOUR_API_KEY',
            'Content-Type': 'application/pdf'
        },
        data=f
    )

data = response.json()
document_id = data['documentId']
print(f"✅ Uploaded! Document ID: {document_id}")

# Poll for completion
def poll_status(document_id):
    while True:
        status_response = requests.get(
            f'https://api.floreal.ai/v1/public/documents/{document_id}',
            headers={'Authorization': 'X-API-Key YOUR_API_KEY'}
        )
        status = status_response.json()

        print(f"Status: {status['status']}")

        if status['status'] == 'completed':
            print("✅ Processing complete!")
            print(f"Candidate: {status.get('contact', {})}")
            return status

        if status['status'] in ['failed', 'invalid']:
            print(f"❌ Processing failed: {status.get('error', {})}")
            return status

        time.sleep(5)

poll_status(document_id)

Error Responses

StatusErrorCauseSolution
400Missing document nameNo documentName query paramAdd documentName query parameter
400Missing content typeNo Content-Type headerAdd Content-Type header
400Missing document dateNo documentDate query paramAdd documentDate query parameter
400Invalid file typeUnsupported content typeUse PDF, DOC, DOCX, or TXT
400File too largeFile exceeds 10MBCompress or split document
400Invalid date formatWrong date formatUse MM-YYYY (e.g., "11-2025")
401UnauthorizedInvalid API keyCheck Authorization header
500Upload failedServer errorRetry or contact support

Validation & Limits

File Requirements

Size: Maximum 10 MB ✅ Types: PDF, DOC, DOCX, TXT only ✅ Content: Must be a valid CV/resume ✅ Auto-conversion: DOC/DOCX files converted to PDF automatically

Metadata Requirements

Document Name: 1 to 255 characters ✅ Document Date: MM-YYYY format (e.g., "03-2024") ✅ Document Type: "cv" or "other" (default: "cv")


Comparison: Upload Methods

FeatureDirect UploadPresigned URLURL Fetch
Requests1 request3 requests1 request
Complexity⭐ Simple⭐⭐⭐ Complex⭐ Simple
File SourceLocal fileLocal fileRemote URL
BandwidthUses APIDirect to S3Server fetches
Best ForQuick integrationLarge filesAutomation

Recommendation: Use Direct Upload for most cases - it's the simplest and fastest method.


Security

API Key Required - All requests authenticated ✅ Organization Scoped - Files isolated per company ✅ Temporary Storage - Files in temp folder until validated ✅ Automatic Cleanup - Temp files deleted after processing ✅ Automatic Sanitization - Filenames cleaned ✅ No Public Access - Files not publicly accessible ✅ HTTPS Only - Encrypted in transit ✅ Audit Trail - All uploads tracked in timeline


Monitoring & Debugging

Check Upload Status

curl -X GET https://api.floreal.ai/v1/public/documents/DOCUMENT_ID \
  -H "X-API-Key: YOUR_API_KEY"

List Recent Uploads

curl -X GET "https://api.floreal.ai/v1/public/documents?limit=10&sortOrder=desc" \
  -H "X-API-Key: YOUR_API_KEY"

Common Issues

Issue: "File uploaded but processing stuck in 'uploading'" Solution: Step Functions workflow may be delayed - wait up to 2 minutes

Issue: "Processing stuck in 'pending' for greater than 90 seconds" Solution: Check Step Functions logs or contact support

Issue: "Document marked as 'invalid' but is a CV" Solution: AI didn't recognize it as CV - check format/content quality

Issue: "DOCX upload works but DOC fails" Solution: DOC conversion may have issues - convert to PDF first


Next Steps

  1. Upload file using this endpoint
  2. Save documentId from response
  3. Poll status every 5 to 10 seconds
  4. Wait for completion (30 to 60 seconds typical)
  5. Retrieve data once status is completed
  6. Start searching using Search API

  • Get Document - GET /v1/public/documents/\{documentId\} - Check status and retrieve data
  • List Documents - GET /v1/public/documents - Browse all uploads
  • Delete Document - DELETE /v1/public/documents/\{documentId\} - Remove CV
  • Search CVs - POST /v1/public/search - Find candidates
POST
/v1/public/documents/upload-direct
X-API-Key<token>

API key for public API access. Get yours at https://app.floreal.ai?tab=api

In: header

Query Parameters

documentNamestring
Length1 <= length <= 255
documentType?string
Default"cv"
Value in"cv" | "other"
documentDatestring
Match^\d{2}-\d{4}$

Response Body

curl -X POST "https://api.floreal.ai/v1/public/documents/upload-direct?documentName=string&documentType=cv&documentDate=string"
{
  "documentId": "789e4567-e89b-12d3-a456-426614174000",
  "status": "uploading",
  "message": "Document uploaded and processing started",
  "documentUrl": "string",
  "file": {
    "name": "string",
    "size": 0,
    "sizeFormatted": "240 KB",
    "contentType": "string"
  },
  "estimatedProcessingTime": "30 to 60 seconds",
  "statusEndpoint": "/v1/public/documents/789e4567-e89b-12d3-a456-426614174000",
  "nextSteps": [
    "string"
  ]
}
{
  "error": "string",
  "message": "string"
}
{
  "error": "string"
}
{
  "error": "string",
  "message": "string"
}