Connect your own tools to Nuvabill
The REST API lets your scripts, accounting software or website read and change clients, services, invoices and tickets. It speaks JSON and is part of Nuvabill 0.4 and newer.
1. API keys
- Sign in to your admin area and open Your profile → API keys.
- Give the key a name, for example "Accounting sync". Tick Can change data only if the tool needs to create or change things.
- Copy the key. It starts with
nb_and is shown only once. Nuvabill keeps only a hash of it.
A key acts as you. It can only do what your role allows, so make a staff member with a small role for each tool. Delete a key on the same page to stop it at once. The API is turned off on the public demo.
2. Making requests
Send the key in the Authorization header of every request, to the address of your Nuvabill followed by /api/v1:
curl https://billing.yourhost.com/api/v1/me \
-H "Authorization: Bearer nb_your_key" \
-H "Accept: application/json"
- Amounts are in cents (the smallest unit of the currency):
2500is $25.00. Every amount comes with its currency. - Lists are paged. Add
?per_page=50&page=2(up to 100 per page). The answer hasdata,linksandmeta.total. - Filters: most lists take
client_idandstatus, for example/invoices?status=unpaid. - Send request bodies as JSON with
Content-Type: application/json.
3. Endpoints
| Request | What it does | Role permission |
|---|---|---|
GET /me | The staff member and key, and the Nuvabill version | Any |
GET /products | Products with their prices | Any |
GET /clients | Clients. Filters: email, status | View clients |
GET /clients/{id} | One client, with wallet balance | View clients |
POST /clients | Create a client | Manage clients |
GET /services | Services. Filters: client_id, status | Manage services |
GET /services/{id} | One service | Manage services |
POST /services/{id}/suspend | Suspend on the server. Optional reason | Manage services |
POST /services/{id}/unsuspend | Unsuspend on the server | Manage services |
POST /services/{id}/terminate | Remove the account from the server | Manage services |
GET /invoices | Invoices. Filters: client_id, status | View billing |
GET /invoices/{id} | One invoice with its lines and payments | View billing |
POST /invoices | Create an invoice | Manage billing |
POST /invoices/{id}/payments | Record a payment, for example a bank transfer | Manage billing |
GET /orders | Orders. Filters: client_id, status | Manage orders |
GET /tickets | Tickets, newest reply first. Filters: client_id, status | Manage support |
GET /tickets/{number} | One ticket with every reply | Manage support |
POST /tickets/{number}/replies | Reply as the key's staff member. The client gets the usual email | Manage support |
Read-only keys can use every GET request above. Requests that change data need a key that can change data.
4. Examples
Create a client
curl -X POST https://billing.yourhost.com/api/v1/clients \
-H "Authorization: Bearer nb_your_key" \
-H "Content-Type: application/json" \
-d '{"first_name": "Mer", "last_name": "Las", "email": "[email protected]", "country": "IQ"}'
Other fields: company_name, phone, address_1, city, state, postcode, tax_id and password. Without a password, the client sets one with "Forgot password".
Create an invoice
curl -X POST https://billing.yourhost.com/api/v1/invoices \
-H "Authorization: Bearer nb_your_key" \
-H "Content-Type: application/json" \
-d '{"client_id": 42, "send_email": true, "items": [
{"description": "Website design", "amount": 25000},
{"description": "Domain setup", "amount": 1500, "taxed": false}
]}'
Tax is added from your tax rules, like invoices made in the admin area. Add "draft": true to keep it hidden from the client, due_at for a due date and notes for a note.
Record a payment
curl -X POST https://billing.yourhost.com/api/v1/invoices/310/payments \
-H "Authorization: Bearer nb_your_key" \
-H "Content-Type: application/json" \
-d '{"amount": 26500, "gateway": "banktransfer", "reference": "BANK-7781"}'
A payment with the same gateway and reference is only recorded once, so it is safe to send again after a timeout. When the invoice is paid, services are set up or unsuspended, like any other payment.
Reply to a ticket
curl -X POST https://billing.yourhost.com/api/v1/tickets/482913/replies \
-H "Authorization: Bearer nb_your_key" \
-H "Content-Type: application/json" \
-d '{"message": "Your site is back online.", "status": "closed"}'
5. Errors and limits
| Status | Meaning |
|---|---|
401 | No key, a wrong key, or the staff member is turned off |
403 | The key can only read, or the role does not allow this |
404 | Not found |
422 | Something in the request is not valid. errors lists each field |
429 | Too many requests. Each key can send 120 requests a minute |
Every error has a message in plain English. Questions or ideas for new endpoints? Open an issue on GitHub.