Skip to main content

Generate Pre-Signed URL for File Upload API

Overview

Generate AWS S3 pre-signed URLs for secure file upload and download. This API creates temporary signed URLs that allow clients to upload files directly to S3 without exposing AWS credentials. The API generates both a PUT URL for uploading and a GET URL for accessing the uploaded file.

API Details

Endpoint

POST https://api.gafapay.com/gafapay/v3/base/file/upload/presigned_url

Headers

CompanyID: b760d21412dd473999e374053fb95031
RequestID: 1764692817
Content-Type: application/json
Authorization: Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI2OTE0MTY3MmI1YzRlZTBiY2EyMDlmYjIiLCJyb2xlcyI6WyJST0xFX0FETUlOIl0sImV4cCI6MTc2NTIxNTI2OH0.NYL_42v1y0YOJyq8-5B5-slGZBWfHiufoLMQdhq6bnI

Request Body

Required Fields

  • fileName (String): The name of the file to be uploaded
    • Example: example.pdf, profile-photo.jpg, document.docx
    • Special characters will be sanitized automatically
  • contentType (String): MIME type of the file
    • Must match the actual file type being uploaded
    • See supported content types below

Supported Content Types

  • PDF: application/pdf
  • Images:
    • image/jpeg - JPEG/JPG images
    • image/png - PNG images
    • image/gif - GIF images
  • Documents:
    • application/msword - Word Document (.doc)
    • application/vnd.openxmlformats-officedocument.wordprocessingml.document - Word Document (.docx)
    • application/vnd.ms-excel - Excel (.xls)
    • application/vnd.openxmlformats-officedocument.spreadsheetml.sheet - Excel (.xlsx)
  • Other:
    • text/plain - Text files
    • application/zip - ZIP archives
    • video/mp4 - MP4 videos
    • audio/mpeg - MP3 audio

Request Example

Upload PDF Document

{
"fileName": "example.pdf",
"contentType": "application/pdf"
}

Upload Image

{
"fileName": "profile-photo.jpg",
"contentType": "image/jpeg"
}

Upload Word Document

{
"fileName": "report.docx",
"contentType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}

Response

{
"success": 1,
"error": [],
"data": {
"fileName": "1733235678901_a1b2c3d4e5f6g7h8_example.pdf",
"uploadUrl": "https://gafa-user-uploads.s3.ap-south-1.amazonaws.com/1733235678901_a1b2c3d4e5f6g7h8_example.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=...",
"fileUrl": "https://gafa-user-uploads.s3.ap-south-1.amazonaws.com/1733235678901_a1b2c3d4e5f6g7h8_example.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=..."
}
}

Response Fields

  • success (integer): Response status indicator
    • 1 = Success
    • 0 = Failure
  • error (array): Array of error messages (empty on success)
  • data (object): Response data object
    • fileName (string): Generated unique file name (format: timestamp_uuid_originalFileName)
    • uploadUrl (string): Pre-signed PUT URL for uploading the file (valid for 5 minutes)
    • fileUrl (string): Pre-signed GET URL for downloading/viewing the file (valid for 5 minutes)

Example Usage

Step 1: Generate Pre-Signed URL

curl --location 'https://api.gafapay.com/gafapay/v3/base/file/upload/presigned_url' \
--header 'CompanyID: b760d21412dd473999e374053fb95031' \
--header 'RequestID: 1764692817' \
--header 'Content-Type: application/json' \
--header 'Authorization: Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...' \
--data '{
"fileName": "example.pdf",
"contentType": "application/pdf"
}'

Step 2: Upload File to S3 (Using Upload URL)

curl --location --request PUT 'UPLOAD_URL_FROM_STEP_1' \
--header 'Content-Type: application/pdf' \
--data-binary '@/path/to/your/file.pdf'

Step 3: Access Uploaded File (Using File URL)

curl --location 'FILE_URL_FROM_STEP_1' \
--output downloaded-file.pdf

JavaScript/Fetch Example

Complete Upload Flow

