Bukku Integration #
Bukku is a Malaysian cloud accounting platform. tofu connects to Bukku using an API Access Token and Company Subdomain — there is no OAuth redirect flow.
tofu reads accounting reference data (chart of accounts, contacts, tax rates, and similar settings) and publishes documents back to Bukku: AR invoices (sales/invoices), AP bills (purchases/bills), and direct expenses as payment vouchers (banking/expenses). Publishing is gated by the can_publish capability.
Bukku has no in-place update API in this integration, so republishing an already-published document uses delete-before-publish: tofu deletes (draft) or voids (committed) the existing Bukku document, then creates it again. Because publish is not auto-on, a user can edit an extraction after its Bukku document is paid — so deleting a paid/submitted document is blocked with a “please verify the extraction” message.
Prerequisites #
Before a customer can connect Bukku, confirm the following:
| Requirement | Details |
|---|---|
| Bukku account | Active Bukku company with API access enabled |
| Admin access in Bukku | User can open Control Panel → Integrations → API Access |
| Entity permissions | User has entity-level integration write permission |
| No existing accounting integration | Each entity supports one accounting integration at a time |
Get Bukku API Credentials #
The customer (or support on their behalf) must collect two values from Bukku:
1. Access Token #
- Log in to Bukku.
- Open Control Panel → Integrations → API Access.
- If API Access is disabled, turn it on and save.
- Copy the Access Token (treat it like a password — do not share in chat or email).
2. Company Subdomain #
The subdomain is the prefix in the Bukku company URL:
https://{subdomain}.bukku.my
Example: if the URL is https://acme.bukku.my, the subdomain is acme.
Note: Enter only the subdomain prefix (
acme), not the full URL or domain suffix.
Official Bukku API reference #
Connect Bukku in tofu #
- In tofu, select the target entity.
- Go to Entity Settings → Integrations.
- Click Add integration and choose Bukku.
- Enter:
- Access Token — from Bukku Control Panel
- Company Subdomain — from the Bukku URL prefix
- Click Connect.
On success:
- tofu validates credentials against Bukku (
GET /contactswithAuthorization: Bearer <token>andCompany-Subdomain: <subdomain>). - A new integration record is created in PENDING status.
- The connected company subdomain (and base currency when available) is shown in the setup dialog.
Activate the Integration #
After connecting, the integration remains PENDING until activated:
- Review the connected company subdomain shown in the Bukku dialog.
- Click Activate.
Activation marks the integration ACTIVE and completes setup for the entity. At this stage, accounting sync capabilities are still being implemented on the Bukku connector; the UI may show read-only notices for some extraction-type settings.
Landing Status on Publish #
AP bills and AR invoices carry a per-entity landing status, set per document type in the Bukku dialog (Entity Settings → Integrations → Bukku → AP Bills / AR Invoices). It maps onto Bukku’s three save states:
| tofu setting | Bukku status | Effect |
|---|---|---|
| Draft | draft |
Lands unposted; the user commits it in Bukku |
| Pending Approval | pending_approval |
Enters Bukku’s approval queue |
| Ready | ready |
Committed on arrival — no second approval step |
The setting is stored on the entity (accounting_invoice_status_on_publish for bills,
ar_invoices_accounting_invoice_status_on_publish for AR invoices) and is applied by
bonsai-accounting-sync only for providers where
IntegrationProvider::supports_status_on_publish is true (Xero and Bukku).
An entity that never chose a status publishes as Draft. Bukku returns Draft from
IntegrationProvider::default_invoice_status_on_publish, which takes priority over the
legacy accounting_invoice_status_on_verify fallback that Xero still uses. That column
defaults to SUBMITTED, so without the Bukku-specific default every existing entity
would have started committing its bills the day this shipped. Opting in is deliberate:
the status only changes once someone picks one in the dialog.
Direct expenses have no such setting — accounting-sync hardcodes them to Authorized
for every provider, which Bukku publishes as ready. Credit notes have none either,
because Bukku lacks the can_publish_credit_note capability.
Publishing as ready interacts with delete-before-publish: a committed document cannot
be deleted, so republishing voids it and creates a replacement. Entities that edit
after publishing will accumulate voided documents in Bukku.
Managing the Connection #
| Action | Steps |
|---|---|
| View status | Entity Settings → Integrations → Bukku |
| Deactivate | Open the Bukku integration dialog → Deactivate |
| Reconnect | Deactivate, then add Bukku again with fresh credentials |
| Change company | Deactivate and connect with the other Bukku company’s subdomain and token |
Capabilities and Limitations #
| Capability | Supported |
|---|---|
| API-key authentication | Yes |
| OAuth sign-in | No |
| Read accounting reference data | Yes |
| Publish AR invoices / AP bills to Bukku | Yes |
| Publish direct expenses (payment vouchers) | Yes |
| Update in place | No — republish uses delete-before-publish |
| Attachment upload on publish | Yes — max 10 MB per file. Multi-page documents over the limit are split into several ≤10 MB PDFs by the page-collection pipeline and uploaded as separate attachments; a single file that still exceeds 10 MB is rejected with an error |
| Create contacts (suppliers/customers) | Yes |
| Multiple accounting integrations per entity | No |
| Self-prompt knowledge setup (AP bill, AR invoice, direct expense) | Available during activation flow when enabled for the entity |
Troubleshooting #
“Access Token is required” / “Company Subdomain is required” #
- Cause: One or both fields were left empty.
- Fix: Enter both values before clicking Connect.
“Failed to connect Bukku integration” / invalid credentials #
- Cause: Token is wrong, expired, or revoked; subdomain does not match the token’s company; API Access is disabled in Bukku.
- Fix:
- Regenerate the token in Bukku Control Panel → Integrations → API Access.
- Confirm the subdomain matches the Bukku login URL prefix exactly.
- Retry Connect.
Cannot add Bukku — another accounting integration exists #
- Cause: The entity already has an active accounting integration (Xero, QBO, Zoho, etc.).
- Fix: Deactivate the existing accounting integration first, then add Bukku.
Activate button is disabled #
- Cause: Connect step did not complete or subdomain metadata is missing.
- Fix: Complete Connect successfully and confirm the connected company subdomain is displayed.
API Reference (Internal) #
For programmatic connection details, see Integration APIs.
Provider code: BUKKU
Create integration:
POST /api/v1/integrations/api-key?entity_id={entity_id}
{
"provider": "BUKKU",
"credentials": {
"access_token": "<bukku-access-token>",
"subdomain": "<company-subdomain>"
}
}
Activate integration:
PUT /api/v1/integrations/{integrationId}?entity_id={entity_id}
{
"status": "PENDING",
"public_metadata": {
"provider": "BUKKU",
"subdomain": "<company-subdomain>"
}
}