Sales, Customer, and Item Message Types

Parent Document: API_Reference.md Implementation Folder: app/src/Message Type/Implementations/Sales/


Overview

This document describes the Sales, Customer, and Item message types in the Cloud Events API. These message types provide business operations for customer credit management, item availability checking, pricing information, sales order lifecycle management, and PDF document retrieval.

Message TypeDirectionPurposeRelated Table(s)
Customer.CreditLimit.GetOutboundRetrieve customer credit limit information including balance, outstanding amounts, and credit statusCustomer (18)
Customer.SalesHistory.GetOutboundRetrieve sales history by item for a specific customer within a date rangeCustomer (18), Item Ledger Entry (32)
Customer.Statement.PdfOutboundRetrieve customer statement as a PDF document with optional date rangeCustomer (18)
Item.Availability.GetOutboundRetrieve item availability information with physical inventory or calculated quantitiesItem (27)
Item.Price.GetOutboundRetrieve item price information from price lists based on customer and date filtersItem (27), Price List Line
Sales.Document.ReleaseInboundRelease an open sales document to make it ready for processing and postingSales Header (36)
Sales.Document.ReopenInboundReopen a released or pending approval sales document to allow modificationsSales Header (36)
Sales.Document.StatisticsOutboundRetrieve sales document statistics including amounts, VAT totals, quantities, weight and volumeSales Header (36)
Sales.Document.PostInboundPost a sales document and return all resulting posted documentsSales Header (36)
Sales.Document.CreateInboundCreate a new sales document header for a specified customer and document typeSales Header (36)
Sales.Document.PreviewPostInboundSimulate posting a sales document and return every captured ledger entry without committingSales Header (36) + every ledger table populated by the BC posting routine (dynamic; native support for G/L Entry, VAT Entry, Item Ledger Entry, Value Entry, Cust. / Detailed Cust. Ledger, Vendor / Detailed Vendor Ledger, Bank Account Ledger, FA Ledger, Maintenance Ledger, Job Ledger, Res. Ledger, Service Ledger, Warranty Ledger, Employee / Detailed Employee Ledger)
Sales.SalesInvoice.PdfOutboundRetrieve posted sales invoice as a PDF documentSales Invoice Header (112)
Sales.SalesShipment.PdfOutboundRetrieve posted sales shipment as a PDF documentSales Shipment Header (110)
Sales.SalesCreditMemo.PdfOutboundRetrieve posted sales credit memo as a PDF documentSales Cr.Memo Header (114)
Sales.ReturnReceipt.PdfOutboundRetrieve posted return receipt as a PDF documentReturn Receipt Header (6660)
Sales.SalesInvoice.CorrectInboundCancel a posted sales invoice and create a new draft sales invoice for correction via BC codeunit 1303Sales Invoice Header (112), Sales Cr.Memo Header (114), Sales Header (36)
Sales.SalesInvoice.CancelInboundCancel a posted sales invoice by posting a corrective credit memo via BC codeunit 1303Sales Invoice Header (112), Sales Cr.Memo Header (114)
Sales.SalesInvoice.SendInboundSend a posted sales invoice via the resolved Document Sending Profile using Sales Invoice Header.SendProfileSales Invoice Header (112), Document Sending Profile (60), Customer (18)
Sales.SalesCreditMemo.SendInboundSend a posted sales credit memo via the resolved Document Sending Profile using Sales Cr.Memo Header.SendProfileSales Cr.Memo Header (114), Document Sending Profile (60), Customer (18)
Customer.Application.PostInboundApply one customer ledger entry against one or more open customer ledger entries via codeunit 226Cust. Ledger Entry (21)
Customer.Application.ReverseInboundReverse (unapply) a posted application on a customer ledger entry via codeunit 226Cust. Ledger Entry (21)
Sales.Quote.MakeOrderInboundConvert a sales quote into a sales order via BC codeunit 86 "Sales-Quote to Order"Sales Header (36)
Sales.BlanketOrder.MakeOrderInboundConvert a sales blanket order into a sales order via BC codeunit 87 "Blanket Sales Order to Order"Sales Header (36)

Note: All PDF message types support both document number and SystemId (GUID) lookup.


Customer.CreditLimit.Get

Purpose: Retrieve customer credit limit information including balance, outstanding amounts, and credit limit status.

Description: Retrieves customer credit limit information including balance, outstanding amounts, remaining credit (with and without tolerance), and credit limit status indicators.

Message Direction: Outbound

Input Parameters:

The customer number can be specified either in the subject field or in the data parameters:

Option 1: Using subject field

{
  "subject": "10000"
}

Option 2: Using JSON data parameters

{
  "data": {
    "customerNo": "10000"
  }
}

Option 3: Using customer SystemId

{
  "data": {
    "customerId": "{12345678-1234-1234-1234-123456789012}"
  }
}

Request Parameters:

Response Format:

{
  "status": "Success",
  "customerNo": "10000",
  "customerName": "Adatum Corporation",
  "balanceLCY": 1234.56,
  "outstandingBalanceDueLCY": 500.00,
  "creditLimitLCY": 10000.00,
  "outstandingAmountLCY": 2000.00,
  "remainingCredit": 6765.44,
  "tolerancePercent": 10.00,
  "remainingCreditWithTolerance": 7765.44,
  "hasOverdueBalance": true,
  "isCreditLimitExceeded": false
}

Response Fields:

Credit Limit Calculation Example:

Given:

Calculation:

Configuration:

Notes:

Example Request:

{
  "specversion": "1.0",
  "type": "Customer.CreditLimit.Get",
  "source": "MyApp v1.0",
  "subject": "10000"
}

Use Cases:

Related Message Types:


Customer.SalesHistory.Get

Purpose: Retrieve sales history by item for a specific customer within a date range.

Description: Retrieves sales history information showing which items a customer has purchased, including number of orders and unit of measure details. Based on Item Ledger Entries for the customer within the specified date range.

Message Direction: Outbound

Input Parameters:

The customer number can be specified in either the subject field or in the data parameters. Additional date range parameters are required in the data field:

{
  "subject": "10000",
  "data": {
    "fromDate": "2025-01-01",
    "toDate": "2025-12-31"
  }
}

Or alternatively:

{
  "data": {
    "customerNo": "10000",
    "fromDate": "2025-01-01",
    "toDate": "2025-12-31"
  }
}

Request Parameters:

ParameterTypeRequiredDescription
customerNoCode[20]YesCustomer number (can be in subject or data)
fromDateDateYesStart date for sales history query (YYYY-MM-DD format)
toDateDateNoEnd date for sales history query (YYYY-MM-DD format). Defaults to today if not provided

Response Format:

{
  "status": "Success",
  "noOfRecords": 5,
  "customerNo": "10000",
  "customerName": "Adatum Corporation",
  "fromDate": "2025-01-01",
  "toDate": "2025-12-31",
  "salesHistory": [
    {
      "itemNo": "1000",
      "variantCode": "",
      "description": "Bicycle",
      "baseUnitOfMeasure": "PCS",
      "baseUOMDescription": "Piece",
      "noOfOrders": 3
    },
    {
      "itemNo": "1001",
      "variantCode": "RED",
      "description": "Touring Bike Red",
      "baseUnitOfMeasure": "PCS",
      "baseUOMDescription": "Piece",
      "noOfOrders": 2
    }
  ]
}

Response Fields:

Root level:

Sales history item:

Configuration: No configuration required. Data is retrieved directly from Item Ledger Entries.

Notes:

Example Request:

{
  "specversion": "1.0",
  "type": "Customer.SalesHistory.Get",
  "source": "Webstore v1.0",
  "subject": "10000",
  "datacontenttype": "application/json",
  "data": {
    "fromDate": "2025-01-01",
    "toDate": "2025-12-31"
  }
}

Use Cases:

Related Message Types:


Customer.Statement.Pdf

Purpose: Retrieve a customer statement as a PDF document with an optional date range.

Description: Retrieves a customer statement as a PDF document using the configured report selection. The statement can show all transactions within a specified date range, defaulting to the last 30 days if no dates are provided.

Message Direction: Outbound

Request Parameters:

The customer number or SystemId must be specified in the subject field. Optional date range parameters can be provided in the data field.

Using customer number (default 30-day period):

{
  "specversion": "1.0",
  "type": "Customer.Statement.Pdf",
  "source": "MyApp v1.0",
  "subject": "10000"
}

Using customer number with date range:

{
  "specversion": "1.0",
  "type": "Customer.Statement.Pdf",
  "source": "MyApp v1.0",
  "subject": "10000",
  "data": "{\"startDate\":\"2026-01-01\",\"endDate\":\"2026-03-20\"}"
}

