Select a topic:

Choose from one of the topics below to browse other articles

Articles & Information.

Billing workflow

Last updated by Jens N. on March 20, 2015 15:09

This tutorial covers a common billing workflow.  You will walk through the endpoints(API calls) in chronological order and see generic json-strings for each step.

Please ensure you have read Getting started since all steps should be replicated using cREST by pasting the json examples.

You may also want to install a browser JSON view extension, to have a quick and collapsible access to the /schema of each resource.

The workflow steps:

  • create a contact (client)
  • create an invoice
  • create a pdf
  • mail the invoice to the contact
  • create a payment reminder
  • create a payment

Gotcha's & Hints

  • Make sure to add "Content-type: application/json" to header.
  • Watch those trailing comma's at the end of any property list, those will result in an error .
  • In some steps you need to insert an object id. Such id's are shown as XYZ_ID, insert them as strings => "some-long-uuid"
  • For brevity the example data contains only some fields. You can find each objects properties in json-schema, with required fields marked.
  • Indenting of json ... borked by wordpress

Create a contact

First create a contact, which will be used in all further steps. The new contact(a client) is returned and you will need it's id for the next step. IMPORTANT: Addresses, even if it is only one, must be inside an ARRAY see []

POST  ../api/contacts
"contact": {
"type": "Client",
"phone_office": "0049-2235-896578",
"due_days": 14,
"organisation": "Igrow Inc.",
"tag_list": "farming",
"email": "info@salesking.eu",
"addresses": [ {
"address": {
"address1": "Farmers Alley. 23",
"city": "Greenwood",
"zip": "30567"

Create an invoice

Insert the contact_id returned by the last call(or leave it empty to create a doc without a contact). The biggest magic is behind "status":"open", which sets the number, date and due_date if those are NOT present. The due date is calculated from the contact due days, but can also be set from due_days. IMPORTANT: LineItems must be inside an ARRAY see []

POST  ../api/invoices
"invoice": {
"contact_id": CONTACT_ID,
"title": "Your invoice No. [number]",
"line_items": [ {
"line_item": {
"tax": 19,
"name": "Mary's Best",
"position": 1,
"quantity": 10,
"quantity_unit": "Pieces",
"description": "High quality fast growing seeds.",
"price_single": 1.45
} ]

Create an archived PDF for the invoice

The archived PDF is saved on our servers and used in emails and exports. It serves as a final snapshot of a document. Each document can have many PDF-versions BUT only the MOST RECENT will be returned as archived_pdf. PDF creation involves using a PDF template, so please grab the id of a template found in the templates-edit url(click icon in list). 

POST ../api/invoices/INVOICE_ID/print
"template_id": PDF_TEMPLATE_ID

Create an Email

An Email must be related to an object(contact,document), therefore it can only be created within it's parent url(/invoices/:ID/emails).

For simplicity, email creation can be done using an email template. The templates subject, body and attachments are used and placeholder are substituted.

By setting "send" the Email is DIRECTLY delivered, so watch those test-addresses!!!

The third option "archived_pdf" tries to append an existing archived PDF to the email, of course only making sense for documents. Both options are only checked for their presence, their values don't matter.

POST ../api/invoices/INVOICE_ID/emails
"email": {
"to_addr": "valid receiver, or@two",
"from_addr": "valid-sender"
"template_id": EMAIL_TEMPLATE_ID,
"send": "1",
"archived_pdf": "1"

Create a payment reminder

The simplest way is using its nested parent(invoice) path. You just make an empty POST and the reminder will be created from the invoice and the payment-reminder settings.

Of course you can add any properties and CRUD operations with /payment_reminders path are also available.

POST ../api/invoices/INVOICE_ID/payment_reminders

With the reminder in place you should print it and depending on your workflow create an email

Create a payment

Like emails payments cannot be created on their own. See "new_doc_status" which can be used to close the related document.

POST ../api/invoices/INVOICE_ID/payments
"payment": {
"amount": 17.26,
"method": "bank_transfer",
"new_doc_status": 'closed'