InvoiceXpress API

Estimates

Create quotes, proformas or fees notes and send them to your clients.

Send by Email

PUT /:document-type/:document-id/email-document.json

Sends an estimate by email.

Example Body

{
  "message": {
    "client": {
      "email": "someone@example.com",
      "save": "0"
    },
    "subject": "Invoice from company",
    "body": "This is where the email body goes",
    "cc": "cc.client@company.com",
    "bcc": "bcc.client@company.com"
  }
}

Example Request

Format:
curl --request PUT \
  --url 'https://account_name.app.invoicexpress.com/:document-type/:document-id/email-document.json?api_key=YOUR%20API%20KEY%20HERE' \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --data '{"message":{"client":{"email":"someone@example.com","save":"0"},"subject":"Invoice from company","body":"This is where the email body goes","cc":"cc.client@company.com","bcc":"bcc.client@company.com","logo":"0"}}'
require 'uri'
require 'net/http'

url = URI("https://account_name.app.invoicexpress.com/:document-type/:document-id/email-document.json?api_key=YOUR%20API%20KEY%20HERE")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["accept"] = 'application/json'
request["content-type"] = 'application/json'
request.body = "{\"message\":{\"client\":{\"email\":\"someone@example.com\",\"save\":\"0\"},\"subject\":\"Invoice from company\",\"body\":\"This is where the email body goes\",\"cc\":\"cc.client@company.com\",\"bcc\":\"bcc.client@company.com\",\"logo\":\"0\"}}"

response = http.request(request)
puts response.read_body
var http = require("https");