Request Parameters:

Response Format:

The initial response is a JSON object containing a download URL and the content type of the downloadable file:

{
  "downloadUrl": "/api/origo/cloudEvent/v1.0/responses({guid})",
  "contentType": "application/pdf"
}

Call the downloadUrl to retrieve the PDF binary. The downloaded content has content type application/pdf. The PDF is generated using the configured report selection for Customer Statement (C.Statement).

Default Behavior:

If no date parameters are provided, the statement covers the last 30 days (Today - 30 days through Today).

Error Messages:

Notes:

Use Cases:

Related Message Types:


Item.Availability.Get

Purpose: Retrieve item availability information including inventory quantities and availability status.

Description: Retrieves item availability information based on the configured calculation type (Physical Inventory or Calculated Quantity). Supports single-item and multi-item queries, location filtering, and requested delivery date for future availability calculations.

Message Direction: Outbound

Item Resolution:

The item(s) to query can be specified using several methods, checked in order:

  1. subject — GUID resolves via SystemId; plain text resolves via Item No.
  2. data.itemNo — Item number (overrides subject)
  3. data.itemId — Item SystemId (GUID)
  4. data.id / data.systemId / data.recordSystemId — Item SystemId (GUID)
  5. data.tableView — BC AL table view filter (e.g., WHERE(Item Category Code=CONST(FURNITURE))) — returns multiple items
  6. If none specified, returns all non-blocked items

Option 1: Single item by number (subject)

{
  "subject": "1000",
  "data": {
    "requestedDeliveryDate": "2026-03-15",
    "locationFilter": "BLUE|RED"
  }
}

Option 2: Single item by JSON data parameter

{
  "data": {
    "itemNo": "1000",
    "requestedDeliveryDate": "2026-03-15",
    "locationFilter": "BLUE|RED"
  }
}

Option 3: Single item by SystemId

{
  "data": {
    "itemId": "{12345678-1234-1234-1234-123456789012}",
    "requestedDeliveryDate": "2026-03-15"
  }
}

Option 4: Multiple items by tableView filter

{
  "data": {
    "tableView": "WHERE(Item Category Code=CONST(FURNITURE))",
    "locationFilter": "BLUE"
  }
}

Request Parameters:

Response Format:

Results are always returned in an items array, even for single-item queries. The array structure depends on the Item Calc. Availability Type configured in Cloud Events Setup.

Response Format - Physical Inventory:

{
  "status": "Success",
  "items": [
    {
      "itemNo": "1000",
      "itemDescription": "Bicycle",
      "baseUnitOfMeasure": "PCS",
      "inventory": [
        { "locationCode": "BLUE", "inventory": 50 },
        { "locationCode": "RED", "inventory": 30 },
        { "locationCode": "", "inventory": 10 }
      ]
    }
  ]
}

Response Format - Calculated Quantity:

{
  "status": "Success",
  "items": [
    {
      "itemNo": "1000",
      "itemDescription": "Bicycle",
      "baseUnitOfMeasure": "PCS",
      "requestedDeliveryDate": "2026-03-15",
      "availability": [
        {
          "locationCode": "BLUE",
          "inventory": 50,
          "qtyReserved": 10,
          "grossRequirement": 20,
          "scheduledReceipt": 30,
          "plannedOrderReceipt": 15,
          "availableQuantity": 65
        }
      ]
    }
  ]
}

Multi-item response example (Physical Inventory):

{
  "status": "Success",
  "items": [
    {
      "itemNo": "1000",
      "itemDescription": "Bicycle",
      "baseUnitOfMeasure": "PCS",
      "inventory": [
        { "locationCode": "BLUE", "inventory": 50 }
      ]
    },
    {
      "itemNo": "1001",
      "itemDescription": "Touring Bicycle",
      "baseUnitOfMeasure": "PCS",
      "inventory": [
        { "locationCode": "BLUE", "inventory": 25 }
      ]
    }
  ]
}

Availability Types:

The response format depends on the Item Calc. Availability Type configured in Cloud Events Setup:

Physical Inventory

Fields (per item):

Calculated Quantity

Fields (per item):

Configuration:

Notes:

Example Requests:

1. Get current inventory for a single item:

{
  "specversion": "1.0",
  "type": "Item.Availability.Get",
  "source": "MyApp v1.0",
  "subject": "1000"
}

2. Get availability for specific delivery date:

{
  "specversion": "1.0",
  "type": "Item.Availability.Get",
  "source": "MyApp v1.0",
  "subject": "1000",
  "data": {
    "requestedDeliveryDate": "2026-03-15"
  }
}

3. Get availability with location filter:

{
  "specversion": "1.0",
  "type": "Item.Availability.Get",
  "source": "MyApp v1.0",
  "subject": "1000",
  "data": {
    "requestedDeliveryDate": "2026-03-15",
    "locationFilter": "BLUE|RED"
  }
}

4. Multi-item query using tableView:

{
  "specversion": "1.0",
  "type": "Item.Availability.Get",
  "source": "MyApp v1.0",
  "data": {
    "tableView": "WHERE(Item Category Code=CONST(FURNITURE))",
    "locationFilter": "BLUE"
  }
}

Error Responses:

Use Cases:

Related Message Types:


Item.Price.Get

Purpose: Retrieve item price information based on configured price calculation rules.

Description: Retrieves item price information from price lists based on customer, requested delivery date, quantity, and variant filters. Supports single-item and multi-item queries. Returns prices from customer-specific price lists, all-customers price lists, and item card prices as fallback.

Message Direction: Outbound

Item Resolution:

Same resolution as Item.Availability.Get:

  1. subject — GUID resolves via SystemId; plain text resolves via Item No.
  2. data.itemNo — Item number (overrides subject)
  3. data.itemId — Item SystemId (GUID)
  4. data.id / data.systemId / data.recordSystemId — Item SystemId (GUID)
  5. data.tableView — BC AL table view filter for multi-item queries
  6. If none specified, returns prices for all non-blocked items

Customer Resolution Priority:

  1. data.customerNo — Customer number (Code)
  2. data.customerId — Customer SystemId (GUID)
  3. data.customerRecordId — Customer SystemId (GUID)
  4. data.customerSystemId — Customer SystemId (GUID)
  5. If none specified, returns all-customers prices only

Option 1: Single item by number (subject)

{
  "subject": "1000",
  "data": {
    "customerNo": "C001",
    "requestedDeliveryDate": "2026-03-15"
  }
}

Option 2: Single item by JSON data parameter

{
  "data": {
    "itemNo": "1000",
    "customerNo": "C001",
    "requestedDeliveryDate": "2026-03-15"
  }
}

Option 3: Single item by SystemId

{
  "data": {
    "itemId": "{12345678-1234-1234-1234-123456789012}",
    "customerNo": "C001",
    "requestedDeliveryDate": "2026-03-15"
  }
}

Option 4: Multiple items by tableView filter

{
  "data": {
    "tableView": "WHERE(Item Category Code=CONST(FURNITURE))",
    "customerNo": "C001",
    "requestedDeliveryDate": "2026-03-15"
  }
}

Request Parameters:

Customer Validation:

When a customer identifier (customerNo, customerId, customerRecordId, or customerSystemId) is provided, the customer record is validated before price calculation. All of the following must be configured on the customer:

If any of these are missing, an error response is returned (e.g., "Customer C001 must have a VAT Bus. Posting Group.").

Response Format:

Price list lines from all matched items are returned in a single priceListLines array. Each line includes an itemNo field to identify which item it belongs to.

{
  "status": "Success",
  "priceListLines": [
    {
      "priceListCode": "RETAIL-2026",
      "priceListDescription": "Retail Price List 2026",
      "lineNo": 10000,
      "itemNo": "1000",
      "variantCode": "BLUE",
      "unitOfMeasureCode": "PCS",
      "qtyPerUnitOfMeasure": 1.0,
      "minimumQuantity": 10,
      "amountType": "Price",
      "unitPrice": 950.00,
      "unitPriceExclVAT": 950.00,
      "unitPriceInclVAT": 1178.00,
      "lineDiscountPct": 5.0,
      "allowInvoiceDisc": true,
      "allowLineDisc": true,
      "vatBusPostingGr": "DOMESTIC",
      "vatProdPostingGr": "STANDARD",
      "vatPct": 24.0,
      "itemName": "Bicycle",
      "itemDescription": "Touring Model",
      "baseUnitOfMeasure": "PCS",
      "eanCode": "5701234560013",
      "unspscCode": "87111501",
      "netWeight": 12.5,
      "itemSystemId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "priceType": "Customer",
      "status": "Active",
      "startingDate": "2026-01-01",
      "endingDate": "2026-12-31"
    }
  ]
}

