Skip to main content

How to Upload a Receipt Image Using a Presigned URL

This guide explains the complete workflow for uploading receipt images using the Thanx API

Overview of the Flow

Thanx uses two separate endpoints for handling receipt uploads:
  1. Get Upload URL — to obtain a presigned aws s3 url.
  2. Create Receipt — to create a receipt referencing the uploaded image via image_path.

Step 1 — Request a Presigned Upload URL

Example Request

curl -X GET "https://api.thanxsandbox.com/upload_url?upload_type=receipt" \
  -H "Authorization: Bearer <token>" \
  -H "Accept-Version: v4.0"

Successful Response

{
  "url": "https://thanx-sandbox.s3.amazonaws.com/uploads/receipt/...",
  "image_path": "uploads/receipt/image_<unique>.jpeg"
}
The presigned URL expires. Make sure to upload your file before it does.

Step 2 — Upload the Image to S3 Using the Presigned URL

The upload must be raw binary. Multipart uploads will corrupt the file and cause validation errors.

Correct Upload Using curl

curl -X PUT "presigned_url;" \
  -H "Content-Type: image/jpeg" \
  --data-binary @"my_receipt.jpg"

Correct Upload Using Postman

  • Method → PUT
  • URL → paste the full presigned URL
  • Body → select binary
  • Click Select File
  • Headers → add: Content-Type: image/jpeg

Do Not Use

  • form-data
  • raw
  • file upload inside raw
  • multipart/form-data These formats produce the error:
Image content type is not a valid image

Step 3 — Submit the Receipt

Once the image is successfully uploaded to S3, you can submit the receipt.

Example Request

curl https://api.thanxsandbox.com/receipts \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Accept-Version: v4.0" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "receipt": {
      "merchant_id": "abc123",
      "amount": 13.45,
      "payment_type": "cash",
      "purchased_at": "2024-09-15T00:52:10.655+00:00",
      "image_path": "uploads/receipt/image_<unique>.jpeg",
      "user_comments": "Card reader was down"
    }
  }'

Internal Note

The Thanx backend temporarily downloads the image from S3 for processing and deletes the temporary upload afterward.

Common Errors & Fixes

Error: Image content type is not a valid image

Cause: The file was uploaded using multipart/form-data.
Fix: Re-upload using raw binary.

Error: Image file is empty or corrupted

Causes:
  • Missing --data-binary
  • Incorrect Content-Type
  • Expired presigned URL
Fix: Ensure:
  • Correct content type
  • URL is still valid
  • Upload is binary

Summary

  • 1 Request presigned URL via /upload_url
  • 2 Upload the image to S3 using a PUT binary request
  • 3 Submit the receipt using the returned image_path