Skip to Content
Technical Articles

SAP Business ByDesign – OData API Examples

The SAP Business ByDesign (ByD) provides REST/OData APIs to access ByD business objects, reports and data sources:

  • The OData API for Reports is tailored for remote access to pre-processed and formatted analytical data (reports). The remote application may extract a ByD analytical model as a cube incl. semantics like key figures, language-dependent texts and aggregated data.
  • The OData API for Data Sources is designed to extract analytical raw data (data sources) in flat tables, free of redundancies from ByD.
  • The OData API for Business Objects is designed for UI-driven access to ByD business objects. A UI-like remote application or system interactively queries, reads, creates, updates, deletes or performs actions on ByD business objects and business documents. Using the work center “Application and User Management – OData Services“, key users are empowered to decide which business objects, nodes, elements and actions are exposed via OData API.

You find more information about ByD APIs in blog post SAP Business ByDesign – API Overview.

Where do I get OData examples?

To get some hands-on experience using SAP Business ByDesign OData APIs you find a repository of API Examples on GitHubSAP Business ByDesign – API Samples.

The GitHub repository provides sample ByD Custom OData Services for currently 44 business objects and 6 Postman collections with more than 600 example OData requests. The Postman collections illustrate hands-on how to access master data, business documents and analytical data in context of ByD business processes with a focus on ByD OData APIs.

All sample Postman collections are tailored to SAP Business ByDesign Partner Demo Tenants (Full scope US) with preconfigured and loaded sample data provided by SAP.

Nevertheless you can use the Postman collections and sample Custom OData Services in other ByD systems as well, if you adopt Postman environment variables and Postman requests according the business configuration and master data of your ByD system.

The GitHub repository contains the following Postman collecions:

  • Analytics – Data Sources: Extract analytical raw data (data sources) from the ByD.
  • Analytics – Reports: Extract pre-processed, aggregated and formatted reporting data from ByD.
  • Master Data: Access ByD master data objects using APIs
    • Organizational Structure
    • Material
    • Service Product
    • Sales Price
    • Business Partner
    • Customer
    • Supplier
    • Employee and Position
    • Code lists
  • Reference Scenarios: Run ByD business processes using APIs to get insights how to create, change and read involved business documents and how to create business document relationships to achieve a meaningful document flow
    • Lead to opportunity to quote
    • Order to cash for services
    • Procure to pay for services
    • Field service and repair
    • Procure to stock
    • Sell from stock
    • Drop shipment
    • Make to stock
    • Clear due items using bank statements
  • Projects: Create, change and read cost collecting projects and customer projects
    • Cost collection project with task hierarchy
    • Cost collecting project with project team and work
    • Customer project with planning data
    • Sell project-based services (sales order > project > project time recordings)
  • Sales and Commerce Scenarios: Run ByD sales and commerce processes using APIs to get insights how to create, change and read involved business documents and how to create business document relationships to achieve a meaningful document flow.
    • Sell from stock with external payment
    • Create customer invoices with external payment
    • Customer return to stock
    • Pre-confirm payments using clearing house statements
    • Confirm payments using bank statements
    • Create sales orders using a nested create, batch and node-by-node
    • Create sales orders with attachments
    • Create sales orders with externally provided prices, discounts and surcharges

Please check the description of the respective Postman collection for further details.

How to run API examples?

The easiest way to run an API sample scenario would be using a SAP Business ByDesign Partner Demo Tenant (Full scope US) with preconfigured and loaded sample data provided by SAP.
The following example is based on such a tenant and I am running the scenario “Master Data – Service Product (write)“:

  1. Install the API sample package “Master Data and configure your ByD system following the instructions in  chapters “Download and Installation” and “Configuration” of the GitHub repository readme file.
  2. Open the Postman Runner and select the collection “Master Data, the collection folder “Service Product (write)and the environment “Master Data“:
  3. Click on “Run Service Product (write)” and see the process flow:

For more detailed analysis you can open the Postman Console to log detailed traces or simply execute the requests one-by-one in the Postman collection itself.

By the way:
The sample Postman collections may serve as well as approach to create meaningful data along process chains to prepare a ByD system for demo purposes, or to run regression tests by processing end-to-end business processes.

Blog Posts with further Examples