Response Fields:

Each price list line contains:

Price Selection Logic:

The default implementation retrieves prices in the following priority (per item):

  1. Customer-Specific Prices:
  1. All-Customers Prices:
  1. Item Card Prices:

Configuration:

Error Responses:

Notes:

Example Requests:

1. Get prices for item (all customers):

{
  "specversion": "1.0",
  "type": "Item.Price.Get",
  "source": "MyApp v1.0",
  "subject": "1000"
}

2. Get customer-specific prices:

{
  "specversion": "1.0",
  "type": "Item.Price.Get",
  "source": "MyApp v1.0",
  "subject": "1000",
  "data": {
    "customerNo": "C001",
    "requestedDeliveryDate": "2026-03-15"
  }
}

3. Get prices with quantity and variant:

{
  "specversion": "1.0",
  "type": "Item.Price.Get",
  "source": "MyApp v1.0",
  "subject": "1000",
  "data": {
    "customerNo": "C001",
    "requestedDeliveryDate": "2026-03-15",
    "quantity": 25,
    "variantCode": "BLUE"
  }
}

4. Multi-item pricing using tableView:

{
  "specversion": "1.0",
  "type": "Item.Price.Get",
  "source": "MyApp v1.0",
  "data": {
    "tableView": "WHERE(Item Category Code=CONST(FURNITURE))",
    "customerNo": "C001"
  }
}

5. Customer-specific pricing by SystemId:

{
  "specversion": "1.0",
  "type": "Item.Price.Get",
  "source": "MyApp v1.0",
  "subject": "1000",
  "data": {
    "customerId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Use Cases:

Related Message Types:


Sales.Document.Release

Purpose: Release an open sales document to make it ready for processing and posting.

Description: Releases a sales document by changing its status from Open to Released. This action validates the document, locks it for editing, and makes it available for further processing such as picking, shipping, and invoicing. Supports all sales document types: Order, Invoice, Credit Memo, and Return Order. The operation uses the standard Business Central release functionality and provides comprehensive status information before and after the release operation.

Message Direction: Inbound

Request Parameters:

The document can be identified using the subject field or a key in the data JSON object:

Option 1: Using subject (document number)

{
  "specversion": "1.0",
  "subject": "SO-1001"
}

Option 2: Using subject (SystemId GUID)

{
  "specversion": "1.0",
  "subject": "{12345678-1234-1234-1234-123456789012}"
}

Option 3: Using data field

{
  "specversion": "1.0",
  "data": {
    "orderNo": "SO-1001"
  }
}

Request Parameters:

Note: Either subject or a data key must be provided. The subject field is checked first; if empty, data keys are checked in the order listed above.

Response Format:

Success Response:

{
  "status": "Success",
  "documentType": "Order",
  "documentNo": "SO-1001",
  "customerNo": "C001",
  "customerName": "Contoso Ltd.",
  "statusBefore": "Open",
  "statusAfter": "Released",
  "documentDate": "2025-05-15",
  "amount": 1100.00,
  "amountIncludingVAT": 1364.00
}

Error Response:

{
  "status": "Error",
  "message": "Sales Order SO-1001 not found."
}

Response Fields:

Validation Rules:

  1. Document Identifier Required: Either subject or a data key must be specified
  2. Document Must Exist: The specified sales document must exist in the system
  3. Status Validation: The document must have status "Open" (documents already released will return an error)
  4. Standard Validations: All standard Business Central validation rules for releasing sales documents apply (e.g., mandatory fields, line quantities, etc.)

Document Lookup:

Error Messages:

Complete Workflow Example:

This example demonstrates the complete workflow of creating a sales document, adding lines, verifying status, releasing, and confirming the release:

Step 1: Create Sales Order

{
  "specversion": "1.0",
  "type": "Data.Records.Set",
  "source": "OrderManagement v1.0",
  "subject": "Sales Header",
  "data": {
    "data": [
      {
        "primaryKey": {
          "DocumentType": "Order",
          "No_": "SO-1001"
        },
        "fields": {
          "SelltoCustomerNo": "C001",
          "OrderDate": "2025-05-15"
        }
      }
    ]
  }
}

Step 2: Add Sales Lines

{
  "specversion": "1.0",
  "type": "Data.Records.Set",
  "source": "OrderManagement v1.0",
  "subject": "Sales Line",
  "data": {
    "data": [
      {
        "primaryKey": {
          "DocumentType": "Order",
          "DocumentNo": "SO-1001",
          "LineNo": 10000
        },
        "fields": {
          "Type": "Item",
          "No": "1000",
          "Quantity": 5,
          "UnitPrice": 100.00
        }
      },
      {
        "primaryKey": {
          "DocumentType": "Order",
          "DocumentNo": "SO-1001",
          "LineNo": 20000
        },
        "fields": {
          "Type": "Item",
          "No": "1001",
          "Quantity": 3,
          "UnitPrice": 200.00
        }
      }
    ]
  }
}

Step 3: Verify Order Status is Open

{
  "specversion": "1.0",
  "type": "Data.Records.Get",
  "source": "OrderManagement v1.0",
  "data": {
    "tableName": "Sales Header",
    "fieldNumbers": [3],
    "tableView": "WHERE(Document Type=CONST(Order),No.=CONST(SO-1001))"
  }
}

Response (Status is Open):

{
  "status": "Success",
  "result": [
    {
      "id": "12345678-...",
      "primaryKey": {
        "DocumentType": "Order",
        "No_": "SO-1001"
      },
      "fields": {
        "Status": "Open"
      }
    }
  ]
}

Step 4: Release the Sales Order

{
  "specversion": "1.0",
  "type": "Sales.Document.Release",
  "source": "OrderManagement v1.0",
  "subject": "SO-1001"
}

Response (Release Successful):

{
  "status": "Success",
  "documentType": "Order",
  "documentNo": "SO-1001",
  "customerNo": "C001",
  "customerName": "Contoso Ltd.",
  "statusBefore": "Open",
  "statusAfter": "Released",
  "documentDate": "2025-05-15",
  "amount": 1100.00,
  "amountIncludingVAT": 1364.00
}

Step 5: Verify Order Status is Released

{
  "specversion": "1.0",
  "type": "Data.Records.Get",
  "source": "OrderManagement v1.0",
  "data": {
    "tableName": "Sales Header",
    "fieldNumbers": [3],
    "tableView": "WHERE(Document Type=CONST(Order),No.=CONST(SO-1001))"
  }
}

Response (Status is Released):

{
  "status": "Success",
  "result": [
    {
      "id": "12345678-...",
      "primaryKey": {
        "DocumentType": "Order",
        "No_": "SO-1001"
      },
      "fields": {
        "Status": "Released"
      }
    }
  ]
}

Use Cases:

Related Message Types:

Notes:


Sales.Document.Statistics

Purpose: Retrieve sales document statistics including amounts, VAT totals, quantities, weight and volume.

Description: Retrieves comprehensive statistics for a sales document including amounts, line and invoice discounts, VAT breakdown, total quantities, weight and volume. This is a read-only operation that provides the same information displayed on the Sales Statistics page in Business Central. Supports all sales document types: Order, Invoice, Credit Memo, and Return Order. The document can be identified by either the document number or SystemId (GUID).

Message Direction: Outbound

Request Parameters:

The document can be identified using the subject field or a key in the data JSON object:

Option 1: Using subject field (document number)

{
  "specversion": "1.0",
  "type": "Sales.Document.Statistics",
  "source": "MyApp v1.0",
  "subject": "SO-1001"
}

Option 2: Using subject field (SystemId)

{
  "specversion": "1.0",
  "type": "Sales.Document.Statistics",
  "source": "MyApp v1.0",
  "subject": "{12345678-1234-1234-1234-123456789012}"
}

Option 3: Using data field

{
  "specversion": "1.0",
  "type": "Sales.Document.Statistics",
  "source": "MyApp v1.0",
  "data": {
    "orderNo": "SO-1001"
  }
}

Request Parameters:

Note: Either subject or a data key must be provided. The subject field is checked first; if empty, data keys are checked in the order listed above.

Document Lookup:

Response Format:

Success Response:

{
  "status": "Success",
  "documentType": "Order",
  "documentNo": "SO-1001",
  "customerNo": "10000",
  "customerName": "Adatum Corporation",
  "currencyCode": "",
  "documentDate": "2026-03-07",
  "order": {
    "amount": 5000.00,
    "lineDiscountAmount": 150.00,
    "invoiceDiscountAmount": 250.00,
    "totalExclVAT": 4750.00,
    "vatAmount": 1187.50,
    "totalInclVAT": 5937.50,
    "quantity": 100,
    "totalWeight": 125.50,
    "totalVolume": 2.35,
    "noOfVATLines": 1
  },
  "vat_totals": [
    {
      "vatIdentifier": "STANDARD",
      "vatPct": 25.00,
      "lineAmount": 5000.00,
      "vatBase": 4750.00,
      "vatAmount": 1187.50,
      "amountInclVAT": 5937.50
    }
  ]
}

Error Response:

{
  "status": "Error",
  "error": "Sales Order SO-1001 not found."
}

Response Fields:

Top Level Fields

Order Group Fields

VAT Totals Array

Contains one entry per VAT rate used in the document:

Validation Rules:

  1. Document Identifier Required: Either subject or a data key must be specified
  2. Document Must Exist: The specified sales document must exist in the system
  3. Specification Version: Must be version 1.0

Error Messages:

Currency and Rounding:

All amounts are rounded using the currency precision defined in the order's currency code:

Calculation Details:

  1. Line Discount Amount: Calculated by summing the "Line Discount Amount" field from all sales lines
  2. Weight and Volume: Calculated by multiplying each line's quantity by its Gross Weight and Unit Volume fields
  3. VAT Amounts: Calculated using Business Central's standard VAT calculation logic (CalcVATAmountLines)
  4. Invoice Discount: Retrieved from the VAT Amount Line calculations
  5. Totals: Retrieved using the GetTotalVATAmount method from VAT Amount Line

Use Cases:

Related Message Types:

Notes:


Sales.Document.Post

Purpose: Post a sales document and return all resulting posted documents.

Description: Posts a sales document using the standard Business Central Sales-Post codeunit. Supports all four sales document types: Order, Invoice, Credit Memo, and Return Order. The document must have at least one line. After successful posting the original document is consumed and one or more posted documents are created. The response contains details of each posted document in a postedDocuments array.

Document TypePosted Documents Created
OrderPosted Sales Invoice + Posted Sales Shipment
InvoicePosted Sales Invoice
Credit MemoPosted Sales Credit Memo
Return OrderPosted Sales Credit Memo + Posted Return Receipt

Message Direction: Inbound

Request Parameters:

The document can be identified using the subject field or a key in the data JSON object:

Option 1: Using subject field (document number)

{
  "specversion": "1.0",
  "type": "Sales.Document.Post",
  "source": "MyApp v1.0",
  "subject": "SO-1001"
}

Option 2: Using data field

{
  "specversion": "1.0",
  "type": "Sales.Document.Post",
  "source": "MyApp v1.0",
  "data": "{\"orderNo\": \"SO-1001\"}"
}

Option 3: Using SystemId (GUID)

{
  "specversion": "1.0",
  "type": "Sales.Document.Post",
  "source": "MyApp v1.0",
  "subject": "{12345678-1234-1234-1234-123456789012}"
}

Request Parameters:

Note: Either subject or a data key must be provided. The subject field is checked first; if empty, data keys are checked in the order listed above.

Document Lookup:

Response Format:

{
  "status": "Success",
  "documentType": "Order",
  "documentNo": "SO-1001",
  "customerNo": "10000",
  "customerName": "Adatum Corporation",
  "postedDocuments": [
    {
      "type": "Posted Sales Invoice",
      "recordSystemId": "12345678-1234-1234-1234-123456789012",
      "no": "PI-1001",
      "postingDate": "2026-03-16",
      "amount": 5000.00,
      "amountIncludingVAT": 6200.00,
      "custLedgerEntryNo": 1001
    },
    {
      "type": "Posted Sales Shipment",
      "recordSystemId": "87654321-4321-4321-4321-210987654321",
      "no": "S-1001",
      "postingDate": "2026-03-16"
    }
  ]
}

Response Fields:

Top Level

FieldTypeDescription
statusstring"Success" or "Error"
documentTypestringType of the original document: "Order", "Invoice", "Credit Memo", or "Return Order"
documentNostringOriginal document number that was posted
customerNostringSell-to customer number
customerNamestringSell-to customer name

postedDocuments Array

Each entry represents one posted document created by the posting:

FieldTypeDescription
typestringPosted document type ("Posted Sales Invoice", "Posted Sales Shipment", "Posted Sales Credit Memo", or "Posted Return Receipt")
recordSystemIdstringSystemId (GUID) of the posted document record
nostringDocument number of the posted document
postingDatedatePosting date of the posted document
amountdecimalTotal amount excluding VAT (present on invoices and credit memos only)
amountIncludingVATdecimalTotal amount including VAT (present on invoices and credit memos only)
custLedgerEntryNointegerCustomer ledger entry number (present on invoices and credit memos only)

Error Scenarios:

ErrorMessage
Document not found"Sales document not found."
No lines"Sales document SO-1001 has no lines to post."
No document specified"Document identifier must be specified in subject field or request JSON (systemId, recordSystemId, id, orderNo, quoteNo, invoiceNo, creditMemoNo, blanketOrderNo, returnOrderNo)."
Posting failureBusiness Central posting validation message (e.g., missing posting setup, blocked customer)

Notes:


Sales.SalesInvoice.Pdf

Purpose: Retrieve a posted sales invoice as a PDF document.

Description: Retrieves a posted sales invoice as a PDF document using the configured report selection. The invoice can be identified by either the document number or SystemId (GUID).

Message Direction: Outbound

Request Parameters:

The invoice number or SystemId can be specified either in the subject field or in the data parameters:

Option 1: Using subject field with invoice number

{
  "specversion": "1.0",
  "type": "Sales.SalesInvoice.Pdf",
  "source": "MyApp v1.0",
  "subject": "103001"
}

Option 2: Using subject field with SystemId

{
  "specversion": "1.0",
  "type": "Sales.SalesInvoice.Pdf",
  "source": "MyApp v1.0",
  "subject": "{12345678-1234-1234-1234-123456789012}"
}

Option 3: Using JSON data parameters with invoiceNo

{
  "specversion": "1.0",
  "type": "Sales.SalesInvoice.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "invoiceNo": "103001"
  }
}

Option 4: Using JSON data parameters with invoiceId

{
  "specversion": "1.0",
  "type": "Sales.SalesInvoice.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "invoiceId": "{12345678-1234-1234-1234-123456789012}"
  }
}

