Create a bill
/partners/billsCreates a new vendor bill (draft by default, or approved for migrations).
Required: exactly one of vendorUuid OR inline vendor object, date, dueDate, and lineItems with categoryAccountUuid, quantity, and price. Optional approvalStatus (draft | approved). Inline vendors are echoed on the response as _partnerInlineCreated.
Request body
vendorUuiduuidExisting vendor UUID from the Vendors API. Mutually exclusive with vendor.
vendorobjectInline vendor to create when vendorUuid is omitted.
namestringVendor display name (or use vendor field alias).
emailstringOptional vendor email.
datedaterequiredBill date (ISO, YYYY-MM-DD).
dueDatedaterequiredDue date (ISO, YYYY-MM-DD).
lineItemsarrayrequiredExpense lines on the bill.
categoryAccountUuiduuidrequiredExpense account UUID from Chart of Accounts.
descriptionstringLine description.
quantitynumberrequiredQuantity.
pricenumberrequiredUnit price.
projectUuiduuidOptional project UUID on the line.
customerUuiduuidOptional customer UUID for billable expenses.
billNumberstringCustom bill number. Auto-assigned when omitted.
purchaseOrderNumberstringPurchase order reference.
notesstringFree-text notes.
currencystringISO 4217 currency. Defaults to workspace currency.
tagUuidsarrayTag UUIDs from the Tags API.
projectUuiduuidBill-level project UUID.
approvalStatusenumDraft (default) or approved — approved posts A/P journals immediately (migration use case).
One of: draft, approved
attachmentsarrayAttachments by public URL.
urlstringrequiredPublic file URL.
titlestringDisplay title.
Responses
201Bill created in draft.400Validation failed — missing required fields or invalid UUID references.401Missing or invalid HMAC signature, expired timestamp, or invalid Bearer token. Troubleshoot403The credential does not have access to this workspace or resource. Troubleshoot429Rate limit exceeded (100 requests per minute per clientId). Retry after the Retry-After header. Troubleshoothttps://api.getcount.com/partners/billsimport crypto from 'node:crypto';
const BASE_URL = 'https://api.getcount.com';
const CLIENT_ID = process.env.COUNT_CLIENT_ID;
const CLIENT_SECRET = process.env.COUNT_CLIENT_SECRET;
const ACCESS_TOKEN = process.env.COUNT_ACCESS_TOKEN;
const method = 'POST';
const signingPath = '/bills';
const timestamp = Math.floor(Date.now() / 1000).toString();
const body = {
"vendorUuid": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
"date": "2026-01-15",
"dueDate": "2026-02-15",
"lineItems": [
{
"categoryAccountUuid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"description": "Office supplies",
"quantity": 1,
"price": 250
}
],
"notes": "Q1 office supplies"
};
const bodyString = JSON.stringify(body);
const bodyHash = crypto.createHash('sha256').update(bodyString).digest('hex');
const baseString = `${method}:${signingPath}:${timestamp}:${bodyHash}`;
const signature = crypto.createHmac('sha256', CLIENT_SECRET).update(baseString).digest('hex');
const response = await fetch(`${BASE_URL}/partners/bills`, {
method,
headers: {
'x-client-id': CLIENT_ID,
'x-timestamp': timestamp,
'x-signature': signature,
'Content-Type': 'application/json',
Authorization: `Bearer ${ACCESS_TOKEN}`,
},
body: bodyString,
});
console.log(await response.json());{
"id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"billNumber": "BILL-1043",
"billType": "bill",
"date": "2026-01-15",
"dueDate": "2026-02-15",
"currency": "USD",
"approvalStatus": "draft",
"status": "draft",
"total": 250,
"paidAmount": 0,
"amountDue": 250,
"notes": "Office supplies for Q1",
"purchaseOrderNumber": null,
"isDeleted": false,
"vendor": {
"id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
"name": "Office Depot",
"email": "ap@officedepot.example"
},
"lineItems": [
{
"id": "a4b5c6d7-e8f9-0123-abcd-456789012345",
"description": "Office supplies",
"quantity": 1,
"price": 250,
"total": 250,
"categoryAccountUuid": "c3d4e5f6-a7b8-9012-cdef-123456789012"
}
],
"transactions": [],
"appliedVendorMemos": [],
"tagUuids": [],
"createdAt": "2026-01-15T10:30:00.000Z",
"updatedAt": "2026-01-28T14:22:30.000Z"
}