16 Comments
You must be Logged on to comment or reply to a post.
  • Update of API sample package “End-to-End Scenarios”:

    • Sample OData service tmserviceorder.xml enhanced by service order lifecycle status
    • Scenario “Drop Shipment”: SOAP request to create third-party delivery notification replaced by corresponding OData request.
    • Scenario “Procure to Stock”: Request “Accept supplier invoice exception” removed (not needed after ByD update to SP02)
  • Thanks Knut Heusermann  for this very helpful blog.

    We have a doubt about Sales Order Item Pricing:

    We are building an integration which fits on “Selling Services Scenario” provided on the API Sample Package.

    Since our Services are not price defined, we tried to create a SalesOrder indicating the price on each Item, but we got an error.

    We also tried to update the SalesOrder when it is created, and since we get no error, the price is not updated.

    Could help us with that? We saw that it is possible to do on SOAP, but for this integration we are building, REST is a Must.

    Thank you.

  • Update of API sample package “Projects”: Added a sample Custom OData Service and corresponding Postman OData requests to create and read project time recordings.

  • Hello.

    Using the provided POST request “Update fulfilled quantity” in the “Field Service and repair” Scenario, we are getting the following error:

    The server has not found any resource matching the Data Services Request URI.

    Has anyone ever found a solution for this?

    Thank you in advance.

     

     

    • Hi Marc,

      I’m using Postman environment variables in the OData URL. Those variables are either values provided or are populated by previous requests.

      In your request the environment variable “ServiceConfirmationItemScheduleLineObjectID” seems to be empty or invalid. Please enter a valid value for variable “ServiceConfirmationItemScheduleLineObjectID” in your Postman environment or run the OData requests of folder “Field Service and Repair” in the given sequence such that the variable is populated by request “Get service confirmation” (see Postman request test script of request “Get service confirmation”).

      Best regards,
      Knut

  • Hi Knut,

    We’ve got a requirement to create Customer Invoice Requests directly via OData rather than via Sales Orders. Looking at the PSM, it should be possible to create a Customer Invoice Request by setting Business Process Variant Type to 3 (for a manual request), the CustomerInvoiceProcessingTypeCode to CI and buy setting the buyer party and sales unit party (as well as items of course).

    I’ve taken your example web service for Selling Services and have imported the customer invoice request service into my BYD tenant and then altered the service to expose the relevant fields and objects.

    However when I try to create a request with a POST, I find that the Sales Unit Party is read only. I am able to set the Business Process Variant Type, and the CustomerInvoiceProcessingTypeCode but the sales unit party ID is read only.

    Is this why you’ve used a sales order and then released the order, and then get the invoice request from the sales order ID, because you ca’t create an invoice request directly?

    Greg

    • Hi Greg,

      I’m using sales orders because of the scenario that I realized (for example incl. deliveries and ATP check); using sales orders was not intended as workaround for creating invoice requests directly.

      You can change the sales unit party of customer invoice requests by a Patch on the corresponding resource of the SalesUnitPartyCollection. The fact that you can’t create the sales unit party with the invoice request directly is a gap in our PSM for OData.
      However, if you dig deeper you will find out that there are more invoice request elements not yet create/update enabled or missing and hence as of today you can’t create an external customer invoice request using OData.
      For that reason, I would suggest to use the SOAP API Manage Customer Invoice Requests to create external customer invoice requests. This API provides you with the possibility to create and change invoice requests incl. prices and external payments, and you can furthermore trigger invoicing directly.

      Here is an example for an invoice request using API Manage Customer Invoice Requests:

      <?xml version="1.0" encoding="UTF-8"?>
      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:glob="http://sap.com/xi/SAPGlobal20/Global" xmlns:glob1="http://sap.com/xi/AP/Globalization">
          <soapenv:Header/>
          <soapenv:Body>
              <glob:CustomerInvoiceRequestBundleMaintainRequest_sync>
                  <BusinessDocumentBasicMessageHeader>
                      <!-- Enter message header UUID for idem potency! -->
                      <!-- <UUID>?</UUID> -->
                  </BusinessDocumentBasicMessageHeader>
                  <CustomerInvoiceRequest actionCode="01" itemListCompleteTransmissionIndicator="false">
                      <ObjectNodeSenderTechnicalID>HDR_1</ObjectNodeSenderTechnicalID>
                      <BaseBusinessTransactionDocumentID>{{CustomerInvoiceRequestID}}</BaseBusinessTransactionDocumentID>
                      <Name>My customer invoice with external payment</Name>
                      <!-- SettlementPriorityCode: 
                       1 = Immediate - create custom invoice, 
                       2 = Urgent - stop if a down payment exists
                       3 = Normal - save invoice request with status "to be invoiced" -->
                      <SettlementPriorityCode>1</SettlementPriorityCode>
                      <ReferenceBusinessTransactionDocumentID>{{InvoiceRequestExternalReference}}</ReferenceBusinessTransactionDocumentID> <!-- External Reference -->
                      <BuyerParty>
                          <InternalID>{{CustomerID}}</InternalID>
                      </BuyerParty>
                      <SalesUnitParty>
                          <InternalID>{{SalesUnitID}}</InternalID>
                      </SalesUnitParty>
                      <CashDiscountTerms>
                          <!-- 1001 = immediately net; 1006 = 10 days 5% -->
                          <Code>1001</Code>
                          <!-- <FullPaymentEndDate>2019-05-30</FullPaymentEndDate> -->
                      </CashDiscountTerms>
                      <PaymentControl>
                          <!-- PaymentFormCode: 04 = Direct Debit, 20 = External Payment -->
                          <PaymentFormCode>20</PaymentFormCode>
                          <PaymentReferenceID>{{PaymentReferenceID}}</PaymentReferenceID>
                          <!-- used to clear the payment -->
                          <PaymentReferenceTypeCode>5</PaymentReferenceTypeCode>
                          <PaymentServiceSubscriberID>{{CompanyID}}</PaymentServiceSubscriberID>
                          <PaymentServiceCustomerID>{{CustomerID}}</PaymentServiceCustomerID>
                          <ExternalPayment actionCode="01">
                              <!-- <UUID>?</UUID> -->
                              <!-- Bank Account ID from UI screen My Bank >> View All >> Bank Accounts -->
                              <HouseBankAccountKeyInternalID>{{HouseBankAccountID}}</HouseBankAccountKeyInternalID>
                              <!-- House bank: 1000644 - ABN AMRO Bank -->
                              <PaymentTransactionReferenceID>{{PaymentTransactionReferenceID}}</PaymentTransactionReferenceID>
                              <DocumentDate>{{DocumentDate}}</DocumentDate>
                              <ValueDate>{{ValueDate}}</ValueDate>
                              <Amount currencyCode="USD">220</Amount>
                          </ExternalPayment>
                      </PaymentControl>
                      <PricingTerms>
                          <!-- PricingProcedureCode: PPGP02 = Standard Gross Procedure, PPSTD1 = Standard Procedure -->
                          <PricingProcedureCode>PPGP02</PricingProcedureCode>
                          <CurrencyCode>USD</CurrencyCode>
                      </PricingTerms>
      <!-- Invoice item | service product | tax code derived by system -->
                      <Item>
                          <BaseBusinessTransactionDocumentItemID>10</BaseBusinessTransactionDocumentItemID>
                          <!-- ReceivablesPropertyMovementDirectionCode: 1 = Invoice item, 2 = Credit memo item -->
                       <ReceivablesPropertyMovementDirectionCode>2</ReceivablesPropertyMovementDirectionCode>
                          <!-- <Description languageCode="EN">My invoice item</Description> -->
                          <CashDiscountDeductibleIndicator>false</CashDiscountDeductibleIndicator>
                          <Product>
                              <InternalID>{{ServiceProductID2}}</InternalID>
                              <TypeCode>2</TypeCode>
                          </Product>
                          <Quantity unitCode="HUR">10</Quantity>
                          <QuantityTypeCode>TIME</QuantityTypeCode>
                          <PriceAndTax>
                              <!-- List Price -->
                              <PriceComponent>
                                  <!-- TypeCode: 8PR1 = Gross list price, 7PR1 = Net list price -->
                                  <TypeCode>8PR1</TypeCode>
                                  <Rate>
                                      <DecimalValue>120</DecimalValue>
                                      <CurrencyCode>USD</CurrencyCode>
                                      <BaseDecimalValue>10</BaseDecimalValue>
                                      <BaseMeasureUnitCode>HUR</BaseMeasureUnitCode>
                                  </Rate>
                              </PriceComponent>
                          </PriceAndTax>
                          <ObjectNodeSenderTechnicalID>ITM_1</ObjectNodeSenderTechnicalID>
                      </Item>
      <!-- Invoice item | free text -->
                      <Item>
                          <BaseBusinessTransactionDocumentItemID>20</BaseBusinessTransactionDocumentItemID>
                          <ReceivablesPropertyMovementDirectionCode>2</ReceivablesPropertyMovementDirectionCode>
                          <Description languageCode="EN">My free text invoice item</Description>
                          <CashDiscountDeductibleIndicator>false</CashDiscountDeductibleIndicator>
                          <Quantity unitCode="EA">1</Quantity>
                          <QuantityTypeCode>EA</QuantityTypeCode>
                          <PriceAndTax>
                              <!-- List Price -->
                              <PriceComponent>
                                  <TypeCode>8PR1</TypeCode>
                                  <Rate>
                                      <DecimalValue>100.00</DecimalValue>
                                      <CurrencyCode>USD</CurrencyCode>
                                  </Rate>
                              </PriceComponent>
                          </PriceAndTax>
                          <ProductTaxDetails>
                              <ProductTaxationCharacteristicsCode listID="US">500</ProductTaxationCharacteristicsCode>
                          </ProductTaxDetails>
                          <AccountingCodingBlockAssignment>
                              <AccountingCodingBlock>
                                  <AccountingCodingBlockTypeCode>ACC</AccountingCodingBlockTypeCode>
                                  <GeneralLedgerAccountAliasCode>A-1700</GeneralLedgerAccountAliasCode>
                              </AccountingCodingBlock>
                          </AccountingCodingBlockAssignment>
                          <ObjectNodeSenderTechnicalID>ITM_2</ObjectNodeSenderTechnicalID>
                      </Item>
                  </CustomerInvoiceRequest>
              </glob:CustomerInvoiceRequestBundleMaintainRequest_sync>
          </soapenv:Body>
      </soapenv:Envelope>

      Best regards,
      Knut

       

      • Hi Knut,

        Sorry I didn’t thank you for this at the time – for some reason I didn’t get notified that you’d left a response, and I had moved onto something else. I am now back on this piece of work – thank you for the explanation; the gap in the ODATA PSM is still there today.

        I have a problem using the SOAP API though. Unless Sales Orders are scoped in, which in my customer’s tenant it is not, the SOAP API cannot create a Customer Invoice Request. You get a very cryptic error:

        No scheme configuration found for scheme ‘&CIRHP&’

        On another tenant with Sales Orders scoped in, I can create the customer invoice requests no problem. However scoping Sales Orders in is not an option on the tenant I need to do this on. Any advice?

        Greg

        • Hi Greg,

          I don’t think the error message is caused by the Sales Order scoping. Could you please log an incident in ByD to follow up on your issue?

          Thanks and best regards,
          Knut

          • Hi Knut,

            You are correct. After followup, it’s emerged that the option “Upload of Invoice Requests” needs to be in scope. Otherwise you get that very unhelpful error! Thanks again for the help.

            Greg

  • Hi Knut

    I tested your end-to-end scenario field service and repair.
    We also need to read and update the field “Incident Description” in our scenario.
    Can you give me a hint how to update the field?

    Thank you and best regards
    Jasmin

    • Hi Jasmin,

      please do the following:

      1. Add the node Root/TextCollection/Text to the service order OData service. As result you get a collection “ServiceOrderText” (I renamed it to “Text”) in the OData service.
      2. Now you can create, update and read the incident description using this collection. The text referring to the incident description has TypeCode “10006”.

      Text TypeCodes:

      • Incident description: 10006
      • Customer Information: 10024
      • Internal Comment: 10011

      Best regards,
      Knut

      • This example creates a service order incident description:

        POST /sap/byd/odata/cust/v1/tmserviceorder/TextCollection HTTP/1.1
        Host: …
        Content-Type: application/json
        x-csrf-token: …
        Accept: application/json
        cache-control: no-cache
        Postman-Token: …

        {
        “ParentObjectID”: “{{ServiceOrderObjectID}}”,
        “Text”: “Some incident description …”,
        “TypeCode”: “10006”
        }

        I’ll add this example to the next version of the OData samples on Github as well 🙂

         

  • Update: Today I uploaded a new version of API sample packages to the GitHub repository:

    • I restructured the repository to simplify installation and configuration.
    • Refactored and new sample OData services for master data incl. organisational structures, employees, business partners, customer, suppliers, employees, positions, materials and service products
    • Enhanced sample OData services for sales order, customer invoice request, customer invoices, …
    • New examples to order services and procure services
    • New examples to sell products from stock with external payment
    • New examples to process customer returns
    • New examples to pre-confirm payments using clearing house statements
    • New examples to confirm payments and clear open items using bank statements
    • New examples to create and process invoices with external payment
    • New examples to create sales orders with external prices, discounts and surcharges
    • New examples to access the payment monitor
    • Correction of supplier invoice examples to post invoices