Option 5: Using generic documentNo parameter

{
  "specversion": "1.0",
  "type": "Sales.SalesInvoice.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "documentNo": "103001"
  }
}

Request Parameters:

Response Format:

The initial response is a JSON object containing a download URL and the content type of the downloadable file:

{
  "downloadUrl": "/api/origo/cloudEvent/v1.0/responses({guid})",
  "contentType": "application/pdf"
}

Call the downloadUrl to retrieve the PDF binary. The downloaded content has content type application/pdf. The PDF is generated using the configured report selection for Sales Invoice (S.Invoice).

Error Messages:

Notes:

Related Message Types:


Sales.SalesShipment.Pdf

Purpose: Retrieve a posted sales shipment as a PDF document.

Description: Retrieves a posted sales shipment as a PDF document using the configured report selection. The shipment can be identified by either the document number or SystemId (GUID).

Message Direction: Outbound

Request Parameters:

The shipment number or SystemId can be specified either in the subject field or in the data parameters:

Option 1: Using subject field with shipment number

{
  "specversion": "1.0",
  "type": "Sales.SalesShipment.Pdf",
  "source": "MyApp v1.0",
  "subject": "102001"
}

Option 2: Using subject field with SystemId

{
  "specversion": "1.0",
  "type": "Sales.SalesShipment.Pdf",
  "source": "MyApp v1.0",
  "subject": "{12345678-1234-1234-1234-123456789012}"
}

Option 3: Using JSON data parameters with shipmentNo

{
  "specversion": "1.0",
  "type": "Sales.SalesShipment.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "shipmentNo": "102001"
  }
}

Option 4: Using JSON data parameters with shipmentId

{
  "specversion": "1.0",
  "type": "Sales.SalesShipment.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "shipmentId": "{12345678-1234-1234-1234-123456789012}"
  }
}

Option 5: Using generic documentNo parameter

{
  "specversion": "1.0",
  "type": "Sales.SalesShipment.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "documentNo": "102001"
  }
}

Request Parameters:

Response Format:

