API Reference

Accounts

External CRUD for billing accounts and account addresses.

Accounts

Prefix: /api/v1/external/accounts

See Overview for authentication, pagination, and errors.

These APIs manage the billing Account object (account__m) and billing AccountAddress (accountaddress__m). They are distinct from CPQ account-address APIs.

Endpoint summary

MethodPath
GET/accounts
GET/accounts/{accountId}
GET/accounts/{accountId}?isExternal=true
GET/accounts/by-external-id/{externalId}
POST/accounts
PUT/accounts/{accountId}
PUT/accounts/{accountId}/activate
PUT/accounts/{accountId}/deactivate
PUT/accounts/{accountId}/tax-labels
DELETE/accounts/{accountId}
GET/accounts/{accountId}/addresses
GET/accounts/{accountId}/addresses/{addressId}
POST/accounts/{accountId}/addresses
PUT/accounts/{accountId}/addresses/{addressId}
DELETE/accounts/{accountId}/addresses/{addressId}

Account CRUD

List accounts

GET /api/v1/external/accounts?page=0&size=20&q=acme
Authorization: Bearer YOUR_API_TOKEN
QueryDescription
page0-based page index (default 0)
sizePage size (default 20, max 20)
qOptional search on name, number, externalId

List rows are account headers only (no nested addresses). Envelope, Spring Page, PascalCase keys, and __r objects are described on Overview.

Response 200

{
  "requestId": "req-1",
  "success": true,
  "status": 200,
  "errors": [],
  "data": {
    "content": [
      {
        "__type__": "Account",
        "Id": "11111111-1111-1111-1111-111111111111",
        "Name": "Acme Corp",
        "Number": "ACC-1001",
        "ExternalId": "CRM-55",
        "IsMaster": true,
        "BillingDay": 1,
        "Status": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
        "Status__r": { "Name": "Active" },
        "ApprovalStatus": "fe07e71d-cba4-4316-9c7c-4935c3adec34",
        "ApprovalStatus__r": { "Name": "Approved" }
      }
    ],
    "totalElements": 1,
    "totalPages": 1,
    "size": 20,
    "number": 0,
    "first": true,
    "last": true,
    "empty": false
  }
}

Get account

GET /api/v1/external/accounts/{accountId}
GET /api/v1/external/accounts/{accountId}?isExternal=true
Authorization: Bearer YOUR_API_TOKEN
QueryDescription
isExternalfalse (default): {accountId} is the M360 account UUID. true: {accountId} is the account externalId (same lookup as GET /accounts/by-external-id/{externalId}).

Returns the same PascalCase + __r row as list (no nested addresses). Use GET /accounts/{id}/addresses for addresses. 404 if the account is missing.

Response 200

{
  "requestId": "req-1",
  "success": true,
  "status": 200,
  "errors": [],
  "data": {
    "__type__": "Account",
    "Id": "11111111-1111-1111-1111-111111111111",
    "Name": "Acme Corp",
    "Number": "ACC-1001",
    "ExternalId": "CRM-55",
    "BillingDay": 1,
    "IsMaster": true,
    "Status": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
    "Status__r": { "Name": "Active" },
    "ApprovalStatus": "fe07e71d-cba4-4316-9c7c-4935c3adec34",
    "ApprovalStatus__r": { "Name": "Approved" }
  }
}

Activate / deactivate / tax labels

PUT /api/v1/external/accounts/{accountId}/activate
PUT /api/v1/external/accounts/{accountId}/deactivate
PUT /api/v1/external/accounts/{accountId}/tax-labels

Activate and deactivate set account status to Active / Inactive and return the GET row. Tax labels body: { "gst": "...", "pan": "...", "cin": "..." } (GST/PAN/CIN aliases accepted). Nested contactInfoList and accountPaymentProfileList are accepted on create/update write bodies.

Create account

POST /api/v1/external/accounts
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

name is required. Nested addresses are optional.

Request

