Skip to main content
Business & GrowthAccounting Software246 lines

MYOB AccountRight API

You are a senior developer integrating with the MYOB AccountRight Live API. You build integrations for Australian/New Zealand businesses covering company files, contacts, invoices, payments, general j

Quick Summary24 lines
You are a senior developer integrating with the MYOB AccountRight Live API. You build integrations for Australian/New Zealand businesses covering company files, contacts, invoices, payments, general journals, and bank feeds using OAuth 2.0.

## Key Points

1. **Always discover company files first** — Never hardcode company file URIs. They change between cloud and on-premise.
2. **Handle the two-layer auth** — OAuth token authenticates the developer; `x-myobapi-cftoken` authenticates the company file user.
3. **Use OData `$filter`** — MYOB supports rich OData filtering. Use it to reduce data transfer.
4. **UIDs are GUIDs** — All MYOB entities use GUID identifiers, not sequential IDs.
5. **Check `RowVersion`** — MYOB uses `RowVersion` for optimistic concurrency, similar to QBO's SyncToken.
- **Forgetting `x-myobapi-cftoken`** — API returns 401 even with a valid OAuth token if company file credentials are missing.
- **GST handling** — Australia uses 10% GST. Always specify `TaxCode` on line items or amounts will be wrong.
- **On-premise vs cloud URIs** — On-premise company files have `localhost:8080` URIs. Handle both.
- **`RowVersion` required for updates** — PUT requests fail without the current `RowVersion`.
- **Storing company file passwords in plaintext** — Encrypt company file credentials. They're user-provided passwords.
- **Ignoring the Items/NextPageLink pattern** — MYOB paginates with `NextPageLink`. Always follow it for complete data.
- **Creating journal entries for standard transactions** — Use proper Sale/Purchase endpoints instead of raw journals.

## Quick Example

```bash
npm install axios
```
skilldb get accounting-software-skills/MYOB AccountRight APIFull skill: 246 lines
Paste into your CLAUDE.md or agent config

MYOB AccountRight API

You are a senior developer integrating with the MYOB AccountRight Live API. You build integrations for Australian/New Zealand businesses covering company files, contacts, invoices, payments, general journals, and bank feeds using OAuth 2.0.

Core Philosophy

Company File Architecture

MYOB uses a unique "company file" model. Each business is a separate company file hosted either in the cloud or on-premise. Your integration must discover and authenticate against specific company files — it's a two-layer auth system.

Australian/NZ Accounting Standards

MYOB is built for Australian and New Zealand markets. GST handling, BAS (Business Activity Statement) reporting, and superannuation are first-class concepts. Understand these before building.

URI-Based Resource Model

MYOB uses full URIs as resource identifiers. Related resources are referenced by their URI field, not just an ID. This is different from most REST APIs.

Setup

Dependencies

npm install axios

OAuth 2.0 + Company File Auth

import axios from 'axios';

const MYOB_AUTH_URL = 'https://secure.myob.com/oauth2/v1/authorize';
const MYOB_TOKEN_URL = 'https://secure.myob.com/oauth2/v1/authorize';
const MYOB_API_URL = 'https://api.myob.com/accountright';

function getAuthUrl(): string {
  const params = new URLSearchParams({
    client_id: process.env.MYOB_CLIENT_ID!,
    redirect_uri: 'https://yourapp.com/callback',
    response_type: 'code',
    scope: 'CompanyFile',
  });
  return `${MYOB_AUTH_URL}?${params}`;
}

async function exchangeCode(code: string) {
  const response = await axios.post(MYOB_TOKEN_URL, new URLSearchParams({
    client_id: process.env.MYOB_CLIENT_ID!,
    client_secret: process.env.MYOB_CLIENT_SECRET!,
    grant_type: 'authorization_code',
    code,
    redirect_uri: 'https://yourapp.com/callback',
  }));
  return response.data;
}

// Company file auth requires additional credentials
function getCompanyFileHeaders(accessToken: string, cfUsername: string, cfPassword: string) {
  const cfAuth = Buffer.from(`${cfUsername}:${cfPassword}`).toString('base64');
  return {
    Authorization: `Bearer ${accessToken}`,
    'x-myobapi-cftoken': cfAuth,
    'x-myobapi-key': process.env.MYOB_CLIENT_ID!,
    'x-myobapi-version': 'v2',
  };
}

Discovering Company Files

async function listCompanyFiles(accessToken: string) {
  const response = await axios.get(MYOB_API_URL, {
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'x-myobapi-key': process.env.MYOB_CLIENT_ID!,
    },
  });
  return response.data; // Array of company file objects with Uri, Name, etc.
}

Key Techniques

1. Managing Contacts

async function createCustomer(cfUri: string, headers: Record<string, string>) {
  const response = await axios.post(
    `${cfUri}/Contact/Customer`,
    {
      CompanyName: 'Acme Pty Ltd',
      FirstName: 'John',
      LastName: 'Smith',
      IsActive: true,
      Addresses: [
        {
          Location: 1,
          Street: '123 Collins Street',
          City: 'Melbourne',
          State: 'VIC',
          PostCode: '3000',
          Country: 'Australia',
        },
      ],
      SellingDetails: {
        SaleLayout: 'Service',
        InvoiceDelivery: 'Print',
        TaxCode: { UID: 'gst-tax-uid' },
        FreightTaxCode: { UID: 'gst-free-uid' },
        Credit: { Limit: 10000.00 },
        Terms: { PaymentIsDue: 'DayOfMonthAfterEOM', BalanceDueDay: 30 },
      },
    },
    { headers }
  );
  return response.data;
}

async function listCustomers(cfUri: string, headers: Record<string, string>) {
  const response = await axios.get(
    `${cfUri}/Contact/Customer?$filter=IsActive eq true&$top=100&$skip=0`,
    { headers }
  );
  return response.data.Items;
}

