Merran documentation API & integrations
Scan a receipt
const url = 'http://localhost:3000/api/pantry/receipts';const form = new FormData();form.append('file', 'file');form.append('text', 'example');
const options = { method: 'POST', headers: {cookie: 'merran.session_token=<merran.session_token>'}};
options.body = form;
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://localhost:3000/api/pantry/receipts \ --header 'Content-Type: multipart/form-data' \ --cookie merran.session_token=<merran.session_token> \ --form file=@file \ --form text=exampleReads a receipt into a draft to look over before anything goes in the pantry: photos of a paper one, screenshots or a PDF of an emailed one (up to 6 files, one file field each), or its text. Each line says what it is, how much, and the shopping list item it was bought for. Add it with POST /pantry/receipts/{receiptId}/add; it’s forgotten after a day. Uses the household’s model for receipts, which must be able to read photos or PDFs if those are sent, and counts towards its AI spend. With an API key, it needs the pantry: write permission.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
A photo, screenshot or PDF of the receipt.
The receipt’s text, as from an email.
Responses
Section titled “Responses”Read, waiting for a look.
object
The day on it.
object
As printed.
What it is, plainly.
Food goes in the pantry; household things and the rest don’t, unless they’re picked.
The shopping list item it was bought for, taken off the list when it’s added.
object
The receipt’s photos or PDF, to compare with.
object
Example
{ "id": "0199e8b0-5a10-7a01-8b00-00000000002e", "store": "Walmart", "date": "2026-10-14", "total": 48.12, "lines": [ { "id": "0d1b5c2a9e44", "text": "GV WHL MLK 1GAL", "name": "whole milk", "amount": "1 gal", "price": 3.48, "kind": "food", "listItem": { "id": "0199e8b0-5a10-7a01-8b00-00000000001d", "name": "milk" } } ], "files": [ { "url": "/api/pantry/receipts/0199e8b0-5a10-7a01-8b00-00000000002e/files/0", "mediaType": "image/jpeg" } ], "createdAt": "2026-10-15T18:30:00.000Z"}Nothing to read, or a file Merran can’t read.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}Not signed in.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}Not allowed.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}The files are too big.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}It isn’t a receipt (receipt_is_recipe when it’s a recipe), or the model can’t read photos or PDFs.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}This month’s AI limit is reached.
object
object
object
Example
{ "error": { "code": "not_found", "message": "There's nothing here.", "fields": { "name": "Give it a name." } }}© 2026 Kyle Johnson. Documentation: CC BY 4.0. Merran: AGPL-3.0-or-later.