The initial response is a JSON object containing a download URL and the content type of the downloadable file:

{
  "downloadUrl": "/api/origo/cloudEvent/v1.0/responses({guid})",
  "contentType": "application/pdf"
}

Call the downloadUrl to retrieve the PDF binary. The downloaded content has content type application/pdf. The PDF is generated using the configured report selection for Sales Shipment (S.Shipment).

Error Messages:

Notes:

Related Message Types:


Sales.SalesCreditMemo.Pdf

Purpose: Retrieve a posted sales credit memo as a PDF document.

Description: Retrieves a posted sales credit memo as a PDF document using the configured report selection. The credit memo can be identified by either the document number or SystemId (GUID).

Message Direction: Outbound

Request Parameters:

The credit memo number or SystemId can be specified either in the subject field or in the data parameters:

Option 1: Using subject field with credit memo number

{
  "specversion": "1.0",
  "type": "Sales.SalesCreditMemo.Pdf",
  "source": "MyApp v1.0",
  "subject": "104001"
}

Option 2: Using subject field with SystemId

{
  "specversion": "1.0",
  "type": "Sales.SalesCreditMemo.Pdf",
  "source": "MyApp v1.0",
  "subject": "{12345678-1234-1234-1234-123456789012}"
}

Option 3: Using JSON data parameters with creditMemoNo

{
  "specversion": "1.0",
  "type": "Sales.SalesCreditMemo.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "creditMemoNo": "104001"
  }
}

Option 4: Using JSON data parameters with creditMemoId

{
  "specversion": "1.0",
  "type": "Sales.SalesCreditMemo.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "creditMemoId": "{12345678-1234-1234-1234-123456789012}"
  }
}

Option 5: Using generic documentNo parameter

{
  "specversion": "1.0",
  "type": "Sales.SalesCreditMemo.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "documentNo": "104001"
  }
}

Request Parameters:

Response Format:

The initial response is a JSON object containing a download URL and the content type of the downloadable file:

{
  "downloadUrl": "/api/origo/cloudEvent/v1.0/responses({guid})",
  "contentType": "application/pdf"
}

Call the downloadUrl to retrieve the PDF binary. The downloaded content has content type application/pdf. The PDF is generated using the configured report selection for Sales Credit Memo (S.Cr.Memo).

Error Messages:

Notes:

Related Message Types:


Sales.ReturnReceipt.Pdf

Purpose: Retrieve a posted return receipt as a PDF document.

Description: Retrieves a posted return receipt as a PDF document using the configured report selection. The return receipt can be identified by either the document number or SystemId (GUID).

Message Direction: Outbound

Request Parameters:

The return receipt number or SystemId can be specified either in the subject field or in the data parameters:

Option 1: Using subject field with return receipt number

{
  "specversion": "1.0",
  "type": "Sales.ReturnReceipt.Pdf",
  "source": "MyApp v1.0",
  "subject": "105001"
}

Option 2: Using subject field with SystemId

{
  "specversion": "1.0",
  "type": "Sales.ReturnReceipt.Pdf",
  "source": "MyApp v1.0",
  "subject": "{12345678-1234-1234-1234-123456789012}"
}

Option 3: Using JSON data parameters with returnReceiptNo

{
  "specversion": "1.0",
  "type": "Sales.ReturnReceipt.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "returnReceiptNo": "105001"
  }
}

Option 4: Using JSON data parameters with returnReceiptId

{
  "specversion": "1.0",
  "type": "Sales.ReturnReceipt.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "returnReceiptId": "{12345678-1234-1234-1234-123456789012}"
  }
}

Option 5: Using generic documentNo parameter

{
  "specversion": "1.0",
  "type": "Sales.ReturnReceipt.Pdf",
  "source": "MyApp v1.0",
  "data": {
    "documentNo": "105001"
  }
}

Request Parameters:

Response Format:

The initial response is a JSON object containing a download URL and the content type of the downloadable file:

{
  "downloadUrl": "/api/origo/cloudEvent/v1.0/responses({guid})",
  "contentType": "application/pdf"
}

Call the downloadUrl to retrieve the PDF binary. The downloaded content has content type application/pdf. The PDF is generated using the configured report selection for Return Receipt (S.Ret.Rcpt.).

Error Messages:

Notes:

Related Message Types:


Integration Patterns

Pattern 1: Order Entry Workflow with Validation

Complete order entry workflow with credit check, availability check, and pricing validation before releasing:

1. Customer.CreditLimit.Get → Verify customer has available credit
2. Item.Availability.Get → Check item availability for delivery date
3. Item.Price.Get → Retrieve current pricing
4. Data.Records.Set → Create sales order header and lines
5. Sales.Document.Release → Release order for processing

Pattern 2: Inventory Management Dashboard

Real-time inventory dashboard using availability and pricing information:

1. Data.Records.Get → Get list of items (Item table)
2. Item.Availability.Get → Get availability for each item
3. Item.Price.Get → Get pricing information for each item
4. Display combined inventory and pricing dashboard

Pattern 3: Customer Portal Integration

E-commerce or customer portal integration workflow:

1. Customer.CreditLimit.Get → Display available credit to customer
2. Item.Availability.Get → Show available quantities
3. Item.Price.Get → Display customer-specific pricing
4. Data.Records.Set → Create order from portal
5. Sales.Document.Release → Auto-release based on credit/availability rules

Related Documentation


Sales.Document.Create

Purpose: Create a new sales document header for a specified customer and document type.

Direction: Inbound (Action request)

Filter Table: Sales Header (36)

Description: Creates a new sales document (Quote, Order, Invoice, Credit Memo, Blanket Order, or Return Order) for a customer. Only the header is created — lines must be added separately using Data.Records.Set.

Request Format

ParameterRequiredDescription
sourceYesCalling application identifier
subjectNoCustomer number or SystemId (GUID)
data.documentTypeYesDocument type: "Quote", "Order", "Invoice", "Credit Memo", "Blanket Order", "Return Order"
data.postingDateNoPosting date (ISO YYYY-MM-DD). Defaults to WorkDate
data.noNoCustomer number (alternative to subject)
data.idNoCustomer SystemId (GUID, alternative to subject)
data.systemIdNoCustomer SystemId (GUID, alternative to subject)
data.recordSystemIdNoCustomer SystemId (GUID, alternative to subject)

Customer Lookup Priority

  1. subject field: GUID → GetBySystemId, plain text → Get by No.
  2. data JSON keys (first match): no, id, systemId, recordSystemId

Example Requests

Create a sales order for customer 10000:

{
  "specversion": "1.0",
  "type": "Sales.Document.Create",
  "source": "MyApp v1.0",
  "subject": "10000",
  "data": {
    "documentType": "Order"
  }
}

Create a sales invoice with a custom posting date:

{
  "specversion": "1.0",
  "type": "Sales.Document.Create",
  "source": "OrderSync v2.0",
  "data": {
    "documentType": "Invoice",
    "no": "10000",
    "postingDate": "2026-04-15"
  }
}

Response Format

Returns JSON in Data.Records.Get format:

{
  "status": "Success",
  "noOfRecords": 1,
  "result": [
    {
      "id": "a1b2c3d4-...",
      "primaryKey": {
        "DocumentType": "Order",
        "No_": "SO-001"
      },
      "fields": {
        "DocumentType": "Order",
        "No_": "SO-001",
        "SelltoCustomerNo_": "10000",
        "SelltoCustomerName": "Adatum Corporation",
        "PostingDate": "2026-03-07",
        "Status": "Open"
      }
    }
  ]
}

Error Responses

ErrorCause
documentType is required in request JSONMissing documentType in data
Invalid document type 'X'Unrecognized document type value
Customer not foundNo customer matches the provided identifier

Implementation Notes:

Related Message Types:


Sales.Document.PreviewPost

Purpose: Simulate posting a sales document and return all resulting ledger entries without committing any changes.

Description: Drives the standard BC posting routine (Codeunit "Sales-Post (Yes/No)") through Codeunit "Gen. Jnl.-Post Preview", which captures every entry that would be inserted and then rolls back the transaction. Use this to validate that a document can be posted, show an AI agent the exact financial impact, or surface predicted document numbers and totals before posting.

Message Direction: Inbound

Side effects: None — the transaction is always rolled back. The sales header remains unchanged.

Supported Document Types: Order, Invoice, Credit Memo, Return Order.

Input Parameters:

