Light uses presigned URLs for file uploads. This two-step process keeps your API key secure and supports direct uploads of any size.
How It Works
Upload a Receipt for a Card Transaction
const fs = require('fs');
async function uploadReceipt(transactionId, filePath) {
const API_KEY = process.env.LIGHT_API_KEY;
const fileName = filePath.split('/').pop();
const contentType = fileName.endsWith('.pdf')
? 'application/pdf'
: 'image/jpeg';
// Step 1: Get a presigned upload URL
const urlRes = await fetch(
`https://api.light.inc/v1/card-transactions/${transactionId}/receipt-upload-url`,
{
method: 'POST',
headers: {
'Authorization': `Basic ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ fileName, contentType }),
}
);
const { uploadUrl } = await urlRes.json();
// Step 2: Upload the file directly
const fileBuffer = fs.readFileSync(filePath);
const uploadRes = await fetch(uploadUrl, {
method: 'PUT',
headers: { 'Content-Type': contentType },
body: fileBuffer,
});
if (!uploadRes.ok) {
throw new Error(`Upload failed: ${uploadRes.status}`);
}
console.log('Receipt uploaded successfully');
}
uploadReceipt('txn_abc123', './receipts/coffee.jpg');
Supported File Types
| Type | Content Type | Max Size |
|---|
| PDF | application/pdf | 10 MB |
| JPEG | image/jpeg | 10 MB |
| PNG | image/png | 10 MB |
Presigned URLs expire after a short period. Always upload the file immediately after obtaining the URL. If the URL expires, request a new one.