Entryfy Receipt Scanner API

Extract structured data from receipt photos using AI vision. Plug-and-play for any campaign or project.

Base URL
https://cudofkdbcfhkdqxxxeje.supabase.co/functions/v1
Future: https://api.entryfy.com.na

Authentication

All requests require a Bearer token in the Authorization header.

Authorization: Bearer rsk_your_api_key_here

Service keys are hashed (SHA-256 + pepper) and stored in the database. Each key is scoped to a campaign — the campaign determines extraction rules, provider overrides, and product tagging.

To generate a new key, use node scripts/hash-service-key.mjs "your-raw-key" and insert the hash into receipt_scanner_api_service_keys.

Endpoints

POST /extract

Extract structured data from a receipt image. Accepts multipart form uploads or JSON with base64/URL.

Option 1: Multipart Form Upload (recommended)

curl -X POST https://cudofkdbcfhkdqxxxeje.supabase.co/functions/v1/extract \
  -H "Authorization: Bearer rsk_your_key" \
  -F "image=@receipt.jpg"

Option 2: JSON with Base64

curl -X POST https://cudofkdbcfhkdqxxxeje.supabase.co/functions/v1/extract \
  -H "Authorization: Bearer rsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "imageBase64": "/9j/4AAQ...",
    "mimeType": "image/jpeg"
  }'

Option 3: JSON with Image URL

curl -X POST https://cudofkdbcfhkdqxxxeje.supabase.co/functions/v1/extract \
  -H "Authorization: Bearer rsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "imageUrl": "https://example.com/receipt.jpg" }'

Request Parameters

FieldTypeRequiredDescription
imageFilemultipartReceipt image file (JPEG, PNG, or WebP)
imageBase64stringjsonBase64-encoded image data
mimeTypestringwith base64image/jpeg, image/png, or image/webp
imageUrlstringjsonHTTPS URL to a receipt image

Constraints: Max 15 MB. Images only (no PDF). Provide exactly one of image, imageBase64, or imageUrl.

Success Response (200)

{
  "success": true,
  "data": {
    "upload_id": "uuid",
    "extraction_id": "uuid",
    "campaign_id": "uuid",
    "campaign_name": "My Campaign",
    "provider_id": "gemini",
    "model_id": "gemini-2.5-flash",
    "latency_ms": 7500,
    "vision_ms": 6200,
    "normalize_ms": 120,
    "extraction": {
      // ... see Extraction Schema below
    }
  }
}

Error Response (4xx / 5xx)

{
  "success": false,
  "error": {
    "code": "invalid_image",
    "message": "PDF files are not accepted. Upload a photo."
  }
}
CodeHTTPDescription
unauthorized401Missing, invalid, expired, or revoked API key
invalid_image400Not a valid JPEG/PNG/WebP, or file is a PDF
validation_error400Missing required fields or bad request body
unsupported_media415Content-Type is not multipart or JSON
extraction_failed502Vision AI provider error or timeout
storage_error500Failed to store image in Supabase Storage
db_error500Failed to persist extraction to database

Extraction Schema

The extraction object contains all data extracted from the receipt. All fields are nullable — only fields visible on the receipt will have values.

Merchant / Store

FieldTypeDescription
merchant_namestringStore or business name
merchant_addressstringFull address as printed
merchant_phonestringPhone number(s)
merchant_faxstringFax number
merchant_emailstringEmail address
merchant_websitestringWebsite URL
merchant_vat_numberstringVAT / tax registration number
merchant_registration_numberstringCompany registration number
merchant_liquor_licensestringLiquor license number
store_branchstringBranch or location name
store_numberstringStore/shop number

Transaction

FieldTypeDescription
purchase_datestringDate as YYYY-MM-DD
purchase_timestringTime as HH:MM or HH:MM:SS (24h)
currencystringISO code (NAD, ZAR, USD, etc.)
receipt_typestring"tax_invoice", "receipt", "credit_note"
receipt_numberstringReceipt or slip number
invoice_numberstringInvoice number
transaction_idstringTransaction reference
slip_numberstringSlip number

Staff & Terminal