Document Selection Methods: Any one of the following identifies the document:

  1. subject as plain text — looked up as document No. across all four document types.
  2. subject as GUID — looked up as SystemId on Sales Header.
  3. data.systemId / data.recordSystemId / data.id — SystemId lookup.
  4. data.orderNo / data.invoiceNo / data.creditMemoNo / data.returnOrderNo — typed No. lookup restricted to the matching Document Type.

Response Format:

{
  "status": "Success",
  "rollback": true,
  "summary": "Preview-posting Order SO-001 for customer C01 would create 6 ledger entries across 6 tables. Transaction is balanced.",
  "documentType": "Order",
  "documentNo": "SO-001",
  "customerNo": "C01",
  "customerName": "Acme Customer",
  "lcyCode": "USD",
  "documentCurrencyCode": "EUR",
  "documentExchangeRate": 1.08,
  "predictedNumbers": {
    "postedInvoiceNo": "SI-00045",
    "postedShipmentNo": "SS-00045"
  },
  "totals": {
    "balanced": true,
    "totalDebitLCY": 1080.00,
    "totalCreditLCY": 1080.00,
    "totalDebitFCY": 1000.00,
    "totalCreditFCY": 1000.00
  },
  "preview": [
    { "tableId": 17, "tableName": "G/L Entry", "tableCaption": "G/L Entry", "description": "...", "entryCount": 3, "entries": [ /* full row JSON per entry */ ] },
    { "tableId": 254, "tableName": "VAT Entry", "entryCount": 1, "entries": [ ] },
    { "tableId": 32, "tableName": "Item Ledger Entry", "entryCount": 1, "entries": [ ] },
    { "tableId": 5802, "tableName": "Value Entry", "entryCount": 1, "entries": [ ] },
    { "tableId": 21, "tableName": "Cust. Ledger Entry", "entryCount": 1, "entries": [ { "Amount": 1000.00, "AmountLCY": 1080.00, "CurrencyCode": "EUR" } ] },
    { "tableId": 380, "tableName": "Detailed Cust. Ledg. Entry", "entryCount": 1, "entries": [ ] }
    /* additional populated tables (e.g. Job Ledger Entry, FA Ledger Entry, Bank Account Ledger Entry, ...) appear here when the document touches them */
  ]
}

Response Fields:

Currency Invariant:

documentCurrencyCode == "" ⇒ documentExchangeRate == 1 ∧ totalDebitFCY == totalDebitLCY ∧ totalCreditFCY == totalCreditLCY

When the document is in LCY, the FCY columns mirror the LCY columns and the exchange rate is 1. Per-entry currency context is also available on each multi-currency entry (CurrencyCode, Amount, AmountLCY).

Predicted vs Actual: Between preview and actual posting another transaction may consume the predicted No. Series numbers, so the actual posted numbers may differ. Use predictedNumbers for informational display only.

Error Scenarios:

Related Message Types:


Customer.Application.Post

Purpose: Apply one customer ledger entry (the applying entry) against one or more open customer ledger entries (the applied-to entries) and post the application via Microsoft codeunit 226 "CustEntry-Apply Posted Entries".

Description: Mirrors the behaviour of the Apply Customer Entries page. The applying entry's "Applies-to ID" and "Amount to Apply" are stamped, each target entry is tagged with the same Applies-to ID, and CustEntry-Apply Posted Entries.Apply posts the application. All entries must belong to the same customer.

Message Direction: Inbound

Supported Tables: Cust. Ledger Entry (21)

Request Format

Cloud Event Parameters:

ParameterRequiredDescription
subjectYes*SystemId (GUID) or Entry No. (integer) of the applying customer ledger entry
typeYesCustomer.Application.Post

*The applying entry may also be identified via systemId, recordSystemId, id, entryNo or entryNumber in the request JSON.

Request JSON:

FieldTypeRequiredDescription
appliesToEntriesArrayYesNon-empty array of target entries to apply. Each element may be an integer (Entry No.), a GUID string (SystemId), or an object with entryNo / entryNumber / systemId / recordSystemId / id.
postingDateDateNoPosting date of the application. Defaults to the applying entry's posting date.
documentNoCode[20]NoDocument No. stamped on the application. Defaults to the applying entry's document no.
amountToApplyDecimalNoAmount to apply from the applying entry. Defaults to the entry's Remaining Amount.

Example Request

{
  "specversion": "1.0",
  "type": "Customer.Application.Post",
  "subject": "1234",
  "data": {
    "appliesToEntries": [5678, 5679],
    "postingDate": "2025-02-15",
    "documentNo": "PAY-2025-0001",
    "amountToApply": 1500.00
  }
}

Response Format

{
  "status": "Success",
  "applyingEntryNo": 1234,
  "applyingRecordSystemId": "a1b2c3d4-...",
  "customerNo": "10000",
  "documentNo": "PAY-2025-0001",
  "postingDate": "2025-02-15",
  "amountToApply": "1500.00",
  "totalApplied": "1500.00",
  "remainingAmount": "0.00",
  "open": false,
  "applications": [
    {
      "entryNo": 5678,
      "recordSystemId": "...",
      "documentType": "Invoice",
      "documentNo": "INV-1001",
      "amountApplied": "1000.00"
    },
    {
      "entryNo": 5679,
      "recordSystemId": "...",
      "documentType": "Invoice",
      "documentNo": "INV-1002",
      "amountApplied": "500.00"
    }
  ]
}

Response Fields

FieldTypeDescription
statusTextSuccess or Error
applyingEntryNoIntegerEntry No. of the applying entry
applyingRecordSystemIdGUIDSystemId of the applying entry
customerNoCode[20]Customer No. of the applying entry
documentNoCode[20]Document No. used for the application
postingDateDatePosting date used for the application
amountToApplyDecimalAmount that was set as Amount to Apply on the applying entry
totalAppliedDecimalSum of amountApplied across all target entries
remainingAmountDecimalRemaining amount on the applying entry after the application
openBooleanWhether the applying entry is still open after the application
applicationsArrayOne entry per target. See below.
applications[].entryNoIntegerEntry No. of the target entry
applications[].recordSystemIdGUIDSystemId of the target entry
applications[].documentTypeTextDocument type of the target entry
applications[].documentNoCode[20]Document No. of the target entry
applications[].amountAppliedDecimalAmount that was applied against the target entry

Configuration

None. The implementation uses Microsoft codeunit 226 and standard customer ledger entries directly.

Error Scenarios

Related Message Types


Customer.Application.Reverse

Purpose: Reverse (unapply) a posted application on a customer ledger entry via Microsoft codeunit 226 "CustEntry-Apply Posted Entries.PostUnApplyCustomer".

Description: By default the most recent application on the supplied entry is reversed. A specific application can be targeted by passing detailedEntryNo. Microsoft codeunit 226 enforces unapply rules (e.g. no later transactions that depend on this application).

Message Direction: Inbound

Supported Tables: Cust. Ledger Entry (21)

Request Format

Cloud Event Parameters:

ParameterRequiredDescription
subjectYes*SystemId (GUID) or Entry No. (integer) of the customer ledger entry whose application should be reversed
typeYesCustomer.Application.Reverse

*The entry may also be identified via systemId, recordSystemId, id, entryNo or entryNumber in the request JSON.

Request JSON:

FieldTypeRequiredDescription
detailedEntryNoIntegerNoDetailed Cust. Ledg. Entry No. of the application to reverse. Defaults to the last application on the entry.
postingDateDateNoPosting date of the reversal. Defaults to the application's posting date.
documentNoCode[20]NoDocument No. stamped on the reversal. Defaults to the application's document no.

Example Request

{
  "specversion": "1.0",
  "type": "Customer.Application.Reverse",
  "subject": "1234",
  "data": {
    "postingDate": "2025-02-15",
    "documentNo": "REV-2025-0001"
  }
}

Response Format

{
  "status": "Success",
  "entryNo": 1234,
  "recordSystemId": "...",
  "customerNo": "10000",
  "reversedDetailedEntryNo": 5678,
  "reversedAmount": "1500.00",
  "postingDate": "2025-02-15",
  "documentNo": "REV-2025-0001",
  "remainingAmount": "1500.00",
  "open": true
}

Response Fields

FieldTypeDescription
statusTextSuccess or Error
entryNoIntegerEntry No. of the customer ledger entry
recordSystemIdGUIDSystemId of the customer ledger entry
customerNoCode[20]Customer No. of the entry
reversedDetailedEntryNoIntegerDetailed Cust. Ledg. Entry No. that was reversed
reversedAmountDecimalAmount that was reversed
postingDateDatePosting date used for the reversal
documentNoCode[20]Document No. used for the reversal
remainingAmountDecimalRemaining amount on the entry after the reversal
openBooleanWhether the entry is open after the reversal

