verification
use it
# add to stunt.yaml
services:
smartbill:
adapter: embedded:smartbill-style
# then
$ stunt upThe embedded: source extracts this adapter from the binary — no git clone, fully offline.
how to mock the SmartBill Cloud API locally
Install stunt, paste the service block above into stunt.yaml, run stunt up — then point your client at localhost instead of SmartBill Cloud API. It works offline, keeps state across requests and restarts, and every response is synthetic: the route shapes, status codes, pagination, and webhook delivery follow the real SmartBill Cloud API 1.0 surface — the data is fake, the behavior is real.
backing stores
invoiceestimatepaymentseriespurchase
api surface (18)
generated from the adapter manifest — exactly what boots, nothing more
18 routes
POST/invoice
GET/invoice
PUT/invoice/cancel
PUT/invoice/restore
GET/invoice/paymentstatus
POST/estimate
GET/estimate
PUT/estimate/cancel
POST/purchase
GET/purchase
POST/payment
DELETE/payment/v2
GET/stocks
POST/document/send
GET/tax
GET/series
POST/sim/company
POST/sim/stocks/movement
VM-verified behaviors (25)
- ✓requests without credentials are turned away with the errorText envelope
- ✓non-Basic schemes, malformed base64, and colon-less pairs are 401, never a 5xx
- ✓any username:token Basic pair is accepted, under any header case
- ✓the company bootstrap registers a cif and echoes it without internal fields
- ✓a missing cif is a 422 and an unknown cif is a plain 404
- ✓invoice create answers 200 with an empty body and numbers documents sequentially
- ✓totals are computed per line and returned as JSON numbers on read-back
- ✓the read-back drops internal fields and defaults issueDate from the clock
- ✓documents are scoped by series: the FCT number space is not the PRO one
- ✓cancel marks the invoice canceled and records the cancellation tax
- ✓restore flips the document back to active
- ✓canceling an unknown invoice is the 404 errorText envelope
- ✓a payment whose invoicesList number is a JSON number lands on its invoice
- ✓paymentstatus walks to paid and clamps overpayment at zero
- ✓deleting a payment un-pays the invoice; a second delete is 404
- ✓a payment body without the payment envelope is 422
- ✓estimates number on their own PRO counter and cancel like invoices
- ✓purchase invoices number on the ACH counter and carry the supplier object
- ✓stock movements seed quantities that read back grouped by warehouse
- ✓out movements decrement stock and cannot drain a product that was never in
- ✓productName and productCode filters narrow the grouped read
- ✓tax and series metadata are static {list} envelopes with no cif
- ✓document send records the message; a missing envelope is 422
- ✓undecodable and non-object bodies are a 400 errorText, never a 5xx
- ✓an empty body still creates when the cif rides in the query
Not implemented (3)
- No invoice/estimate/purchase list endpoints
- No PDF rendering, e-Factura (ANAF SPV) transmission, or email/SMS delivery
- No GET /invoice/paymentstatus (paidAmount/unpaidAmount/paid reporting)
Differs from the real API (4)
- paymentId on POST /invoice/payment is a simulator extension for the delete flow
- /tax and /series require no cif (real SmartBill scopes both per company)
- cif falls back to ?cif= for POST bodies; the real API takes companyVatCode from the body only
- Overpaid invoices report paidAmount above total and a zero-total invoice can never read paid
want more of the SmartBill Cloud API surface? adapters are YAML + Starlark — the authoring guide covers adding routes, fixtures, and state machines. Open an issue for anything big first, or just file a PR — merged routes ship in the next release.