Skip to main content
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

TypeContent TypeMax Size
PDFapplication/pdf10 MB
JPEGimage/jpeg10 MB
PNGimage/png10 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.