Configuration

None. The implementation uses Microsoft codeunit 226 directly.

Error Scenarios

Related Message Types


Sales.Quote.MakeOrder

Purpose: Convert a sales quote into a sales order.

Direction: Inbound (Action request)

Filter Table: Sales Header (36)

Description: Invokes the standard BC Codeunit "Sales-Quote to Order" (codeunit 86) to convert an existing sales quote into a sales order. The original quote is deleted and a new sales order is created with the same customer, lines, and dimensions. Returns the new order number along with key header fields.

Request Format

ParameterRequiredDescription
sourceYesCalling application identifier
subjectYesQuote document number or SystemId (GUID) of the Sales Header

Subject Identification Order

The subject value is resolved via FindSalesHeader:

  1. If subject is a valid GUID ? GetBySystemId
  2. Otherwise ? Get by document number across all sales document types

The resolved document must have Document Type = Quote, otherwise an error is returned.

Example Request

{
  "specversion": "1.0",
  "type": "Sales.Quote.MakeOrder",
  "source": "MyApp v1.0",
  "subject": "SQ-001"
}

Response Format (Success)

{
  "status": "Success",
  "quoteNo": "SQ-001",
  "orderNo": "SO-005",
  "orderSystemId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "customerNo": "10000",
  "customerName": "Adatum Corporation",
  "documentDate": "2026-03-07",
  "orderDate": "2026-03-07"
}

Response Fields

FieldTypeDescription
statusTextSuccess on success, Error on failure
quoteNoCode[20]Number of the original quote that was converted
orderNoCode[20]Number of the newly created sales order
orderSystemIdGuidSystemId (GUID) of the new sales order header
customerNoCode[20]Sell-to customer number
customerNameTextSell-to customer name
documentDateDateISO date (yyyy-MM-dd) � document date of the new order
orderDateDateISO date (yyyy-MM-dd) � order date of the new order

Error Responses

ErrorCause
Subject parameter is required.Subject was empty
Sales document {No} not found.No sales header matches the subject
Sales document {No} is not a Quote (actual type: {Type}).Subject resolved to a non-Quote document
Error text from BCThe standard Sales-Quote to Order codeunit raised an error (callstack included as callstack field)

Related Message Types


Sales.BlanketOrder.MakeOrder

Purpose: Convert a sales blanket order into a sales order.

Direction: Inbound (Action request)

Filter Table: Sales Header (36)

Description: Invokes the standard BC Codeunit "Blanket Sales Order to Order" (codeunit 87) to create a new sales order from a blanket order. Lines with Qty. to Ship > 0 are transferred to the new order; the blanket order remains and outstanding quantities are reduced accordingly.

Request Format

ParameterRequiredDescription
sourceYesCalling application identifier
subjectYesBlanket order document number or SystemId (GUID) of the Sales Header

Subject Identification Order

  1. If subject is a valid GUID ? GetBySystemId
  2. Otherwise ? Get by document number across all sales document types

The resolved document must have Document Type = Blanket Order, otherwise an error is returned.

Prerequisites

Each blanket-order line that should be transferred must have Qty. to Ship > 0 (use Data.Records.Set first to set the values). Lines with zero Qty. to Ship are skipped.

Example Request

{
  "specversion": "1.0",
  "type": "Sales.BlanketOrder.MakeOrder",
  "source": "MyApp v1.0",
  "subject": "SB-001"
}

Response Format (Success)

{
  "status": "Success",
  "blanketOrderNo": "SB-001",
  "orderNo": "SO-006",
  "orderSystemId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "customerNo": "10000",
  "customerName": "Adatum Corporation",
  "documentDate": "2026-03-07",
  "orderDate": "2026-03-07"
}

Response Fields

FieldTypeDescription
statusTextSuccess on success, Error on failure
blanketOrderNoCode[20]Number of the source blanket order
orderNoCode[20]Number of the newly created sales order
orderSystemIdGuidSystemId (GUID) of the new sales order header
customerNoCode[20]Sell-to customer number
customerNameTextSell-to customer name
documentDateDateISO date (yyyy-MM-dd) � document date of the new order
orderDateDateISO date (yyyy-MM-dd) � order date of the new order

Error Responses

ErrorCause
Subject parameter is required.Subject was empty
Sales document {No} not found.No sales header matches the subject
Sales document {No} is not a Blanket Order (actual type: {Type}).Subject resolved to a non-blanket document
Error text from BCThe standard Blanket Sales Order to Order codeunit raised an error (e.g. no lines with Qty. to Ship > 0); callstack included as callstack field

Related Message Types


Sales.SalesInvoice.Correct

Purpose: Cancel a posted sales invoice and start a new draft sales invoice for correction.

Description: Wraps BC standard codeunit 1303 Correct Posted Sales Invoice method CancelPostedInvoiceCreateNewInvoice. Posts a corrective credit memo against the original invoice and creates a new draft Sales Header (Document Type = Invoice) initialised from the original invoice.

Message Direction: Inbound

Posting Gate: G/L. The request is rejected when G/L posting is disabled in Cloud Events Setup.

Identifier Resolution Order: GUID via Subject (SystemId) ? Subject as No. (Get) ? JSON keys (systemId, recordSystemId, id, invoiceNo, no, documentNo).

Input Parameters:

{
  "type": "Sales.SalesInvoice.Correct",
  "subject": "POST-INV-000123"
}

Or by SystemId:

{
  "type": "Sales.SalesInvoice.Correct",
  "subject": "5f0d3b6e-3e8e-4a8b-9f6b-1d3c4e5f6a7b"
}

Or by JSON data:

{
  "type": "Sales.SalesInvoice.Correct",
  "data": { "invoiceNo": "POST-INV-000123" }
}

Response Format:

{
  "status": "Success",
  "originalInvoiceNo": "POST-INV-000123",
  "originalInvoiceId": "5f0d3b6e-3e8e-4a8b-9f6b-1d3c4e5f6a7b",
  "customerNo": "C00010",
  "customerName": "Customer Ltd.",
  "cancellingCreditMemo": {
    "no": "PCM-000456",
    "id": "1a2b3c4d-..."
  },
  "newDraftInvoice": {
    "no": "SI-000789",
    "id": "9f8e7d6c-...",
    "documentType": "Invoice"
  }
}

Response Fields:

Process Flow:

  1. Resolve the posted invoice from subject or request JSON.
  2. Enforce the G/L posting gate.
  3. Run BC CancelPostedInvoiceCreateNewInvoice inside an isolated Codeunit.Run so BC errors are returned as JSON with full callstack.
  4. BC posts a cancelling sales credit memo, fully applies it to the original invoice, and creates a new draft Sales Header (Document Type = Invoice) copied from the original.
  5. The cancelling credit memo is looked up via the Cancelled Document link table (Source ID = 112, Cancelled Doc. No. = original invoice).
  6. Original, cancelling credit memo, and new draft are returned in a single JSON response.

Output Documents:

RoleBC TableIdentifier in Response
Original posted invoice (now Cancelled)Sales Invoice HeaderoriginalInvoiceId / originalInvoiceNo
Cancelling sales credit memo (posted, fully applied)Sales Cr.Memo HeadercancellingCreditMemo.id / .no
New editable draft invoiceSales Header (Document Type = Invoice)newDraftInvoice.id / .no

Document Linkage:

Fetching the Resulting Documents with Data.Records.Get:

Each id is the BC SystemId. Use it with Data.Records.Get:

{ "type": "Data.Records.Get", "data": { "tableName": "Sales Header", "tableView": "WHERE(SystemId=CONST(<newDraftInvoice.id>))" } }
{ "type": "Data.Records.Get", "data": { "tableName": "Sales Cr.Memo Header", "tableView": "WHERE(SystemId=CONST(<cancellingCreditMemo.id>))" } }
{ "type": "Data.Records.Get", "data": { "tableName": "Sales Line", "tableView": "WHERE(Document Type=CONST(Invoice),Document No.=CONST(<newDraftInvoice.no>))" } }
{ "type": "Data.Records.Get", "data": { "tableName": "Sales Cr.Memo Line", "tableView": "WHERE(Document No.=CONST(<cancellingCreditMemo.no>))" } }
{ "type": "Data.Records.Get", "data": { "tableName": "Cancelled Document", "tableView": "WHERE(Source ID=CONST(112),Cancelled Doc. No.=CONST(<originalInvoiceNo>))" } }

Error Scenarios:

Related Message Types:


Sales.SalesInvoice.Cancel

Purpose: Cancel a posted sales invoice by posting a corrective credit memo.

