Overview
Staple Invoice exposes two programmatic surfaces. The REST API provides full read and write access to bills (AP) and invoices (AR) over HTTP — create, update, soft-delete, restore, integrity verification, and Peppol UBL export. The MCP server lets any MCP-compatible AI agent — Claude Code, Claude Desktop, claude.ai — read and write invoice data directly from your AI workflow.
Both surfaces share the same authentication mechanism: personal access tokens minted in Settings → Developers. One token works for both.
https://invoice.staple.jpAuthentication
Create a personal access token in the Staple Invoice app under Settings → Developers. The token is shown once — copy it immediately. It is stored only as a SHA-256 hash and is bound to your (orgId, userId)pair, so it inherits your organisation’s tenancy boundaries automatically.
Pass the token as a standard Bearer credential:
Authorization: Bearer <your-token>
Example
curl https://invoice.staple.jp/api/bills \ -H "Authorization: Bearer $TOKEN"
Query-parameter fallback
The MCP server URL also accepts ?token=<token>. Clients like Claude Desktop and claude.ai only take a Name and URL with no header field, so this is the only way to attach a static token there. Prefer the Authorization header wherever the client supports it.
https://invoice.staple.jp/api/mcp?token=<your-token>
List bills
/api/billsBearer token or session cookieReturns all AP bills for your organisation, newest first. Soft-deleted bills are excluded.
curl https://invoice.staple.jp/api/bills \ -H "Authorization: Bearer $TOKEN"
Create bill
/api/billsBearer token or session cookieCreate a new AP bill. The route runs vendor linking (find-or-create the canonical vendor row), AI category suggestion, duplicate detection (same vendor + number, or same vendor + amount within 30 days), and JPY-equivalent FX estimation for non-JPY bills.
For OCR-promoted bills the client posts with a triage id (id starts with "ocr-"); the route generates a stable inv-<ulid> id and the call is idempotent on reload. For direct creates, supply a final id and the call is idempotent on that id.
curl -X POST https://invoice.staple.jp/api/bills \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "inv-01jxx...",
"vendor": "Acme Cloud KK",
"amount": 48000,
"currency": "JPY",
"received": "2026-06-01"
}'Returns the created bill with status 201. Returns 200 with the existing row if the id was already committed (idempotent).
Get bill
/api/bills/{id}Bearer token or session cookieFetch a single bill by ID. Returns 404 if not found or in a different organisation.
curl https://invoice.staple.jp/api/bills/inv-01jxx... \ -H "Authorization: Bearer $TOKEN"
Update bill
/api/bills/{id}Bearer token or session cookiePatch one or more fields. Only supplied fields are changed. A status change fires a status-changed event in the audit log; each other field change fires a field-edited event (訂正削除履歴 for 電子帳簿保存法). Changing currency or amount automatically re-estimates jpyAmount unless the caller also supplies jpyAmount or jpyConfirmed directly.
To restore a soft-deleted bill, send { "restore": true }.
# Approve a bill
curl -X PATCH https://invoice.staple.jp/api/bills/inv-01jxx... \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "status": "approved" }'
# Restore a deleted bill
curl -X PATCH https://invoice.staple.jp/api/bills/inv-01jxx... \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "restore": true }'Delete bill
/api/bills/{id}Bearer token or session cookieSoft-delete — the row is hidden from list/get but retained for 電子帳簿保存法 history, and can be un-deleted via PATCH { "restore": true }. An optional { "reason": "..." } body is recorded on the deleted audit event.
curl -X DELETE https://invoice.staple.jp/api/bills/inv-01jxx... \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "reason": "duplicate upload" }'Returns 204 No Content. Returns 404 if not found or already deleted.
Bill activity log
/api/bills/{id}/activityBearer token or session cookieFull 訂正削除履歴 audit trail for a bill — imports, status changes, field edits, and deletes/restores — oldest first.
curl https://invoice.staple.jp/api/bills/inv-01jxx.../activity \ -H "Authorization: Bearer $TOKEN"
[
{
"id": "evt_...",
"invoiceId": "inv-01jxx...",
"userId": "usr_...",
"userName": "Dev User",
"userEmail": "dev@staple.local",
"type": "status-changed",
"fromStatus": "ai-review",
"toStatus": "auto-approved",
"data": null,
"createdAt": "2026-06-04T02:11:00.000Z"
}
]Verify bill integrity
/api/bills/{id}/verifyBearer token or session cookie電子帳簿保存法 真実性 check. Re-fetches the preserved source file from Blob storage, recomputes its SHA-256, and compares it to the hash captured at ingest. A mismatch means the stored bytes were altered after the fact. The check itself is logged immutably in the audit trail.
curl -X POST https://invoice.staple.jp/api/bills/inv-01jxx.../verify \ -H "Authorization: Bearer $TOKEN"
{
"ok": true,
"expected": "e3b0c44298fc1c14...",
"actual": "e3b0c44298fc1c14...",
"match": true
}List invoices
/api/invoicesBearer token or session cookieReturns all AR invoices for your organisation, newest first. Soft-deleted invoices are excluded.
curl https://invoice.staple.jp/api/invoices \ -H "Authorization: Bearer $TOKEN"
Create invoice
/api/invoicesBearer token or session cookieCreate a new AR invoice. The route runs customer vendor linking (find-or-create a kind="payer" vendor), payment-terms inference from the issue → due gap, and duplicate detection (same customer + number, or same customer + amount within 30 days). Creation fires a created event in the immutable audit log.
curl -X POST https://invoice.staple.jp/api/invoices \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"number": "INV-2026-001",
"customer": "Acme Corp",
"amount": 100000,
"currency": "JPY",
"sentIso": "2026-06-01"
}'Returns the created invoice with status 201.
Get invoice
/api/invoices/{id}Bearer token or session cookieFetch a single invoice by ID. Returns 404 if not found or in a different organisation.
curl https://invoice.staple.jp/api/invoices/inv-01jxx... \ -H "Authorization: Bearer $TOKEN"
Update invoice
/api/invoices/{id}Bearer token or session cookiePatch one or more fields. A status change fires a status-changed event; each other field change fires a field-edited event in the immutable audit log. Pass { "restore": true } to un-delete a soft-deleted invoice.
# Mark an invoice paid
curl -X PATCH https://invoice.staple.jp/api/invoices/inv-01jxx... \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "status": "paid" }'Delete invoice
/api/invoices/{id}Bearer token or session cookieSoft-delete — the row is hidden from list/get but retained for 電子帳簿保存法 history, and can be un-deleted via PATCH { "restore": true }. An optional { "reason": "..." } body is recorded on the deleted audit event.
curl -X DELETE https://invoice.staple.jp/api/invoices/inv-01jxx... \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "reason": "sent to wrong customer" }'Returns 204 No Content. Returns 404 if not found or already deleted.
Peppol UBL export
/api/invoices/{id}/peppolBearer token or session cookieGenerate a JP PINT-compliant UBL 2.1 XML document for the invoice. The generated XML is persisted to Blob storage as the authoritative transmitted artifact, its SHA-256 upgrades the stored integrity fingerprint, and the export is logged immutably.
Returns application/xml as a file download.
| Status | Meaning |
|---|---|
| 200 | UBL XML returned as attachment. |
| 400 | invalid_invoice — generated XML failed structural validation. Response includes issues array. |
| 422 | not_exportable — invoice lacks captured line items (e.g. seeded demo records). |
curl https://invoice.staple.jp/api/invoices/inv-01jxx.../peppol \ -H "Authorization: Bearer $TOKEN" \ -o invoice.xml
Verify invoice integrity
/api/invoices/{id}/verifyBearer token or session cookie電子帳簿保存法 真実性 check for issued invoices. If a transmitted artifact (UBL/PDF) was persisted via the Peppol export, re-fetches and re-hashes it; otherwise recomputes the canonical snapshot hash. Compares to the stored fingerprint and logs the run immutably.
curl -X POST https://invoice.staple.jp/api/invoices/inv-01jxx.../verify \ -H "Authorization: Bearer $TOKEN"
{
"ok": true,
"expected": "e3b0c44298fc1c14...",
"actual": "e3b0c44298fc1c14...",
"match": true
}Forward a bill by email
Every organisation has a dedicated inbound address — forward or BCC a vendor bill to it and it lands in your Inbox, no API call or login required. Find your address on the Inbox screen under “Forward bills by email.”
<org-id>@bill.staple.jp (lowercased)Each PDF, JPEG, or PNG attachment — plus Peppol / JP PINT UBL XML — runs through the same OCR pipeline as a browser upload and lands as a real bill with status: "ai-review". Nothing is auto-approved: every email-ingested bill still needs a human to confirm it, exactly like a dragged-in file. An email with multiple attachments creates one bill per attachment.
Duplicate protection
Byte-identical re-deliveries (a webhook retry, an accidental double-forward) are skipped automatically via a content-hash check, before OCR ever runs. Bills sharing a vendor and document number are flagged as a possible duplicate for review, same as any other ingestion path.
Limits
| Constraint | Detail |
|---|---|
| File size | 4.5MB per attachment. Larger images are compressed automatically before OCR; oversized PDFs are skipped. |
| File types | PDF, JPEG, PNG, and Peppol/JP PINT UBL XML. Other attachment types are silently skipped, not a hard failure for the whole email. |
| Sender | Not restricted to a pre-registered address — a bill’s real sender is the vendor’s own billing system. A sender domain that doesn’t match the resolved vendor’s known domain gets an informational flag in review, not a block. |
Errors
All error responses return JSON with an error field. HTTP status codes follow standard conventions.
| Status | Error | Cause |
|---|---|---|
| 401 | unauthorized:no-session · unauthorized:no-org · unauthorized:invalid-token | Missing, invalid, or revoked Bearer token — or no session cookie. |
| 400 | invalid_body | Request body failed schema validation. The response includes an issues field with the full error detail. |
| 404 | not_found | Document does not exist or belongs to a different organisation. |
| 400 | invalid_invoice | Peppol export: generated UBL failed structural validation. Response includes an issues array. |
| 422 | not_exportable | Peppol export: invoice cannot be exported (missing line items). |
MCP server
The Staple Invoice MCP server runs in-process as a stateless Streamable-HTTP server. Connect any MCP-compatible AI client to read and write invoice data from within your AI workflow.
https://invoice.staple.jp/api/mcpConnect from Claude Code
claude mcp add staple-invoice --transport http \ https://invoice.staple.jp/api/mcp \ --header "Authorization: Bearer $TOKEN"
Connect from Claude Desktop or claude.ai
These clients only accept a Name and URL — no custom header field. Pass the token as a query parameter instead:
Name: Staple Invoice URL: https://invoice.staple.jp/api/mcp?token=<your-token>
Test with MCP Inspector
npx @modelcontextprotocol/inspector # → Transport: Streamable HTTP # → URL: http://localhost:3000/api/mcp # → Headers: Authorization: Bearer <token>
Available tools
19 tools across reads and safe writes. No deletes exposed via MCP, no email sending.
Read tools
| Tool | Description |
|---|---|
bill_list | List received (AP) bills, newest first. Optionally filtered by status. |
bill_get | Fetch a single AP bill by ID, including all extracted fields and line items. |
bill_activity | Get the full audit-trail activity log for a received bill. |
invoice_list | List all sent (AR) invoices for the org, newest first. |
invoice_get | Fetch a single invoice by ID. |
invoice_peppol | Get the Peppol / JP PINT UBL XML export of an invoice. |
vendor_search | Search or list vendors (payee and payer counterparties) in the organisation's directory. |
vendor_get | Fetch a single vendor by ID. |
vendor_rollup | Aggregate AP totals and bill counts for a vendor. |
space_list | List the org's spaces — cost centers / departments used to allocate invoices. |
draft_list | List AR invoice drafts. |
draft_get | Fetch a single draft by ID. |
draft_next_number | Get the next suggested invoice number for a new draft. |
report_summary | Financial summary — AP/AR counts and totals by status, plus outstanding and paid amounts on each side. |
Write tools
| Tool | Description |
|---|---|
bill_create | Create a new AP bill record with vendor linking and AI categorisation. |
bill_update | Update fields or change the status of a received bill (e.g. approve, mark paid). |
vendor_create | Create a new vendor in the payee directory. |
vendor_update | Patch fields on an existing vendor. Only supplied fields change. |
draft_upsert | Create or update an AR invoice draft. |