var options = {
  "method": "PUT",
  "hostname": "account_name.app.invoicexpress.com",
  "port": null,
  "path": "/:document-type/:document-id/email-document.json?api_key=YOUR%20API%20KEY%20HERE",
  "headers": {
    "accept": "application/json",
    "content-type": "application/json"
  }
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(JSON.stringify({ message: 
   { client: { email: 'someone@example.com', save: '0' },
     subject: 'Invoice from company',
     body: 'This is where the email body goes',
     cc: 'cc.client@company.com',
     bcc: 'bcc.client@company.com',
     logo: '0' } }));
req.end();
import http.client

conn = http.client.HTTPSConnection("account_name.app.invoicexpress.com")

payload = "{\"message\":{\"client\":{\"email\":\"someone@example.com\",\"save\":\"0\"},\"subject\":\"Invoice from company\",\"body\":\"This is where the email body goes\",\"cc\":\"cc.client@company.com\",\"bcc\":\"bcc.client@company.com\",\"logo\":\"0\"}}"

headers = {
    'accept': "application/json",
    'content-type': "application/json"
    }

conn.request("PUT", "/:document-type/:document-id/email-document.json?api_key=YOUR%20API%20KEY%20HERE", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://account_name.app.invoicexpress.com/:document-type/:document-id/email-document.json?api_key=YOUR%20API%20KEY%20HERE",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"message\":{\"client\":{\"email\":\"someone@example.com\",\"save\":\"0\"},\"subject\":\"Invoice from company\",\"body\":\"This is where the email body goes\",\"cc\":\"cc.client@company.com\",\"bcc\":\"bcc.client@company.com\",\"logo\":\"0\"}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://account_name.app.invoicexpress.com/:document-type/:document-id/email-document.json?api_key=YOUR%20API%20KEY%20HERE"

	payload := strings.NewReader("{\"message\":{\"client\":{\"email\":\"someone@example.com\",\"save\":\"0\"},\"subject\":\"Invoice from company\",\"body\":\"This is where the email body goes\",\"cc\":\"cc.client@company.com\",\"bcc\":\"bcc.client@company.com\",\"logo\":\"0\"}}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("accept", "application/json")
	req.Header.Add("content-type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}

Path Parameters

Name Type Required Description Example
document-type String Required

The type of estimate you wish to send by email: quotes, proformas or fees_notes.

quotes
document-id Integer Required

ID of the document to send by email.

42

Request Body

Name Type Required Description Example
message Object Required

Email data.

{
  "message": {
  "message": { ... }
Object

Email data

    "client": {
    "client": { ... }
Object

Client email and save options.

      "email": "someone@example.com",
String

[Required] Document will be sent to this email address. Must be a valid email address ex: foo@bar.com

      "save": "0"
String

[Required] Saves this email as your client email address. (0 – Does not save the client’s email. 1 – Saves / Updates the client’s email).

    },
    "subject": "Invoice from company",
String

[Optional] The subject of the email.

    "body": "This is where the email body goes",
String

[Optional] The body of the email.

    "cc": "cc.client@company.com",
String

[Optional] Email CC field. Must be a valid email address ex: foo@bar.com

    "bcc": "bcc.client@company.com",
String

[Optional] Email BCC field. Must be a valid email address ex: foo@bar.com

    "logo": "0"
String

[Optional] Send email with logo. Defaults to 0. Only available in some plans. It’s ignored if the account doesn’t have the logo configured. Not available for trial accounts. (0 - Send email without logo. 1 - Send email with logo )

  }
}

Responses

200 Success

The email was sent successfully.

(Empty Response)
401 Access denied

The API Key parameter is missing or is incorrectly entered.

(Empty Response)
404 Not Found

The supplied :document-id doesn’t match any existing document.

(Empty Response)
422 Unprocessable Entity

Some parameters sent were incorrect.

(Empty Response)

Generate PDF

GET /api/pdf/:document-id.json

Returns the url of the PDF for the specified document. This is an asynchronous operation, which means the PDF file may not be ready immediately.

Example Request

Format:
curl --request GET \
  --url 'https://account_name.app.invoicexpress.com/api/pdf/:document-id.json?second_copy=false&api_key=YOUR%20API%20KEY%20HERE' \
  --header 'accept: application/json'
require 'uri'
require 'net/http'

url = URI("https://account_name.app.invoicexpress.com/api/pdf/:document-id.json?second_copy=false&api_key=YOUR%20API%20KEY%20HERE")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'

response = http.request(request)
puts response.read_body
var http = require("https");

var options = {
  "method": "GET",
  "hostname": "account_name.app.invoicexpress.com",
  "port": null,
  "path": "/api/pdf/:document-id.json?second_copy=false&api_key=YOUR%20API%20KEY%20HERE",
  "headers": {
    "accept": "application/json"
  }
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();
import http.client

conn = http.client.HTTPSConnection("account_name.app.invoicexpress.com")

headers = { 'accept': "application/json" }

conn.request("GET", "/api/pdf/:document-id.json?second_copy=false&api_key=YOUR%20API%20KEY%20HERE", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://account_name.app.invoicexpress.com/api/pdf/:document-id.json?second_copy=false&api_key=YOUR%20API%20KEY%20HERE",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://account_name.app.invoicexpress.com/api/pdf/:document-id.json?second_copy=false&api_key=YOUR%20API%20KEY%20HERE"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("accept", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}

Path Parameters

Name Type Required Description Example
document-id Integer Required

The document to convert to PDF.

42

Query Parameters

Name Type Required Description Example
second_copy Boolean Optional

Set value to true to generate copy of original document.

false

Responses

200 Success

The request has been successfully processed.

Estimates Generate pdf
{
  "output": {
  "output": { ... }
Object
    "pdfUrl": "https://sum.url"
String
  }
}
202 Accepted

The request will be processed. You need to keep requesting until you get a response with HTTP status code 200.

(Empty Response)
401 Not Found

No document matches the supplied :document-id.

(Empty Response)
401 Access denied

The API Key parameter is missing or is incorrectly entered.

(Empty Response)
406 Not Acceptable

The :document-id provided is in an invalid state.

(Empty Response)

Get

GET /:document-type/:document-id.json

Returns a specific estimate.

Example Request

Format:
curl --request GET \
  --url 'https://account_name.app.invoicexpress.com/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE' \
  --header 'accept: application/json'
require 'uri'
require 'net/http'

url = URI("https://account_name.app.invoicexpress.com/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'

response = http.request(request)
puts response.read_body
var http = require("https");

var options = {
  "method": "GET",
  "hostname": "account_name.app.invoicexpress.com",
  "port": null,
  "path": "/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE",
  "headers": {
    "accept": "application/json"
  }
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();
import http.client

conn = http.client.HTTPSConnection("account_name.app.invoicexpress.com")

headers = { 'accept': "application/json" }

conn.request("GET", "/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://account_name.app.invoicexpress.com/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://account_name.app.invoicexpress.com/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("accept", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}

Path Parameters

Name Type Required Description Example
document-type String Required

The type of estimate you want to get. For example: quotes, proformas or fees_notes.

quotes
document-id Integer Required

The requested estimate id.

42

Responses

200 Success

The estimate was returned successfully.

Estimates Get
{
  "quote": {
  "quote": { ... }
Object
    "id": 541791,
Integer
    "status": "final",
String
    "archived": false,
Boolean
    "type": "Quote",
String
    "sequence_number": "1/A",
String
    "inverted_sequence_number": "A/1",
String
    "date": "12/06/2017",
String
    "due_date": "12/06/2017",
String
    "reference": "foo",
String
    "observations": "foo",
String
    "retention": "foo",
String
    "permalink": "https://www.app.invoicexpress.com/documents/541791f16ae45a73b703c684a221ef198c10020f3d56a1",
String
    "saft_hash": "NfTN",
String
    "sum": 10,
Integer
    "discount": 0,
Integer
    "before_taxes": 10,
Integer
    "taxes": 2.3,
Number
    "total": 12.3,
Number
    "currency": "Euro",
String
    "client": {
    "client": { ... }
Object
      "id": 1310176,
Integer
      "name": "John",
String
      "country": "Portugal"
String
    },
    items: [
Array
      {
      { ... }
Object

Items

        "name": "iPhone",
String
        "description": "foo",
String
        "unit_price": "10.0",
String
        "unit": "foo",
String
        "quantity": "1.0",
String
        "tax": {
        "tax": { ... }
Object
          "id": 31567,
Integer
          "name": "IVA23",
String
          "value": 23
Integer
        },
        "discount": 0,
Integer
        "subtotal": 10,
Integer
        "tax_amount": 2.3,
Number
        "discount_amount": 0,
Integer
        "total": 12.3
Number
      }
    ]
    "sequence_id": "12345",
String
    "tax_exemption": "M01"
String
  }
}
401 Access denied

The API Key parameter is missing or is incorrectly entered.

(Empty Response)
404 Not Found

No estimate matches the supplied :document-id.

(Empty Response)

List All

GET /estimates.json

Returns all your estimates (quotes, proformas and fees notes). You can filter your estimates by passing parameters in the query string.

Example Request

Format:
curl --request GET \
  --url 'https://account_name.app.invoicexpress.com/estimates.json?text=foo&type%5B%5D=Quote&status%5B%5D=sent&date%5Bfrom%5D=30%2F09%2F2017&date%5Bto%5D=31%2F10%2F2017&due_date%5Bfrom%5D=30%2F09%2F2017&due_date%5Bto%5D=31%2F10%2F2017&total_before_taxes%5Bfrom%5D=100.00&total_before_taxes%5Bto%5D=500.00&non_archived=true&archived=false&page=1&per_page=30&api_key=YOUR%20API%20KEY%20HERE' \
  --header 'accept: application/json'
require 'uri'
require 'net/http'

url = URI("https://account_name.app.invoicexpress.com/estimates.json?text=foo&type%5B%5D=Quote&status%5B%5D=sent&date%5Bfrom%5D=30%2F09%2F2017&date%5Bto%5D=31%2F10%2F2017&due_date%5Bfrom%5D=30%2F09%2F2017&due_date%5Bto%5D=31%2F10%2F2017&total_before_taxes%5Bfrom%5D=100.00&total_before_taxes%5Bto%5D=500.00&non_archived=true&archived=false&page=1&per_page=30&api_key=YOUR%20API%20KEY%20HERE")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'

response = http.request(request)
puts response.read_body
var http = require("https");

var options = {
  "method": "GET",
  "hostname": "account_name.app.invoicexpress.com",
  "port": null,
  "path": "/estimates.json?text=foo&type%5B%5D=Quote&status%5B%5D=sent&date%5Bfrom%5D=30%2F09%2F2017&date%5Bto%5D=31%2F10%2F2017&due_date%5Bfrom%5D=30%2F09%2F2017&due_date%5Bto%5D=31%2F10%2F2017&total_before_taxes%5Bfrom%5D=100.00&total_before_taxes%5Bto%5D=500.00&non_archived=true&archived=false&page=1&per_page=30&api_key=YOUR%20API%20KEY%20HERE",
  "headers": {
    "accept": "application/json"
  }
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.end();
import http.client

conn = http.client.HTTPSConnection("account_name.app.invoicexpress.com")

headers = { 'accept': "application/json" }

conn.request("GET", "/estimates.json?text=foo&type%5B%5D=Quote&status%5B%5D=sent&date%5Bfrom%5D=30%2F09%2F2017&date%5Bto%5D=31%2F10%2F2017&due_date%5Bfrom%5D=30%2F09%2F2017&due_date%5Bto%5D=31%2F10%2F2017&total_before_taxes%5Bfrom%5D=100.00&total_before_taxes%5Bto%5D=500.00&non_archived=true&archived=false&page=1&per_page=30&api_key=YOUR%20API%20KEY%20HERE", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://account_name.app.invoicexpress.com/estimates.json?text=foo&type%5B%5D=Quote&status%5B%5D=sent&date%5Bfrom%5D=30%2F09%2F2017&date%5Bto%5D=31%2F10%2F2017&due_date%5Bfrom%5D=30%2F09%2F2017&due_date%5Bto%5D=31%2F10%2F2017&total_before_taxes%5Bfrom%5D=100.00&total_before_taxes%5Bto%5D=500.00&non_archived=true&archived=false&page=1&per_page=30&api_key=YOUR%20API%20KEY%20HERE",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://account_name.app.invoicexpress.com/estimates.json?text=foo&type%5B%5D=Quote&status%5B%5D=sent&date%5Bfrom%5D=30%2F09%2F2017&date%5Bto%5D=31%2F10%2F2017&due_date%5Bfrom%5D=30%2F09%2F2017&due_date%5Bto%5D=31%2F10%2F2017&total_before_taxes%5Bfrom%5D=100.00&total_before_taxes%5Bto%5D=500.00&non_archived=true&archived=false&page=1&per_page=30&api_key=YOUR%20API%20KEY%20HERE"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("accept", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}

Query Parameters

Name Type Required Description Example
text String Optional

Search for estimate, client or item details.

foo
type[] String Required

Possible values: Quote, Proforma or FeesNote.

Quote
status[] String Required

Possible values: draft, sent, accepted, refused or canceled.

sent
date[from] String Optional

Date in format dd/mm/yyyy. Ex: 30/09/2017

30%2F09%2F2017
date[to] String Optional

Date in format dd/mm/yyyy. Ex: 31/10/2017

31%2F10%2F2017
due_date[from] String Optional

Date in format dd/mm/yyyy. Ex: 30/09/2017

30%2F09%2F2017
due_date[to] String Optional

Date in format dd/mm/yyyy. Ex: 31/10/2017

31%2F10%2F2017
total_before_taxes[from] Number Optional

Minimum document amount. Ex: 100.00

100.00
total_before_taxes[to] Number Optional

Maximum document amount. Ex: 500.00

500.00
non_archived Boolean Required

Possible values: true or false.

true
archived Boolean Optional

Possible values: true or false.

false
page Integer Optional

You can ask for a specific page of invoices. Defaults to 1.

1
per_page Integer Optional

You can specify how many results you want to fetch. Defaults to 10 or value defined in account settings (10, 20 or 30).

30

Responses

200 Success

Estimates were returned successfully.

Estimates List all
{
  estimates: [
Array

List of all estimates.

    {
    { ... }
Object

Estimate Object

      "id": 541791,
Integer
      "status": "final",
String
      "archived": false,
Boolean
      "type": "Quote",
String
      "sequence_number": "1/A",
String
      "inverted_sequence_number": "A/1",
String
      "date": "12/06/2017",
String
      "due_date": "12/06/2017",
String
      "reference": "foo",
String
      "observations": "foo",
String
      "retention": "foo",
String
      "permalink": "https://www.app.invoicexpress.com/documents/541791f16ae45a73b703c684a221ef198c10020f3d56a1",
String
      "saft_hash": "NfTN",
String
      "sum": 10,
Integer
      "discount": 0,
Integer
      "before_taxes": 10,
Integer
      "taxes": 2.3,
Number
      "total": 12.3,
Number
      "currency": "Euro",
String
      "client": {
      "client": { ... }
Object
        "id": 1310176,
Integer
        "name": "John",
String
        "country": "Portugal"
String
      },
      items: [
Array
        {
        { ... }
Object

Items

          "name": "iPhone",
String
          "description": "foo",
String
          "unit_price": "10.0",
String
          "unit": "foo",
String
          "quantity": "1.0",
String
          "tax": {
          "tax": { ... }
Object
            "id": 31567,
Integer
            "name": "IVA23",
String
            "value": 23
Integer
          },
          "discount": 0,
Integer
          "subtotal": 10,
Integer
          "tax_amount": 2.3,
Number
          "discount_amount": 0,
Integer
          "total": 12.3
Number
        }
      ]
      "sequence_id": "12345",
String
      "tax_exemption": "M01"
String
    }
  ]
  "pagination": {
  "pagination": { ... }
Object

Pagination info.

    "total_entries": 6,
Integer
    "current_page": 1,
Integer
    "total_pages": 1,
Integer
    "per_page": 10
Integer
  }
}
401 Access denied

The API Key parameter is missing or is incorrectly entered.

(Empty Response)

Create

POST /:document-type.json

Creates a new quote, proforma or fees_note.

Creating new clients or items along with the estimate

This method also allows to create a new client and/or new items in the same request with the following behavior:

  • If the client name does not exist a new one is created.
  • If items do not exist with the given names, new ones will be created.
  • If item name already exists, the item is updated with the new values.

Taxes

Regarding item taxes, if the tax name is not found, the default tax is applyed to that item. Portuguese accounts should also send the IVA exemption reason if the estimate contains exempt items (IVA 0%).

Example URL

https://ACCOUNT_NAME.app.invoicexpress.com/quotes.json?api_key=API_KEY

You can find your ACCOUNT_NAME and API_KEY here: https://www.app.invoicexpress.com/users/api

Example Body

{
  "quote": {
    "date": "07/05/2017",
    "due_date": "08/05/2017",
    "client": {
      "name": "John",
      "code": "100"
    },
    "items": [
        {
          "name": "Product A",
          "description": "Cleaning product",
          "unit_price": "10.0",
          "quantity": "1.0"
        }
      ]
   }
}

Example Request

Format:
curl --request POST \
  --url 'https://account_name.app.invoicexpress.com/:document-type.json?api_key=YOUR%20API%20KEY%20HERE' \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --data '{"quote":{"date":"03/12/2017","due_date":"03/12/2017","client":{"name":"Client Name","code":"A1"},"items":[{"name":"Item Name","description":"Item Description","unit_price":"100","quantity":"5"}]}}'
require 'uri'
require 'net/http'

url = URI("https://account_name.app.invoicexpress.com/:document-type.json?api_key=YOUR%20API%20KEY%20HERE")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["accept"] = 'application/json'
request["content-type"] = 'application/json'
request.body = "{\"quote\":{\"date\":\"03/12/2017\",\"due_date\":\"03/12/2017\",\"client\":{\"name\":\"Client Name\",\"code\":\"A1\"},\"items\":[{\"name\":\"Item Name\",\"description\":\"Item Description\",\"unit_price\":\"100\",\"quantity\":\"5\"}]}}"

response = http.request(request)
puts response.read_body
var http = require("https");

var options = {
  "method": "POST",
  "hostname": "account_name.app.invoicexpress.com",
  "port": null,
  "path": "/:document-type.json?api_key=YOUR%20API%20KEY%20HERE",
  "headers": {
    "accept": "application/json",
    "content-type": "application/json"
  }
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(JSON.stringify({ quote: 
   { date: '03/12/2017',
     due_date: '03/12/2017',
     client: 
      { name: 'Client Name',
        code: 'A1'},
     items: 
      [ { name: 'Item Name',
          description: 'Item Description',
          unit_price: '100',
          quantity: '5' } ],
    }}));
req.end();
import http.client

conn = http.client.HTTPSConnection("account_name.app.invoicexpress.com")

payload = "{\"quote\":{\"date\":\"03/12/2017\",\"due_date\":\"03/12/2017\",\"client\":{\"name\":\"Client Name\",\"code\":\"A1\"},\"items\":[{\"name\":\"Item Name\",\"description\":\"Item Description\",\"unit_price\":\"100\",\"quantity\":\"5\"}]}}"

headers = {
    'accept': "application/json",
    'content-type': "application/json"
    }

conn.request("POST", "/:document-type.json?api_key=YOUR%20API%20KEY%20HERE", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
<?php

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://account_name.app.invoicexpress.com/:document-type.json?api_key=YOUR%20API%20KEY%20HERE",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"quote\":{\"date\":\"03/12/2017\",\"due_date\":\"03/12/2017\",\"client\":{\"name\":\"Client Name\",\"code\":\"A1\"},\"items\":[{\"name\":\"Item Name\",\"description\":\"Item Description\",\"unit_price\":\"100\",\"quantity\":\"5\"}]}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://account_name.app.invoicexpress.com/:document-type.json?api_key=YOUR%20API%20KEY%20HERE"

  payload := strings.NewReader("{\"quote\":{\"date\":\"03/12/2017\",\"due_date\":\"03/12/2017\",\"client\":{\"name\":\"Client Name\",\"code\":\"A1\"},\"items\":[{\"name\":\"Item Name\",\"description\":\"Item Description\",\"unit_price\":\"100\",\"quantity\":\"5\"}]}}")

  req, _ := http.NewRequest("POST", url, payload)

  req.Header.Add("accept", "application/json")
  req.Header.Add("content-type", "application/json")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}

Path Parameters

Name Type Required Description Example
document-type String Required

The type of document you want to create. For example: quotes, proformas or fees_notes.

quotes

Request Body

Name Type Required Description Example
quote Object Required

Estimate data to be created.

{
  "quote": {
  "quote": { ... }
Object

Replace quote with: proforma or fees_note depending on the type of document you want to create/update.

    "date": "3/12/2017",
String

[Required] The document date. Must be in format dd/mm/yyyy ex.: 03/12/2017. If format is invalid, date will be set to current date.

    "due_date": "03/12/2017",
String

[Required] The document due date. Must be in format dd/mm/yyyy ex.: 03/12/2017. If format is invalid, date will be set to current date.

    "reference": "999",
String

[Optional] The document purchase order reference field.

    "observations": "Observations",
String

[Optional] Document observations, these will be printed with the estimate.

    "retention": "0",
String

[Optional] Withholding tax percentage (%). Must be a number between 0 and 99.99.

    "tax_exemption": "M01",
String

[Required/Optional] Portuguese IVA exemption code. Required for portuguese accounts on invoices with IVA exempt items (0%). Must be one of the following: M01, M02, M03, M04, M05, M06, M07, M08, M09, M10, M11, M12, M13, M14, M15, M16, M99. See the table IVA Exemption Codes for more details.

    "sequence_id": "12345",
String

[Optional] ID of the sequence you want to use with this document. If missing, the default sequence will be used.

    "manual_sequence_number": "1",
String

[Required/Optional] Required for non-portuguese accounts with manual sequence numbering.

    "client": {
    "client": { ... }
Object

[Required] Client details.

      "name": "Client Name",
String

[Required] The document’s client. If the client doesn’t exist, a new one is created. If it exists, the remaining client fields will be ignored.

      "code": "A1",
String

[Required] The client’s unique code. If the client doesn’t exist, a new one is created. If it exists, the remaining client fields will be ignored.

      "email": "foo@bar.com",
String

[Optional] Client email address. Must be a valid email address ex: foo@bar.com

      "address": "Saldanha",
String

[Optional] Client company address.

      "city": "Lisbon",
String

[Optional] Client’s city.

      "postal_code": "1050-555",
String

[Optional] Client’s postal code for it’s company address.

      "country": "Portugal",
String

[Optional] Country, normally used for a company country. Although country is optional, when supplied, it should match one of the country list on the Appendix of this Documentation.

      "fiscal_id": "508000000",
String

[Optional] Client's fiscal ID (Número de Contribuinte).

      "website": "www.website.com",
String

[Optional] Client' website.

      "phone": "910000000",
String

[Optional] Client's phone number.

      "fax": "210000000",
String

[Optional] Client's fax number.

      "observations": "Observations"
String

[Optional] Client's default observations. This is added to the observations field of all the invoices sent to this client.

    },
    items: [
Array

[Required] An array of line items. If items with the given names do not exist, they are created. If an item already exists, it is updated with the new values. At least one is required.

      {
      { ... }
Object

Item Object

        "name": "Item Name",
String

[Required] Name of the item. Must be unique.

        "description": "Item Description",
String

[Required] Item’s description.

        "unit_price": "100",
String

[Required] Item’s unit price. Must be a number equal or greater than 0.0.

        "quantity": "5",
String

[Required] Quantity. Must be a number equal or greater than 0.

        "unit": "service",
String

[Optional] The unit of measure. Ex: hour, day, month, unit , service or other.

        "discount": "50",
String

[Optional] The item discount percentage (%). Defaults to 0.0. Must be a value between 0.0 and 100.0 inclusive.

        "tax": {
        "tax": { ... }
Object

[Optional] The tax applied to the line item. If not present the default tax is applied to the line item.

          "name": "IVA23"
String

[Optional] The tax name to be used on this line item. If not found the default tax is applied to the line item.

        }
      }
    ]
    "mb_reference": "0",
String

[Optional] Generates a Multibanco Reference after you finalize your estimate. This option is only available for Portuguese Accounts. You must have the feature enabled on your account first. Set value to "1" to generate an mb_reference.

    "auto_add_related_document": "0",
String

[Optional] Send invoice to client after payment. This option is only available for accounts with payment services configurated. Must be a number equal to either "1" or "0".

    "tax_exemption_reason": "M00"
String

[Optional] Used when updating a document and removing all tax exempt items. The code M00 means 'Without tax exemption'.

  }
}

Responses

201 Success

Estimate was created successfully.

Estimates Get
{
  "quote": {
  "quote": { ... }
Object
    "id": 541791,
Integer
    "status": "final",
String
    "archived": false,
Boolean
    "type": "Quote",
String
    "sequence_number": "1/A",
String
    "inverted_sequence_number": "A/1",
String
    "date": "12/06/2017",
String
    "due_date": "12/06/2017",
String
    "reference": "foo",
String
    "observations": "foo",
String
    "retention": "foo",
String
    "permalink": "https://www.app.invoicexpress.com/documents/541791f16ae45a73b703c684a221ef198c10020f3d56a1",
String
    "saft_hash": "NfTN",
String
    "sum": 10,
Integer
    "discount": 0,
Integer
    "before_taxes": 10,
Integer
    "taxes": 2.3,
Number
    "total": 12.3,
Number
    "currency": "Euro",
String
    "client": {
    "client": { ... }
Object
      "id": 1310176,
Integer
      "name": "John",
String
      "country": "Portugal"
String
    },
    items: [
Array
      {
      { ... }
Object

Items

        "name": "iPhone",
String
        "description": "foo",
String
        "unit_price": "10.0",
String
        "unit": "foo",
String
        "quantity": "1.0",
String
        "tax": {
        "tax": { ... }
Object
          "id": 31567,
Integer
          "name": "IVA23",
String
          "value": 23
Integer
        },
        "discount": 0,
Integer
        "subtotal": 10,
Integer
        "tax_amount": 2.3,
Number
        "discount_amount": 0,
Integer
        "total": 12.3
Number
      }
    ]
    "sequence_id": "12345",
String
    "tax_exemption": "M01"
String
  }
}
401 Access denied

The API Key parameter is missing or is incorrectly entered.

(Empty Response)
422 Unprocessable Entity

Some parameters were incorrect.

(Empty Response)

Update

PUT /:document-type/:document-id.json

Updates a quote, proforma or fees_note.

Creating new clients or items along with the estimate

This method also allows to create a new client and/or new items in the same request with the following behavior:

  • If the client name does not exist a new one is created.
  • If items do not exist with the given names, new ones will be created.
  • If item name already exists, the item is updated with the new values.

Taxes

Regarding item taxes, if the tax name is not found, no tax will be applied to that item.
Be careful when updating the document items, any missing items from the original document will be deleted.

Example Body

{
  "quote": {
    "date": "07/05/2017",
    "due_date": "08/05/2017",
    "client": {
      "name": "John",
      "code": "100"
    },
    "items": [
        {
          "name": "Product A",
          "description": "Cleaning product",
          "unit_price": "10.0",
          "quantity": "1.0"
        }
      ]
   }
}

Example Request

Format:
curl --request PUT \
  --url 'https://account_name.app.invoicexpress.com/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE' \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --data '{"quote":{"date":"3/12/2017","due_date":"03/12/2017","reference":"999","observations":"Observations","retention":"0","tax_exemption":"M01","sequence_id":"12345","manual_sequence_number":"1","client":{"name":"Client Name","code":"A1","email":"foo@bar.com","address":"Saldanha","city":"Lisbon","postal_code":"1050-555","country":"Portugal","fiscal_id":"508000000","website":"www.website.com","phone":"910000000","fax":"210000000","observations":"Observations"},"items":[{"name":"Item Name","description":"Item Description","unit_price":"100","quantity":"5","unit":"service","discount":"50","tax":{"name":"IVA23"}}],"mb_reference":"0","auto_add_related_document":"0"}}'
require 'uri'
require 'net/http'

url = URI("https://account_name.app.invoicexpress.com/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["accept"] = 'application/json'
request["content-type"] = 'application/json'
request.body = "{\"quote\":{\"date\":\"3/12/2017\",\"due_date\":\"03/12/2017\",\"reference\":\"999\",\"observations\":\"Observations\",\"retention\":\"0\",\"tax_exemption\":\"M01\",\"sequence_id\":\"12345\",\"manual_sequence_number\":\"1\",\"client\":{\"name\":\"Client Name\",\"code\":\"A1\",\"email\":\"foo@bar.com\",\"address\":\"Saldanha\",\"city\":\"Lisbon\",\"postal_code\":\"1050-555\",\"country\":\"Portugal\",\"fiscal_id\":\"508000000\",\"website\":\"www.website.com\",\"phone\":\"910000000\",\"fax\":\"210000000\",\"observations\":\"Observations\"},\"items\":[{\"name\":\"Item Name\",\"description\":\"Item Description\",\"unit_price\":\"100\",\"quantity\":\"5\",\"unit\":\"service\",\"discount\":\"50\",\"tax\":{\"name\":\"IVA23\"}}],\"mb_reference\":\"0\",\"auto_add_related_document\":\"0\"}}"

response = http.request(request)
puts response.read_body
var http = require("https");

var options = {
  "method": "PUT",
  "hostname": "account_name.app.invoicexpress.com",
  "port": null,
  "path": "/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE",
  "headers": {
    "accept": "application/json",
    "content-type": "application/json"
  }
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(JSON.stringify({ quote: 
   { date: '3/12/2017',
     due_date: '03/12/2017',
     reference: '999',
     observations: 'Observations',
     retention: '0',
     tax_exemption: 'M01',
     sequence_id: '12345',
     manual_sequence_number: '1',
     client: 
      { name: 'Client Name',
        code: 'A1',
        email: 'foo@bar.com',
        address: 'Saldanha',
        city: 'Lisbon',
        postal_code: '1050-555',
        country: 'Portugal',
        fiscal_id: '508000000',
        website: 'www.website.com',
        phone: '910000000',
        fax: '210000000',
        observations: 'Observations' },
     items: 
      [ { name: 'Item Name',
          description: 'Item Description',
          unit_price: '100',
          quantity: '5',
          unit: 'service',
          discount: '50',
          tax: { name: 'IVA23' } } ],
     mb_reference: '0',
     auto_add_related_document: '0' } }));
req.end();
import http.client

conn = http.client.HTTPSConnection("account_name.app.invoicexpress.com")

payload = "{\"quote\":{\"date\":\"3/12/2017\",\"due_date\":\"03/12/2017\",\"reference\":\"999\",\"observations\":\"Observations\",\"retention\":\"0\",\"tax_exemption\":\"M01\",\"sequence_id\":\"12345\",\"manual_sequence_number\":\"1\",\"client\":{\"name\":\"Client Name\",\"code\":\"A1\",\"email\":\"foo@bar.com\",\"address\":\"Saldanha\",\"city\":\"Lisbon\",\"postal_code\":\"1050-555\",\"country\":\"Portugal\",\"fiscal_id\":\"508000000\",\"website\":\"www.website.com\",\"phone\":\"910000000\",\"fax\":\"210000000\",\"observations\":\"Observations\"},\"items\":[{\"name\":\"Item Name\",\"description\":\"Item Description\",\"unit_price\":\"100\",\"quantity\":\"5\",\"unit\":\"service\",\"discount\":\"50\",\"tax\":{\"name\":\"IVA23\"}}],\"mb_reference\":\"0\",\"auto_add_related_document\":\"0\"}}"

headers = {
    'accept': "application/json",
    'content-type': "application/json"
    }

conn.request("PUT", "/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://account_name.app.invoicexpress.com/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"quote\":{\"date\":\"3/12/2017\",\"due_date\":\"03/12/2017\",\"reference\":\"999\",\"observations\":\"Observations\",\"retention\":\"0\",\"tax_exemption\":\"M01\",\"sequence_id\":\"12345\",\"manual_sequence_number\":\"1\",\"client\":{\"name\":\"Client Name\",\"code\":\"A1\",\"email\":\"foo@bar.com\",\"address\":\"Saldanha\",\"city\":\"Lisbon\",\"postal_code\":\"1050-555\",\"country\":\"Portugal\",\"fiscal_id\":\"508000000\",\"website\":\"www.website.com\",\"phone\":\"910000000\",\"fax\":\"210000000\",\"observations\":\"Observations\"},\"items\":[{\"name\":\"Item Name\",\"description\":\"Item Description\",\"unit_price\":\"100\",\"quantity\":\"5\",\"unit\":\"service\",\"discount\":\"50\",\"tax\":{\"name\":\"IVA23\"}}],\"mb_reference\":\"0\",\"auto_add_related_document\":\"0\"}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://account_name.app.invoicexpress.com/:document-type/:document-id.json?api_key=YOUR%20API%20KEY%20HERE"

	payload := strings.NewReader("{\"quote\":{\"date\":\"3/12/2017\",\"due_date\":\"03/12/2017\",\"reference\":\"999\",\"observations\":\"Observations\",\"retention\":\"0\",\"tax_exemption\":\"M01\",\"sequence_id\":\"12345\",\"manual_sequence_number\":\"1\",\"client\":{\"name\":\"Client Name\",\"code\":\"A1\",\"email\":\"foo@bar.com\",\"address\":\"Saldanha\",\"city\":\"Lisbon\",\"postal_code\":\"1050-555\",\"country\":\"Portugal\",\"fiscal_id\":\"508000000\",\"website\":\"www.website.com\",\"phone\":\"910000000\",\"fax\":\"210000000\",\"observations\":\"Observations\"},\"items\":[{\"name\":\"Item Name\",\"description\":\"Item Description\",\"unit_price\":\"100\",\"quantity\":\"5\",\"unit\":\"service\",\"discount\":\"50\",\"tax\":{\"name\":\"IVA23\"}}],\"mb_reference\":\"0\",\"auto_add_related_document\":\"0\"}}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("accept", "application/json")
	req.Header.Add("content-type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}

Path Parameters

Name Type Required Description Example
document-type String Required

The type of document you want to update. For example: quotes, proformas or fees_notes.

quotes
document-id Integer Required

ID of the document to update.

1

Request Body

Name Type Required Description Example
quote Object Required

Estimate data to be updated.

{
  "quote": {
  "quote": { ... }
Object

Replace quote with: proforma or fees_note depending on the type of document you want to create/update.

    "date": "3/12/2017",
String

[Required] The document date. Must be in format dd/mm/yyyy ex.: 03/12/2017. If format is invalid, date will be set to current date.

    "due_date": "03/12/2017",
String

[Required] The document due date. Must be in format dd/mm/yyyy ex.: 03/12/2017. If format is invalid, date will be set to current date.

    "reference": "999",
String

[Optional] The document purchase order reference field.

    "observations": "Observations",
String

[Optional] Document observations, these will be printed with the estimate.

    "retention": "0",
String

[Optional] Withholding tax percentage (%). Must be a number between 0 and 99.99.

    "tax_exemption": "M01",
String

[Required/Optional] Portuguese IVA exemption code. Required for portuguese accounts on invoices with IVA exempt items (0%). Must be one of the following: M01, M02, M03, M04, M05, M06, M07, M08, M09, M10, M11, M12, M13, M14, M15, M16, M99. See the table IVA Exemption Codes for more details.

    "sequence_id": "12345",
String

[Optional] ID of the sequence you want to use with this document. If missing, the default sequence will be used.

    "manual_sequence_number": "1",
String

[Required/Optional] Required for non-portuguese accounts with manual sequence numbering.

    "client": {
    "client": { ... }
Object

[Required] Client details.

      "name": "Client Name",
String

[Required] The document’s client. If the client doesn’t exist, a new one is created. If it exists, the remaining client fields will be ignored.

      "code": "A1",
String

[Required] The client’s unique code. If the client doesn’t exist, a new one is created. If it exists, the remaining client fields will be ignored.

      "email": "foo@bar.com",
String

[Optional] Client email address. Must be a valid email address ex: foo@bar.com

      "address": "Saldanha",
String

[Optional] Client company address.

      "city": "Lisbon",
String

[Optional] Client’s city.

      "postal_code": "1050-555",
String

[Optional] Client’s postal code for it’s company address.

      "country": "Portugal",
String

[Optional] Country, normally used for a company country. Although country is optional, when supplied, it should match one of the country list on the Appendix of this Documentation.

      "fiscal_id": "508000000",
String

[Optional] Client's fiscal ID (Número de Contribuinte).

      "website": "www.website.com",
String

[Optional] Client' website.

      "phone": "910000000",
String

[Optional] Client's phone number.

      "fax": "210000000",
String

[Optional] Client's fax number.

      "observations": "Observations"
String

[Optional] Client's default observations. This is added to the observations field of all the invoices sent to this client.

    },
    items: [
Array

[Required] An array of line items. If items with the given names do not exist, they are created. If an item already exists, it is updated with the new values. At least one is required.

      {
      { ... }
Object

Item Object

        "name": "Item Name",
String

[Required] Name of the item. Must be unique.

        "description": "Item Description",
String

[Required] Item’s description.

        "unit_price": "100",
String

[Required] Item’s unit price. Must be a number equal or greater than 0.0.

        "quantity": "5",
String

[Required] Quantity. Must be a number equal or greater than 0.

        "unit": "service",
String

[Optional] The unit of measure. Ex: hour, day, month, unit , service or other.

        "discount": "50",
String

[Optional] The item discount percentage (%). Defaults to 0.0. Must be a value between 0.0 and 100.0 inclusive.

        "tax": {
        "tax": { ... }
Object

[Optional] The tax applied to the line item. If not present the default tax is applied to the line item.

          "name": "IVA23"
String

[Optional] The tax name to be used on this line item. If not found the default tax is applied to the line item.

        }
      }
    ]
    "mb_reference": "0",
String

[Optional] Generates a Multibanco Reference after you finalize your estimate. This option is only available for Portuguese Accounts. You must have the feature enabled on your account first. Set value to "1" to generate an mb_reference.

    "auto_add_related_document": "0",
String

[Optional] Send invoice to client after payment. This option is only available for accounts with payment services configurated. Must be a number equal to either "1" or "0".

    "tax_exemption_reason": "M00"
String

[Optional] Used when updating a document and removing all tax exempt items. The code M00 means 'Without tax exemption'.

  }
}

Responses

200 Success

Document was updated successfully.

(Empty Response)
401 Access denied

The API Key parameter is missing or is incorrectly entered.

(Empty Response)
404 Not Found

The supplied :document-id doesn’t match any existing document.

(Empty Response)
422 Unprocessable Entity

Some parameters sent were incorrect.

(Empty Response)

Change State

PUT /:document-type/:document-id/change-state.json

Changes the state of a quote, proforma or fees_note.

Possible state transitions:

From To Event
draft final finalized
draft deleted deleted
final accepted accept
final refused refuse
final canceled canceled
accepted refused refuse
refused accepted accept
accepted canceled canceled
refused canceled canceled

Any other transitions will fail.
When cancelling a document you must specify a reason.

Example Body

{
  "quote": {
    "state": "finalized"
  }
}

Example Request

Format:
curl --request PUT \
  --url 'https://account_name.app.invoicexpress.com/:document-type/:document-id/change-state.json?api_key=YOUR%20API%20KEY%20HERE' \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --data '{"quote":{"state":"finalized","message":"Wrong quote totals."}}'
require 'uri'
require 'net/http'

url = URI("https://account_name.app.invoicexpress.com/:document-type/:document-id/change-state.json?api_key=YOUR%20API%20KEY%20HERE")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Put.new(url)
request["accept"] = 'application/json'
request["content-type"] = 'application/json'
request.body = "{\"quote\":{\"state\":\"finalized\",\"message\":\"Wrong quote totals.\"}}"

response = http.request(request)
puts response.read_body
var http = require("https");

var options = {
  "method": "PUT",
  "hostname": "account_name.app.invoicexpress.com",
  "port": null,
  "path": "/:document-type/:document-id/change-state.json?api_key=YOUR%20API%20KEY%20HERE",
  "headers": {
    "accept": "application/json",
    "content-type": "application/json"
  }
};

var req = http.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function () {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });
});

req.write(JSON.stringify({ quote: { state: 'finalized', message: 'Wrong quote totals.' } }));
req.end();
import http.client

conn = http.client.HTTPSConnection("account_name.app.invoicexpress.com")

payload = "{\"quote\":{\"state\":\"finalized\",\"message\":\"Wrong quote totals.\"}}"

headers = {
    'accept': "application/json",
    'content-type': "application/json"
    }

conn.request("PUT", "/:document-type/:document-id/change-state.json?api_key=YOUR%20API%20KEY%20HERE", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://account_name.app.invoicexpress.com/:document-type/:document-id/change-state.json?api_key=YOUR%20API%20KEY%20HERE",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "PUT",
  CURLOPT_POSTFIELDS => "{\"quote\":{\"state\":\"finalized\",\"message\":\"Wrong quote totals.\"}}",
  CURLOPT_HTTPHEADER => array(
    "accept: application/json",
    "content-type: application/json"
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://account_name.app.invoicexpress.com/:document-type/:document-id/change-state.json?api_key=YOUR%20API%20KEY%20HERE"

	payload := strings.NewReader("{\"quote\":{\"state\":\"finalized\",\"message\":\"Wrong quote totals.\"}}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("accept", "application/json")
	req.Header.Add("content-type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}

Path Parameters

Name Type Required Description Example
document-type String Required

The type of document you wish to change state: quotes, proformas or fees_notes.

quotes
document-id Integer Required

ID of the document to change state.

42

Request Body

Name Type Required Description Example
quote Object Required

Document state transition.

{
  "quote": {
  "quote": { ... }
Object

Replace quote with: proforma or fees_note depending on the type of document you want to change state.

    "state": "finalized",
String

[Required] The state the document will be in after the call to this endpoint. Options: finalized, deleted, canceled, accept or refuse.

    "message": "Wrong quote totals."
String

[Required/Optional] Reason for cancelling the document. Only required when state is canceled.

  }
}

Responses

200 Success

Document changed state successfully.

Estimates Get
{
  "quote": {
  "quote": { ... }
Object
    "id": 541791,
Integer
    "status": "final",
String
    "archived": false,
Boolean
    "type": "Quote",
String
    "sequence_number": "1/A",
String
    "inverted_sequence_number": "A/1",
String
    "date": "12/06/2017",
String
    "due_date": "12/06/2017",
String
    "reference": "foo",
String
    "observations": "foo",
String
    "retention": "foo",
String
    "permalink": "https://www.app.invoicexpress.com/documents/541791f16ae45a73b703c684a221ef198c10020f3d56a1",
String
    "saft_hash": "NfTN",
String
    "sum": 10,
Integer
    "discount": 0,
Integer
    "before_taxes": 10,
Integer
    "taxes": 2.3,
Number
    "total": 12.3,
Number
    "currency": "Euro",
String
    "client": {
    "client": { ... }
Object
      "id": 1310176,
Integer
      "name": "John",
String
      "country": "Portugal"
String
    },
    items: [
Array
      {
      { ... }
Object

Items

        "name": "iPhone",
String
        "description": "foo",
String
        "unit_price": "10.0",
String
        "unit": "foo",
String
        "quantity": "1.0",
String
        "tax": {
        "tax": { ... }
Object
          "id": 31567,
Integer
          "name": "IVA23",
String
          "value": 23
Integer
        },
        "discount": 0,
Integer
        "subtotal": 10,
Integer
        "tax_amount": 2.3,
Number
        "discount_amount": 0,
Integer
        "total": 12.3
Number
      }
    ]
    "sequence_id": "12345",
String
    "tax_exemption": "M01"
String
  }
}
401 Access denied

The API Key parameter is missing or is incorrectly entered.

(Empty Response)
404 Not Found

The supplied :document-id doesn’t match any existing document.

(Empty Response)
422 Unprocessable Entity

Some parameters sent were incorrect.

(Empty Response)