Description: Wraps BC standard codeunit 1303 Correct Posted Sales Invoice method CancelPostedInvoice. Posts a corrective credit memo against the original invoice. Unlike Correct, no new draft invoice is created.

Message Direction: Inbound

Posting Gate: G/L. The request is rejected when G/L posting is disabled in Cloud Events Setup.

Identifier Resolution Order: Identical to Sales.SalesInvoice.Correct.

Input Parameters:

{
  "type": "Sales.SalesInvoice.Cancel",
  "subject": "POST-INV-000123"
}

Response Format:

{
  "status": "Success",
  "originalInvoiceNo": "POST-INV-000123",
  "originalInvoiceId": "5f0d3b6e-...",
  "customerNo": "C00010",
  "customerName": "Customer Ltd.",
  "cancellingCreditMemo": {
    "no": "PCM-000456",
    "id": "1a2b3c4d-..."
  }
}

The newDraftInvoice object is intentionally omitted.

Process Flow:

  1. Resolve the posted invoice from subject or request JSON.
  2. Enforce the G/L posting gate.
  3. Run BC CancelPostedInvoice inside an isolated Codeunit.Run so BC errors are returned as JSON with full callstack.
  4. BC posts a cancelling sales credit memo and fully applies it to the original invoice. No draft is created.
  5. The cancelling credit memo is looked up via the Cancelled Document link table (Source ID = 112, Cancelled Doc. No. = original invoice).
  6. Original invoice and cancelling credit memo are returned in a single JSON response.

Output Documents:

RoleBC TableIdentifier in Response
Original posted invoice (now Cancelled)Sales Invoice HeaderoriginalInvoiceId / originalInvoiceNo
Cancelling sales credit memo (posted, fully applied)Sales Cr.Memo HeadercancellingCreditMemo.id / .no

Document Linkage:

Fetching the Resulting Documents with Data.Records.Get:

{ "type": "Data.Records.Get", "data": { "tableName": "Sales Cr.Memo Header", "tableView": "WHERE(SystemId=CONST(<cancellingCreditMemo.id>))" } }
{ "type": "Data.Records.Get", "data": { "tableName": "Sales Cr.Memo Line", "tableView": "WHERE(Document No.=CONST(<cancellingCreditMemo.no>))" } }
{ "type": "Data.Records.Get", "data": { "tableName": "Sales Invoice Header", "tableView": "WHERE(No.=CONST(<originalInvoiceNo>))" } }
{ "type": "Data.Records.Get", "data": { "tableName": "Cancelled Document", "tableView": "WHERE(Source ID=CONST(112),Cancelled Doc. No.=CONST(<originalInvoiceNo>))" } }

Error Scenarios: Same as Sales.SalesInvoice.Correct.

Related Message Types:


Sales.SalesInvoice.Send

Purpose: Send a posted sales invoice through Business Central's standard send pipeline using a resolved Document Sending Profile.

Description: Wraps BC standard Sales Invoice Header.SendProfile(var "Document Sending Profile"). The profile to use is determined by a three-step resolution chain (request override → customer profile → system default). The send action itself runs through the standard BC dispatcher and respects every option (E-Mail, Disk, Printer, Electronic Document) configured on the resolved profile.

Message Direction: Inbound

Posting Gate: None. Sending a document does not produce ledger entries.

Profile Resolution Order:

  1. Request override — if the request includes a documentSendingProfile code, it is loaded and used. If the code does not exist, the request fails with Document Sending Profile {code} not found.. Response field documentSendingProfileSource = Request.
  2. Customer profile — if the customer's Document Sending Profile field is set, it is loaded and used. If the customer references a code that no longer exists, the request fails with Customer {no} references Document Sending Profile {code} which no longer exists.. Response field documentSendingProfileSource = Customer.
  3. System default — the first Document Sending Profile with Default = true is used. Response field documentSendingProfileSource = Default.
  4. No match — if none of the above resolves, the request fails with No Document Sending Profile resolved for customer {no} and no system default exists..

Identifier Resolution Order:

  1. data.invoiceNo
  2. data.invoiceId (SystemId)
  3. subject (either an invoice number or a SystemId GUID; GUIDs are detected automatically)

Input Parameters:

{
  "type": "Sales.SalesInvoice.Send",
  "subject": "POST-INV-000123",
  "data": {
    "documentSendingProfile": "EMAIL"
  }
}
ParameterTypeRequiredNotes
subjectTextOne of subject / invoiceNo / invoiceId is requiredInvoice no. or SystemId GUID
data.invoiceNoCode[20]OptionalWins over subject and invoiceId
data.invoiceIdGUIDOptionalUsed if invoiceNo is not supplied
data.documentSendingProfileCode[20]OptionalOverrides the customer + default resolution chain

Success Response:

{
  "status": "Success",
  "documentType": "PostedSalesInvoice",
  "documentNo": "POST-INV-000123",
  "documentId": "5f0d3b6e-1234-5678-90ab-cdef12345678",
  "customerNo": "C00010",
  "customerName": "Customer Ltd.",
  "documentSendingProfileCode": "EMAIL",
  "documentSendingProfileSource": "Request",
  "message": "Document sent successfully."
}

Error Response:

{
  "status": "Error",
  "error": "Document Sending Profile NOSUCH not found.",
  "callstack": "..."
}

Response Fields:

FieldTypeDescription
statusTextSuccess or Error
documentTypeTextAlways PostedSalesInvoice for this message type
documentNoCode[20]Posted invoice number
documentIdGUIDPosted invoice SystemId
customerNoCode[20]Sell-to customer number
customerNameTextCustomer name
documentSendingProfileCodeCode[20]The profile actually used to send
documentSendingProfileSourceTextRequest, Customer, or Default — which step of the resolution chain matched
messageTextHuman-readable summary
errorTextPresent only on Error — the underlying message
callstackTextPresent only on Error — full BC callstack for diagnostics

Error Scenarios:

ErrorCause
Subject parameter is required. Provide the invoice number or SystemId.No identifier supplied in subject, invoiceNo, or invoiceId
Sales Invoice {no} not found.Identifier supplied but no matching Sales Invoice Header row
Document Sending Profile {code} not found.Request override code does not exist
Customer {no} references Document Sending Profile {code} which no longer exists.Customer profile code is dangling
No Document Sending Profile resolved for customer {no} and no system default exists.No override, no customer profile, no default
(BC SendProfile errors)Surfaced verbatim through error + callstack (e.g., missing e-mail account, unconfigured electronic document setup)

Notes:

Related Message Types:


Sales.SalesCreditMemo.Send

Purpose: Send a posted sales credit memo through Business Central's standard send pipeline using a resolved Document Sending Profile.

Description: Wraps BC standard Sales Cr.Memo Header.SendProfile(var "Document Sending Profile"). Profile resolution is identical to Sales.SalesInvoice.Send.

Message Direction: Inbound

Posting Gate: None.

Profile Resolution Order: Identical to Sales.SalesInvoice.Send.

Identifier Resolution Order:

  1. data.creditMemoNo
  2. data.creditMemoId (SystemId)
  3. subject

Input Parameters:

{
  "type": "Sales.SalesCreditMemo.Send",
  "subject": "POST-CRM-000456",
  "data": {
    "documentSendingProfile": "EMAIL"
  }
}
ParameterTypeRequiredNotes
subjectTextOne of subject / creditMemoNo / creditMemoId is requiredCredit memo no. or SystemId GUID
data.creditMemoNoCode[20]OptionalWins over subject and creditMemoId
data.creditMemoIdGUIDOptionalUsed if creditMemoNo is not supplied
data.documentSendingProfileCode[20]OptionalOverrides the customer + default resolution chain

Success Response:

{
  "status": "Success",
  "documentType": "PostedSalesCreditMemo",
  "documentNo": "POST-CRM-000456",
  "documentId": "1a2b3c4d-5678-90ab-cdef-1234567890ab",
  "customerNo": "C00010",
  "customerName": "Customer Ltd.",
  "documentSendingProfileCode": "EMAIL",
  "documentSendingProfileSource": "Customer",
  "message": "Document sent successfully."
}

Error Response:

{
  "status": "Error",
  "error": "Sales Credit Memo POST-CRM-999999 not found.",
  "callstack": "..."
}

Response Fields: Same as Sales.SalesInvoice.Send except documentType = PostedSalesCreditMemo.

Error Scenarios: Same as Sales.SalesInvoice.Send except the document-not-found error is Sales Credit Memo {no} not found..

Related Message Types:


© Origo – Cloud Events Base Extension