curl --request POST \
--url https://anzapi.onboardme.app/api/v1/bills \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--data '
{
"entityKey": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"billDate": "2026-07-18",
"dueDate": "2026-08-01",
"billDetails": "Advisory work — July",
"sendBill": true,
"syncNow": false,
"lineItems": [
{
"amount": 1000,
"taxPercent": 10,
"narration": "Consulting",
"extAccountID": 42,
"extTaxID": 15
}
]
}
'import requests
url = "https://anzapi.onboardme.app/api/v1/bills"
payload = {
"entityKey": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"billDate": "2026-07-18",
"dueDate": "2026-08-01",
"billDetails": "Advisory work — July",
"sendBill": True,
"syncNow": False,
"lineItems": [
{
"amount": 1000,
"taxPercent": 10,
"narration": "Consulting",
"extAccountID": 42,
"extTaxID": 15
}
]
}
headers = {
"Authorization": "Basic <encoded-value>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Basic <encoded-value>', 'Content-Type': 'application/json'},
body: JSON.stringify({
entityKey: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
billDate: '2026-07-18',
dueDate: '2026-08-01',
billDetails: 'Advisory work — July',
sendBill: true,
syncNow: false,
lineItems: [
{
amount: 1000,
taxPercent: 10,
narration: 'Consulting',
extAccountID: 42,
extTaxID: 15
}
]
})
};
fetch('https://anzapi.onboardme.app/api/v1/bills', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://anzapi.onboardme.app/api/v1/bills",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'entityKey' => 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
'billDate' => '2026-07-18',
'dueDate' => '2026-08-01',
'billDetails' => 'Advisory work — July',
'sendBill' => true,
'syncNow' => false,
'lineItems' => [
[
'amount' => 1000,
'taxPercent' => 10,
'narration' => 'Consulting',
'extAccountID' => 42,
'extTaxID' => 15
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"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"
)
func main() {
url := "https://anzapi.onboardme.app/api/v1/bills"
payload := strings.NewReader("{\n \"entityKey\": \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n \"billDate\": \"2026-07-18\",\n \"dueDate\": \"2026-08-01\",\n \"billDetails\": \"Advisory work — July\",\n \"sendBill\": true,\n \"syncNow\": false,\n \"lineItems\": [\n {\n \"amount\": 1000,\n \"taxPercent\": 10,\n \"narration\": \"Consulting\",\n \"extAccountID\": 42,\n \"extTaxID\": 15\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://anzapi.onboardme.app/api/v1/bills")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"entityKey\": \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n \"billDate\": \"2026-07-18\",\n \"dueDate\": \"2026-08-01\",\n \"billDetails\": \"Advisory work — July\",\n \"sendBill\": true,\n \"syncNow\": false,\n \"lineItems\": [\n {\n \"amount\": 1000,\n \"taxPercent\": 10,\n \"narration\": \"Consulting\",\n \"extAccountID\": 42,\n \"extTaxID\": 15\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://anzapi.onboardme.app/api/v1/bills")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic <encoded-value>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"entityKey\": \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n \"billDate\": \"2026-07-18\",\n \"dueDate\": \"2026-08-01\",\n \"billDetails\": \"Advisory work — July\",\n \"sendBill\": true,\n \"syncNow\": false,\n \"lineItems\": [\n {\n \"amount\": 1000,\n \"taxPercent\": 10,\n \"narration\": \"Consulting\",\n \"extAccountID\": 42,\n \"extTaxID\": 15\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"billingID": 123,
"engagementID": 123,
"engagementName": "<string>",
"engagementStatusID": 123,
"isEngagementFinalised": true,
"entityID": 123,
"isOnboardingEntity": true,
"entityName": "<string>",
"billDate": "2023-12-25",
"dueDate": "2023-12-25",
"billNumber": "<string>",
"billAmount": 123,
"billTax": 123,
"billTotal": 123,
"billDetails": "<string>",
"currencyID": 123,
"paymentTotal": 123,
"refNo": "<string>",
"billNow": 123,
"syncNow": true,
"sendBill": true,
"billPercent": 123,
"packageNumber": 123,
"invoiceStatus": "<string>",
"externalID": "<string>",
"externalNumber": "<string>",
"externalURL": "<string>",
"syncAttemptCount": 123,
"syncFailedReason": "<string>",
"brandingThemeID": "<string>",
"createdOn": "2023-11-07T05:31:56Z",
"updatedOn": "2023-11-07T05:31:56Z",
"cancelledOn": "2023-11-07T05:31:56Z",
"lineItems": [
{
"billingDetailID": 123,
"billAmount": 123,
"billTax": 123,
"billTotal": 123,
"narration": "<string>",
"extItemID": 123,
"extAccountID": 123,
"extTaxID": 123,
"fieldOne": "<string>",
"fieldTwo": "<string>",
"orderID": 123,
"serviceID": 123
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}Create a bill
Creates an adhoc bill for a real Active client entity. Requires write access.
Bills are not linked to proposals/engagements and not linked to onboarding entities.
entityKey must come from GET /api/v1/entities (Active client only — not a lead).
Does not push to Xero. Flags sendBill and syncNow are stored for later ledger sync / email behaviour.
Amounts are tax-exclusive: each line needs amount plus either taxAmount or taxPercent (server computes tax). Header totals are summed from lines.
When Xero is connected (GET /api/v1/bills/ledger/status):
- each line needs
extAccountIDorextItemID - each line needs
extTaxID, or ataxPercentthat matches a selected tax rate (±0.02%) - use catalog endpoints under
/api/v1/bills/ledger/…
201: Created bill detail (same shape as load).
403: API client is read-only.
404: Entity not found.
429: Rate limit exceeded.
curl --request POST \
--url https://anzapi.onboardme.app/api/v1/bills \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--data '
{
"entityKey": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"billDate": "2026-07-18",
"dueDate": "2026-08-01",
"billDetails": "Advisory work — July",
"sendBill": true,
"syncNow": false,
"lineItems": [
{
"amount": 1000,
"taxPercent": 10,
"narration": "Consulting",
"extAccountID": 42,
"extTaxID": 15
}
]
}
'import requests
url = "https://anzapi.onboardme.app/api/v1/bills"
payload = {
"entityKey": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"billDate": "2026-07-18",
"dueDate": "2026-08-01",
"billDetails": "Advisory work — July",
"sendBill": True,
"syncNow": False,
"lineItems": [
{
"amount": 1000,
"taxPercent": 10,
"narration": "Consulting",
"extAccountID": 42,
"extTaxID": 15
}
]
}
headers = {
"Authorization": "Basic <encoded-value>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Basic <encoded-value>', 'Content-Type': 'application/json'},
body: JSON.stringify({
entityKey: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
billDate: '2026-07-18',
dueDate: '2026-08-01',
billDetails: 'Advisory work — July',
sendBill: true,
syncNow: false,
lineItems: [
{
amount: 1000,
taxPercent: 10,
narration: 'Consulting',
extAccountID: 42,
extTaxID: 15
}
]
})
};
fetch('https://anzapi.onboardme.app/api/v1/bills', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://anzapi.onboardme.app/api/v1/bills",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'entityKey' => 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
'billDate' => '2026-07-18',
'dueDate' => '2026-08-01',
'billDetails' => 'Advisory work — July',
'sendBill' => true,
'syncNow' => false,
'lineItems' => [
[
'amount' => 1000,
'taxPercent' => 10,
'narration' => 'Consulting',
'extAccountID' => 42,
'extTaxID' => 15
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"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"
)
func main() {
url := "https://anzapi.onboardme.app/api/v1/bills"
payload := strings.NewReader("{\n \"entityKey\": \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n \"billDate\": \"2026-07-18\",\n \"dueDate\": \"2026-08-01\",\n \"billDetails\": \"Advisory work — July\",\n \"sendBill\": true,\n \"syncNow\": false,\n \"lineItems\": [\n {\n \"amount\": 1000,\n \"taxPercent\": 10,\n \"narration\": \"Consulting\",\n \"extAccountID\": 42,\n \"extTaxID\": 15\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Basic <encoded-value>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://anzapi.onboardme.app/api/v1/bills")
.header("Authorization", "Basic <encoded-value>")
.header("Content-Type", "application/json")
.body("{\n \"entityKey\": \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n \"billDate\": \"2026-07-18\",\n \"dueDate\": \"2026-08-01\",\n \"billDetails\": \"Advisory work — July\",\n \"sendBill\": true,\n \"syncNow\": false,\n \"lineItems\": [\n {\n \"amount\": 1000,\n \"taxPercent\": 10,\n \"narration\": \"Consulting\",\n \"extAccountID\": 42,\n \"extTaxID\": 15\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://anzapi.onboardme.app/api/v1/bills")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic <encoded-value>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"entityKey\": \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n \"billDate\": \"2026-07-18\",\n \"dueDate\": \"2026-08-01\",\n \"billDetails\": \"Advisory work — July\",\n \"sendBill\": true,\n \"syncNow\": false,\n \"lineItems\": [\n {\n \"amount\": 1000,\n \"taxPercent\": 10,\n \"narration\": \"Consulting\",\n \"extAccountID\": 42,\n \"extTaxID\": 15\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"billingID": 123,
"engagementID": 123,
"engagementName": "<string>",
"engagementStatusID": 123,
"isEngagementFinalised": true,
"entityID": 123,
"isOnboardingEntity": true,
"entityName": "<string>",
"billDate": "2023-12-25",
"dueDate": "2023-12-25",
"billNumber": "<string>",
"billAmount": 123,
"billTax": 123,
"billTotal": 123,
"billDetails": "<string>",
"currencyID": 123,
"paymentTotal": 123,
"refNo": "<string>",
"billNow": 123,
"syncNow": true,
"sendBill": true,
"billPercent": 123,
"packageNumber": 123,
"invoiceStatus": "<string>",
"externalID": "<string>",
"externalNumber": "<string>",
"externalURL": "<string>",
"syncAttemptCount": 123,
"syncFailedReason": "<string>",
"brandingThemeID": "<string>",
"createdOn": "2023-11-07T05:31:56Z",
"updatedOn": "2023-11-07T05:31:56Z",
"cancelledOn": "2023-11-07T05:31:56Z",
"lineItems": [
{
"billingDetailID": 123,
"billAmount": 123,
"billTax": 123,
"billTotal": 123,
"narration": "<string>",
"extItemID": 123,
"extAccountID": 123,
"extTaxID": 123,
"fieldOne": "<string>",
"fieldTwo": "<string>",
"orderID": 123,
"serviceID": 123
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>"
}Authorizations
Swagger / Postman only: Client ID as username, Client secret as password. In Postman, set this once on the collection (Authorization → Basic Auth) so all requests inherit. For production server-to-server code, prefer X-OM-Auth-ID and X-OM-Auth-Key headers.
Body
Response
Created
Show child attributes
Show child attributes