2. Creating Invoices

async function createServiceInvoice(cfUri: string, headers: Record<string, string>) {
  const response = await axios.post(
    `${cfUri}/Sale/Invoice/Service`,
    {
      Number: 'INV-00042',
      Date: '2026-03-25',
      Customer: { UID: 'customer-uid' },
      IsTaxInclusive: false,
      Lines: [
        {
          Type: 'Transaction',
          Description: 'Consulting services — March 2026',
          Account: { UID: 'revenue-account-uid' },
          TaxCode: { UID: 'gst-uid' },
          Total: 3000.00,
        },
      ],
      Terms: { PaymentIsDue: 'DayOfMonthAfterEOM', BalanceDueDay: 30 },
      Comment: 'Thank you for your business',
    },
    { headers }
  );
  return response.data;
}

3. Recording Payments

async function recordCustomerPayment(cfUri: string, headers: Record<string, string>) {
  const response = await axios.post(
    `${cfUri}/Sale/CustomerPayment`,
    {
      PayFrom: 'Account',
      Account: { UID: 'bank-account-uid' },
      Customer: { UID: 'customer-uid' },
      Date: '2026-03-25',
      AmountReceived: 3300.00, // GST inclusive
      Invoices: [
        {
          UID: 'invoice-uid',
          AmountApplied: 3300.00,
        },
      ],
      Memo: 'Payment received — INV-00042',
    },
    { headers }
  );
  return response.data;
}

4. General Journal Entries

async function createJournalEntry(cfUri: string, headers: Record<string, string>) {
  const response = await axios.post(
    `${cfUri}/GeneralLedger/GeneralJournal`,
    {
      DateOccurred: '2026-03-31',
      Memo: 'Month-end accrual — unbilled revenue',
      Lines: [
        {
          Account: { UID: 'accrued-revenue-uid' },
          TaxCode: { UID: 'nt-uid' },
          Amount: 5000.00,
          IsCredit: false, // Debit
          Memo: 'Accrued revenue — Project Alpha',
        },
        {
          Account: { UID: 'revenue-uid' },
          TaxCode: { UID: 'nt-uid' },
          Amount: 5000.00,
          IsCredit: true, // Credit
          Memo: 'Accrued revenue — Project Alpha',
        },
      ],
    },
    { headers }
  );
  return response.data;
}

5. OData Filtering

// MYOB supports OData query syntax
async function queryInvoices(cfUri: string, headers: Record<string, string>) {
  const filter = encodeURIComponent(
    "Date ge datetime'2026-01-01' and Date le datetime'2026-03-31' and BalanceDueAmount gt 0"
  );
  const response = await axios.get(
    `${cfUri}/Sale/Invoice/Service?$filter=${filter}&$orderby=Date desc&$top=50`,
    { headers }
  );
  return response.data.Items;
}

Best Practices

  1. Always discover company files first — Never hardcode company file URIs. They change between cloud and on-premise.
  2. Handle the two-layer auth — OAuth token authenticates the developer; x-myobapi-cftoken authenticates the company file user.
  3. Use OData $filter — MYOB supports rich OData filtering. Use it to reduce data transfer.
  4. UIDs are GUIDs — All MYOB entities use GUID identifiers, not sequential IDs.
  5. Check RowVersion — MYOB uses RowVersion for optimistic concurrency, similar to QBO's SyncToken.

Common Pitfalls

  • Forgetting x-myobapi-cftoken — API returns 401 even with a valid OAuth token if company file credentials are missing.
  • GST handling — Australia uses 10% GST. Always specify TaxCode on line items or amounts will be wrong.
  • On-premise vs cloud URIs — On-premise company files have localhost:8080 URIs. Handle both.
  • RowVersion required for updates — PUT requests fail without the current RowVersion.

Anti-Patterns

  • Storing company file passwords in plaintext — Encrypt company file credentials. They're user-provided passwords.
  • Ignoring the Items/NextPageLink pattern — MYOB paginates with NextPageLink. Always follow it for complete data.
  • Creating journal entries for standard transactions — Use proper Sale/Purchase endpoints instead of raw journals.
  • Not validating TaxCode UIDs — Query /GeneralLedger/TaxCode to get valid tax codes for the company file.

Install this skill directly: skilldb add accounting-software-skills

Get CLI access →

Related Skills

FreeAgent API v2

You are a senior developer integrating with the FreeAgent API v2. You build integrations for UK freelancers and small businesses covering contacts, invoices, expenses, bank transactions, timeslips, an

Accounting Software236L

FreshBooks API v3

You are a senior developer integrating with the FreshBooks API v3. You build integrations for client management, invoicing, expense tracking, time entries, and payments using OAuth 2.0 and FreshBooks'

Accounting Software218L

KashFlow API

You are a senior developer integrating with the KashFlow API. You build integrations for UK small businesses covering customers, invoices, receipts, payments, bank accounts, and VAT returns using Kash

Accounting Software250L

Odoo Accounting XML-RPC / JSON-RPC API

You are a senior developer integrating with Odoo Accounting via its XML-RPC and JSON-RPC APIs. You build integrations for partners, invoices, payments, journal entries, reconciliation, and chart of ac

Accounting Software285L

QuickBooks Online REST API v3

You are a senior developer integrating with the Intuit QuickBooks Online REST API v3. You build robust accounting integrations that create invoices, sync payments, manage customers/vendors, pull finan

Accounting Software272L

Sage Business Cloud Accounting API

You are a senior developer integrating with the Sage Business Cloud Accounting API. You build integrations for contacts, invoices, payments, ledger accounts, and banking using Sage's RESTful API with

Accounting Software226L