// Step 1: Generate pre-signed URL
async function uploadFileToS3(file) {
try {
// Generate pre-signed URL
const response = await fetch('https://api.gafapay.com/gafapay/v3/base/file/upload/presigned_url', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'CompanyID': 'b760d21412dd473999e374053fb95031',
'RequestID': '1764692817',
'Authorization': 'Token YOUR_TOKEN_HERE'
},
body: JSON.stringify({
fileName: file.name,
contentType: file.type
})
});

const data = await response.json();

if (data.success === 1) {
const { uploadUrl, fileUrl, fileName } = data.data;

// Step 2: Upload file to S3 using PUT
const uploadResponse = await fetch(uploadUrl, {
method: 'PUT',
headers: {
'Content-Type': file.type
},
body: file
});

if (uploadResponse.ok) {
console.log('File uploaded successfully!');
console.log('File URL:', fileUrl);
console.log('Generated filename:', fileName);
return { success: true, fileUrl, fileName };
} else {
console.error('Upload failed:', uploadResponse.status);
return { success: false, error: 'Upload failed' };
}
} else {
console.error('Failed to generate pre-signed URL:', data.error);
return { success: false, error: data.error };
}
} catch (error) {
console.error('Error:', error);
return { success: false, error: error.message };
}
}

// Usage example
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
if (file) {
const result = await uploadFileToS3(file);
if (result.success) {
alert('File uploaded! URL: ' + result.fileUrl);
}
}
});

Error Responses

Missing Required Fields

{
"success": 0,
"error": ["BAD_REQUEST"],
"data": null
}

Invalid Content Type

{
"success": 0,
"error": ["INVALID_CONTENT_TYPE"],
"data": null
}

Authentication Error

{
"success": 0,
"error": ["UNAUTHORIZED"],
"data": null
}

Important Notes

URL Expiration

  • Pre-signed URLs are valid for 5 minutes only
  • Upload your file immediately after generating the URL
  • If the URL expires, generate a new one

File Naming

  • 📝 Unique file names are generated automatically
  • Format: timestamp_uuid_originalFileName
  • Example: 1733235678901_a1b2c3d4e5f6g7h8_example.pdf
  • Special characters in original filename are replaced with underscores

Content Type Matching

  • Always ensure the contentType matches the actual file
  • Mismatched content types may cause upload failures
  • The same content type must be used in Step 1 (API call) and Step 2 (S3 upload)

File Size Limits

  • 📦 Maximum file size: 200 MB
  • Larger files may fail during upload
  • Consider breaking large files into smaller chunks

Direct S3 Upload

  • 🚀 Files are uploaded directly to AWS S3
  • No need to send files through your backend server
  • Reduces server load and improves upload speed
  • Requires proper CORS configuration on S3 bucket

Security

  • 🔒 AWS credentials are never exposed to clients
  • Pre-signed URLs provide temporary, secure access
  • URLs expire automatically after 5 minutes
  • Each URL is unique and single-use recommended

Upload Process Flow

  1. Client: Request pre-signed URL from API

    • Provide fileName and contentType
    • Receive uploadUrl and fileUrl
  2. Client: Upload file directly to S3

    • Use PUT request to uploadUrl
    • Set Content-Type header to match contentType
    • Send file as binary data in request body
  3. Client: Access uploaded file

    • Use fileUrl to download or display the file
    • File URL remains valid for 5 minutes
  4. Store: Save the generated fileName or fileUrl in your database

    • Link it to user documents, profiles, etc.
    • Use saved URL in subsequent API calls (like save user document)

Interactive Testing

🧪 Live API Testing Tool Available!

We've provided an interactive HTML page where you can test this API in real-time.

📍 Access the test page:

If you're running the docs locally:

  1. Make sure the dev server is running (npm start)
  2. Open this URL in your browser: http://localhost:3000/file-upload-test.html

If you're viewing on a deployed site:

  • Navigate to: https://your-domain.com/file-upload-test.html
Quick Access

Copy and paste this into your browser: http://localhost:3000/file-upload-test.html