FieldTypeDescription
cashier_namestringCashier / operator name
cashier_numberstringCashier ID
pos_terminalstringPOS / till number
register_numberstringRegister number

Totals & Payment

FieldTypeDescription
subtotalnumberAmount before tax
taxnumberTotal VAT / tax amount
tax_ratenumberPrimary VAT % (e.g. 15)
totalnumberFinal total
total_itemsnumberNumber of line items
total_quantitynumberTotal quantity of all items
total_savingsnumberTotal discount/promo savings
roundingnumberCash rounding amount
change_duenumberChange given back
amount_tenderednumberAmount paid
non_taxable_totalnumberZero-rated items total
payment_method_hintstring"card", "cash", "eft", etc.
tax_breakdownarrayPer-rate tax rows: { rate_percent, tax_amount, gross_amount, net_amount }

Loyalty & Card

FieldTypeDescription
loyalty_card_numberstringLoyalty / rewards card number
loyalty_pointsstringPoints earned or balance
loyalty_program_namestringProgram name (e.g. "SPAR Rewards")
card_typestringCard brand (FNB, Visa, etc.)
card_last_fourstringLast 4 digits of card

Line Items

Array of product lines extracted from the receipt.

FieldTypeDescription
namestringProduct name
quantitynumberUnits purchased
unit_pricenumberPrice per unit
line_totalnumberTotal for this line
discountnumberDiscount amount on this item
vat_amountnumberPer-item VAT if shown
tax_indicatorstringTax code ("A" taxable, "*" zero-rated)
barcodestringEAN/UPC barcode number
skustringInternal product code
unit_of_measurestring"each", "kg", "ltr", etc.
package_sizestringPackaging as printed ("500ML", "1KG", "72'S")
raw_textstringComplete raw text of the line

Footer & Misc

FieldTypeDescription
warningsstring[]Notes about image quality or ambiguity
raw_footer_textstringFooter messages, return policies
barcode_at_bottomstringBarcode number at bottom of receipt

Normalization Metadata

Included in the extraction as normalization_meta:

FieldTypeDescription
merchant_alias_idstringMatched alias ID (if normalized)
merchant_display_namestringCanonical merchant name after alias lookup
needs_reviewbooleanFlagged for human review
review_reasonsstring[]Why it was flagged

Campaigns

Each API key is scoped to a campaign. Campaigns can customize:

Learning / Normalization

The system improves over time through two alias tables:

Add aliases via Supabase dashboard or direct SQL. They apply globally or per-campaign.

Integration Examples

JavaScript / TypeScript

const form = new FormData();
form.append('image', fileInput.files[0]);

const res = await fetch('https://cudofkdbcfhkdqxxxeje.supabase.co/functions/v1/extract', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer rsk_your_key' },
  body: form,
});

const { data } = await res.json();
console.log(data.extraction.merchant_name);
console.log(data.extraction.total);
console.log(data.extraction.line_items);

Python

import requests

with open('receipt.jpg', 'rb') as f:
    r = requests.post(
        'https://cudofkdbcfhkdqxxxeje.supabase.co/functions/v1/extract',
        headers={'Authorization': 'Bearer rsk_your_key'},
        files={'image': f}
    )

data = r.json()['data']
print(data['extraction']['merchant_name'])
print(data['extraction']['total'])

cURL

curl -X POST https://cudofkdbcfhkdqxxxeje.supabase.co/functions/v1/extract \
  -H "Authorization: Bearer rsk_your_key" \
  -F "image=@receipt.jpg"

Limits & Notes

Database Tables

TablePurpose
receipt_scanner_api_campaignsCampaign config, rules, provider overrides
receipt_scanner_api_service_keysHashed API keys scoped to campaigns
receipt_scanner_api_uploadsImage upload metadata, storage paths, status
receipt_scanner_api_extractionsRaw + normalized extraction JSON, provider, timings
receipt_scanner_api_merchant_aliasesMerchant name normalization mappings
receipt_scanner_api_product_aliasesProduct tagging rules
receipt_scanner_api_async_jobsAsync extraction jobs (future)
Entryfy Receipt Scanner API — FutureMedia Digital