File Upload API¶
Upload PDF files to envelopes using the Upload API.
When to Use¶
Use the upload API when:
- File size is larger than 1MB
- You want to reduce API request time
- You want to avoid base64 encoding overhead
Use standard envelope creation (base64) when:
- File size is less than 1MB
- You want simplicity (single API call)
How It Works¶
- Create envelope (without documents)
- Request upload URL for each document
- Upload PDF to the upload URL
- Wait for processing (poll status endpoint OR use webhook)
- Verify envelope has documents attached
- Send envelope
Upload States¶
| State | Description |
|---|---|
PENDING |
URL generated, waiting for upload |
UPLOADED |
File received, processing |
PROCESSING |
Validating PDF |
COMPLETED |
File ready, can send envelope |
FAILED |
Upload or validation error |
EXPIRED |
URL expired (1 hour) |
API Endpoints¶
Create Upload¶
Generate an upload URL for a document.
Endpoint: POST /api/v1/envelopes/:envelope_id/uploads
Request:
curl -X POST https://api.lexgo.cl/api/v1/envelopes/abc-123/uploads \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_name": "contract.pdf",
"order": 0,
"custom_key": "doc1"
}'
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
file_name |
string | Yes | Filename (max 100 chars) |
order |
integer | Yes | Position in envelope (0, 1, 2...) |
custom_key |
string | No | Your tracking reference |
content_type |
string | No | application/pdf (only PDF supported) |
Response:
{
"success": true,
"upload": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"upload_url": "https://api.lexgo.cl/v1/uploads/550e8400.../stream",
"file_name": "contract.pdf",
"order": 0,
"custom_key": "doc1",
"expires_at": "2025-11-20T17:05:15Z",
"max_file_size": 52428800,
"envelope_id": "abc-123",
"status": "PENDING",
"instructions": {
"method": "PUT",
"headers": { "Content-Type": "application/pdf" },
"note": "Upload file to upload_url using PUT method. Request body should contain the binary file content."
}
},
"request_id": "req_xyz"
}
Note: max_file_size is 52428800 bytes (50 MB).
Error Responses:
404- Envelope not found405- Envelope not in CREATED status (already sent)422- Validation error (duplicate order, missing fields)
Upload File¶
Upload PDF to the upload URL.
Request:
curl -X PUT "{upload_url}" \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/pdf" \
--data-binary @contract.pdf
Important:
- Use HTTP PUT method
- Include
Authorizationheader with your API key - Set
Content-Type: application/pdfheader - Send raw binary file (not base64)
- URL expires in 1 hour
- Max file size: 50MB
Response:
{
"success": true,
"upload_id": "550e8400-e29b-41d4-a716-446655440001",
"status": "UPLOADED",
"message": "File uploaded successfully"
}
Check Upload Status¶
Check processing status of an upload.
Endpoint: GET /api/v1/envelopes/:envelope_id/uploads/:id
Request:
curl https://api.lexgo.cl/api/v1/envelopes/abc-123/uploads/upload_abc123 \
-H "Authorization: YOUR_API_KEY"
Response (Completed):
{
"upload": {
"id": "upload_abc123",
"envelope_id": "abc-123",
"status": "COMPLETED",
"file_id": "file_xyz789",
"order": 0,
"file_name": "contract.pdf",
"custom_key": "doc1",
"uploaded_at": "2025-11-20T19:20:15Z",
"processed_at": "2025-11-20T19:20:18Z"
},
"request_id": "req_def"
}
List All Uploads¶
Get all uploads for an envelope.
Endpoint: GET /api/v1/envelopes/:envelope_id/uploads
Request:
# Get all uploads
curl https://api.lexgo.cl/api/v1/envelopes/abc-123/uploads \
-H "Authorization: YOUR_API_KEY"
# Filter by status
curl "https://api.lexgo.cl/api/v1/envelopes/abc-123/uploads?status=completed" \
-H "Authorization: YOUR_API_KEY"
Response:
{
"uploads": [
{
"id": "upload_abc123",
"envelope_id": "abc-123",
"status": "COMPLETED",
"file_id": "file_xyz789",
"order": 0,
"file_name": "contract.pdf"
}
],
"total": 1,
"request_id": "req_ghi"
}
Webhook Alternative to Polling¶
Subscribe to envelope.file_uploaded for real-time notifications instead of polling:
curl -X POST https://api.lexgo.cl/api/v1/webhooks \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/lexgo",
"subscriptions": "envelope.file_uploaded"
}'
Your webhook will receive notification when file is ready (no polling needed).
See Webhooks API for complete documentation.
Complete Workflow Example¶
# Step 1: Create envelope
ENVELOPE_JSON=$(curl -s -X POST https://api.lexgo.cl/api/v1/envelopes \
-H "Authorization: YOUR_API_KEY" \
-F "name=Contract - John Doe" \
-F "recipients[0][name]=John Doe" \
-F "recipients[0][email]=john@example.com" \
-F "recipients[0][order]=1")
ENVELOPE_ID=$(echo "$ENVELOPE_JSON" | jq -r '.envelope.id')
# Step 2: Request upload URL
UPLOAD_JSON=$(curl -s -X POST \
"https://api.lexgo.cl/api/v1/envelopes/${ENVELOPE_ID}/uploads" \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"file_name":"contract.pdf","order":0}')
UPLOAD_URL=$(echo "$UPLOAD_JSON" | jq -r '.upload.upload_url')
UPLOAD_ID=$(echo "$UPLOAD_JSON" | jq -r '.upload.id')
# Step 3: Upload file
curl -X PUT "$UPLOAD_URL" \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/pdf" \
--data-binary @contract.pdf
# Step 4: Wait for processing
for i in {1..30}; do
STATUS_JSON=$(curl -s \
"https://api.lexgo.cl/api/v1/envelopes/${ENVELOPE_ID}/uploads/${UPLOAD_ID}" \
-H "Authorization: YOUR_API_KEY")
STATUS=$(echo "$STATUS_JSON" | jq -r '.upload.status')
echo "Status: $STATUS"
[ "$STATUS" = "COMPLETED" ] && break
[ "$STATUS" = "FAILED" ] && exit 1
sleep 2
done
# Step 5: Verify envelope has documents
curl "https://api.lexgo.cl/api/v1/envelopes/${ENVELOPE_ID}" \
-H "Authorization: YOUR_API_KEY" | jq '.envelope.documents'
# Step 6: Send envelope
curl -X POST \
"https://api.lexgo.cl/api/v1/envelopes/${ENVELOPE_ID}/send_invitation" \
-H "Authorization: YOUR_API_KEY"
Error Handling¶
Upload Failed (403)¶
Cause: URL expired or wrong Content-Type
Solution: Request new upload URL (they expire after 1 hour).
Status FAILED¶
Cause: Invalid PDF, corrupted file, encrypted PDF
Solution: Check error_message in upload status response:
curl https://api.lexgo.cl/api/v1/envelopes/$ENVELOPE_ID/uploads/$UPLOAD_ID \
-H "Authorization: YOUR_API_KEY" | jq '.upload.error_message'
Cannot Create Upload (422)¶
Cause: Another upload for this order already exists
Solution: Wait for completion or use different order number.
Constraints¶
- File type: PDF only (
application/pdf) - Max file size: 50 MB
- Max filename: 100 characters
- URL expiration: 1 hour
- Single use: Each upload URL can only be used once
- One active per order: Only one pending/uploaded/processing upload per order position
Related Documentation¶
- Uploads Guide - Complete implementations in Python, Ruby, Bash
- Envelopes API - Standard base64 upload method
- Webhooks API - Real-time event notifications