For agents and developers
Pinpal Receipts API and MCP.
The MCP server for assistants, a REST API for your own code, the same sign-in and the same token. A short version for agents is at llms.txt.
Works withClaudeChatGPTand any AI with MCP
Works withClaudeChatGPTand any AI with MCP
Pinpal Receipts connector address
https://receipts.mypinpal.com/mcpPaste this address into Claude, ChatGPT or any AI with MCP, and sign in with Apple or Google. Step by step · API and MCP reference
Pinpal Receipts keeps a small business's paperwork one month at a time: the bank statement's lines, each with its receipt. If they connected you, you find the receipts they are missing (in their mail, through their mail connector), attach them, say in the line's thread where each came from, and tell them what is still open. Pinpal does no bookkeeping.
- MCP server:
https://receipts.mypinpal.com/mcp. For Claude, ChatGPT and every other MCP client. Nothing to install. - REST API:
https://receipts.mypinpal.com/api/v1, below. Same token.
Base URL: https://receipts.mypinpal.com/api/v1.
Auth: Authorization: Bearer TOKEN.
A short copy of this page lives at /llms.txt.
MCP server and tools
Server URL: https://receipts.mypinpal.com/mcp (Streamable
HTTP). Any MCP client that supports OAuth connects on its own: a call
without a token answers 401 and points at
/.well-known/oauth-protected-resource,
the client registers itself and sends the person to sign in with Apple or
Google. Every tool is one call into the REST API below, so the rules are the same whichever door is used.
get_account: the account, statuses, labels, months with counts, the Inbox count.list_months: the months, withtotal, missing, found, done, notNeeded.list_lines: a month's lines:open(missing and found),closed,all, or one status; by label.read_line: a line by its number in the month, with files, thread and Inbox suggestions.add_line: a line by hand (cash).update_line: status, note, memo, labels; text, date and amount on a hand-made line.list_comments / add_comment: the line's thread.list_inbox: receipts not yet on a line, with up to three suggested lines each.read_document: a receipt: an image comes back as the image, a PDF or text as text.upload_document:base64ortext; withmonthandnumberonto a line, withmonthinto that month, with neither into the Inbox.attach_document / detach_document: onto a line, or back to the Inbox.import_statement: a CSV or a PDF with text into lines.list_labels: use the person's labels, never make them.export_month: a 30-day link to the month's zip.send_to_accountant: mails that link.
How to behave
- Set
doneonly after checking that amount, date and merchant match; otherwise leavefoundand say what is unsure. - Say in the thread where each receipt came from.
not_neededneeds anote: the reason. Every status change is written into the thread.- An imported line's text, date and amount cannot change.
- Use the person's labels; unknown names are refused.
- Never do bookkeeping. Export or mail only when asked.
- You cannot delete a comment, a file or a receipt, or change a label (
403). Detaching is allowed.
REST API
| Method and path | What |
|---|---|
GET /me | the account, statuses, labels, months, Inbox count |
DELETE /me | revoke this token |
GET /months · POST /months | the months; an empty month |
GET/PATCH /months/:key | the month with its lines |
GET/POST /months/:key/lines | lines (?status=&label=); a line by hand |
GET/PATCH /months/:key/lines/:n | one line |
GET/POST /months/:key/lines/:n/comments | the thread |
GET/POST /months/:key/lines/:n/files | files; a receipt straight onto the line |
POST /months/:key/lines/:n/files/:k/detach | back to the Inbox |
GET /inbox · POST /inbox?month= | the Inbox; a receipt into it (a sure match is attached at once) |
GET /documents/:id · POST /documents/:id/attach | a receipt; attach it to {month, number} |
POST /import?month= | a statement into lines |
POST /months/:key/export | {url, name, expiresAt} |
POST /months/:key/send | {email, message?}: mails the link |
GET /labels | the labels |
Shapes
Month: 2026-09, with counts total, missing, found, done, notNeeded, handled.
Line: one row of the statement, addressed by its number in the month. amount is signed, negative is money out. status is missing, found, done or not_needed. memo is the person's own words.
Document: a receipt, in the Inbox or on a line. read holds what was read off it: status, amount, currency, date, merchant.
Errors
401missing or bad token402the free plan is full: a new one past the 20 free receipts ({"error":"free_limit_reached","limit":20,"message":"..."}); relay the message, do not retry403only the person may do this (delete, change labels)404no such thing400a bad body, or a statement that is a photo (with the reason)
OAuth 2.0
An app can obtain a token without a paste. The person signs in on
receipts.mypinpal.com; your server swaps the code for the same kind of
personal API token. Discovery:
/.well-known/oauth-authorization-server.
GET https://receipts.mypinpal.com/oauth/authorize
?client_id=…
&redirect_uri=…
&response_type=code
&state=…
&code_challenge=…
&code_challenge_method=S256
POST https://receipts.mypinpal.com/oauth/token
grant_type=authorization_code
code=…
redirect_uri=…
client_id=…
code_verifier=…
→ { "access_token": "…", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "…", "scope": "receipts" }
Dynamic client registration and PKCE are supported, so an MCP client needs no setup.