Bukku Integration

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
Tofu organization access bukku_integration feature enabled for the organization
Entity permissions User has entity-level integration write permission
No existing accounting integration Each entity supports one accounting integration at a time

Enable the Feature Flag #

Bukku is gated behind the bukku_integration canary feature flag. Without it, Bukku does not appear in the integration picker.

  1. Sign in to Tofu as an organization admin.
  2. Open Organization Settings → Features.
  3. Enable Bukku Integration.
  4. Confirm the integration card appears under Entity Settings → Integrations → Add integration.

For flag configuration details, see Feature Flags.

Get Bukku API Credentials #

The customer (or support on their behalf) must collect two values from Bukku:

1. Access Token #

  1. Log in to Bukku.
  2. Open Control Panel → Integrations → API Access.
  3. If API Access is disabled, turn it on and save.
  4. 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 #

  1. In Tofu, select the target entity.
  2. Go to Entity Settings → Integrations.
  3. Click Add integration and choose Bukku.
  4. Enter:
    • Access Token — from Bukku Control Panel
    • Company Subdomain — from the Bukku URL prefix
  5. Click Connect.

On success:

  • Tofu validates credentials against Bukku (GET /contacts with Authorization: Bearer <token> and Company-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:

  1. Review the connected company subdomain shown in the Bukku dialog.
  2. 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.

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 #

Bukku does not appear in Add integration #

  • Cause: bukku_integration feature flag is disabled for the organization.
  • Fix: Enable Bukku Integration under Organization Settings → Features.

“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:
    1. Regenerate the token in Bukku Control Panel → Integrations → API Access.
    2. Confirm the subdomain matches the Bukku login URL prefix exactly.
    3. 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>"
  }
}