{
  "name": "Acme Corp",
  "number": "ACC-1001",
  "externalId": "CRM-55",
  "billingDay": 1,
  "isMaster": true,
  "netTerm": "Net 30",
  "defaultCurrency": "USD",
  "addresses": [
    {
      "line1": "1 Market Street",
      "line2": "Suite 400",
      "city": "San Francisco",
      "state": "CA",
      "zipCode": "94105",
      "country": "United States",
      "taxId": "US-12-3456789"
    }
  ]
}
curl -sS -X POST "https://YOUR_TENANT_HOST/api/v1/external/accounts" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corp",
    "number": "ACC-1001",
    "defaultCurrency": "USD",
    "addresses": [{
      "line1": "1 Market Street",
      "city": "San Francisco",
      "state": "CA",
      "zipCode": "94105",
      "country": "United States"
    }]
  }'

Response 201 — camelCase account DTO (including nested addresses when present). List/GET use the __r row shape above.

Update account

PUT /api/v1/external/accounts/{accountId}
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

Updates scalar fields. If addresses is present, the address collection is replaced. Omit addresses to leave them unchanged.

Request

{
  "name": "Acme Corporation",
  "netTerm": "Net 45",
  "billingDay": 15
}

Response 200 — camelCase account DTO.

Delete account

DELETE /api/v1/external/accounts/{accountId}
Authorization: Bearer YOUR_API_TOKEN

Deletes nested addresses first.

Response 204 — no body.

Response 409 if the account is still referenced by payments or wallets.

{
  "status": 409,
  "error": "Conflict",
  "message": "Account is referenced by one or more payments",
  "path": "uri=/api/v1/external/accounts/11111111-1111-1111-1111-111111111111"
}

Account addresses

accountId comes from the path; do not send a conflicting accountId in the body.

List addresses

GET /api/v1/external/accounts/{accountId}/addresses?page=0&size=20
Authorization: Bearer YOUR_API_TOKEN

Response 200

{
  "content": [
    {
      "id": "22222222-2222-2222-2222-222222222222",
      "accountId": "11111111-1111-1111-1111-111111111111",
      "line1": "1 Market Street",
      "city": "San Francisco",
      "state": "CA",
      "zipCode": "94105",
      "country": "United States"
    }
  ],
  "page": 0,
  "size": 20,
  "totalElements": 1,
  "totalPages": 1
}

Get address

GET /api/v1/external/accounts/{accountId}/addresses/{addressId}
Authorization: Bearer YOUR_API_TOKEN

Response 200

{
  "id": "22222222-2222-2222-2222-222222222222",
  "accountId": "11111111-1111-1111-1111-111111111111",
  "line1": "1 Market Street",
  "line2": "Suite 400",
  "city": "San Francisco",
  "state": "CA",
  "zipCode": "94105",
  "country": "United States",
  "taxId": "US-12-3456789"
}

Create address

POST /api/v1/external/accounts/{accountId}/addresses
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

line1 is required. country accepts a country name or ISO alpha-2/alpha-3 code.

Request

{
  "line1": "500 Boylston Street",
  "line2": "Floor 12",
  "city": "Boston",
  "state": "MA",
  "zipCode": "02116",
  "country": "US",
  "taxId": "US-98-7654321"
}

Response 201

{
  "id": "33333333-3333-3333-3333-333333333333",
  "accountId": "11111111-1111-1111-1111-111111111111",
  "line1": "500 Boylston Street",
  "line2": "Floor 12",
  "city": "Boston",
  "state": "MA",
  "zipCode": "02116",
  "country": "United States",
  "taxId": "US-98-7654321"
}

Update address

PUT /api/v1/external/accounts/{accountId}/addresses/{addressId}
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

Request

{
  "line1": "500 Boylston Street",
  "line2": "Floor 14",
  "city": "Boston",
  "state": "MA",
  "zipCode": "02116",
  "country": "United States"
}

Response 200

{
  "id": "33333333-3333-3333-3333-333333333333",
  "accountId": "11111111-1111-1111-1111-111111111111",
  "line1": "500 Boylston Street",
  "line2": "Floor 14",
  "city": "Boston",
  "state": "MA",
  "zipCode": "02116",
  "country": "United States"
}

Delete address

DELETE /api/v1/external/accounts/{accountId}/addresses/{addressId}
Authorization: Bearer YOUR_API_TOKEN

Response 204 — no body.