Adaco Vendor API Guide & Reference

Introduction

The Adaco Vendor API enables users to add vendors into Adaco and update their details as required. This allows third-party systems, such as accounting software, to act at the master source for vendor information, avoiding double-entry issues as well as ensuring that vendor details are kept up-to-date within Fourth.

This is a SOAP API. There are three methods available:

  • Login — establishes a session
  • InsertVendors — creates one or more vendors in a property
  • UpdateVendors — updates one or more vendors in a property

Quick Facts

Integration type SOAP with XML
Authentication Header authentication via a session ID
Availability Fourth Inventory for Hotels customers
Testing Test environment is available on request
More information N/A

Updates

You can find any updates on the Release Notes page for the Vendor API.

Get Access

Before integrating, you’ll need to set up a new user account in Fourth with access rights to the API. The resources you plan to use determine what access rights are required. 

Step 1: create a user group 

Create a user group for accessing the API within one of your Fourth properties — we recommend the central purchasing (CP) property where there is one.

The Group Details screen. Under "Edit Permissions" the option "API Access" is ticked.

For security, we also recommend that you limit the user group to access to just the “Vendor API”. The setting for this is within the user group's Property > API Access sub-section. The group needs the Create, and Update access right selected for the Vendor API.

The "Access Rights" screen, with the Vendor API options highlighted.

Step 2: create a user account

In the same property, create a user account. Assign it to the API user group.

Step 3: provide the API user the account details

The API user — normally a third-party system — will need to know the following:

  • Username and password for the user account.
  • Property number for the property in which the user account exists. They will need to include this number when making API requests.

Get the property number

Before you can make any Vendor API requests, you will need the property numbers of the Adaco properties. One of our Fourth integration specialist can provide a list of these to you during your initial integration. You can also find a property's property number in the Fourth UI with the rest of the property's details. 

Screenshot with the Property Number highlighted

Creating vendors in the central property vs other properties

Most Adaco customers include a central property (CP), which acts a principal property for purchasing and other features that are relevant to all properties. This includes vendor information. Customers can control for many vendor fields whether the data must align with the CP or not.

  • If a field is controlled by the CP, then you cannot update that field to be individual to each property. For example, MinimumOrder would be the same for all properties. Once the vendor is created in the CP, any value for the field sent to other properties is ignored.
  • If a field is controlled by the individual properties, then you can update the field per property.

Automatic vendor creation

Whenever a vendor is added to a property, Fourth checks to see if the vendor already exists in the CP:

  • If it doesn't exist, then Fourth adds the vendor to both the property and the CP, using the values you have sent in.
  • If it does already exist, then the vendor is added to the property; however, any values controlled by the CP are applied to the property.

Adding vendors to properties

You must create the vendor in each property separately, using the same AccountsPayableXreference for the vendor.

Recommendation: Unless otherwise advised, don't add the vendor directly to the CP (InsertVendors method). Instead, add the vendor to your non-CP properties and allow Adaco to add the vendor to the CP automatically. This stops the API from returning an error if you later try to add the vendor in the non-CP property.

Updates to CP-controlled fields

Once you have a vendor in Adaco, then you can only update vendor fields that are controlled by the CP by sending through an UpdateVendors request to the CP. The updates are then replicated in the other Adaco properties.

CPQuoteControl

When using this API, you will have to specify whether vendor pricing is managed by each property, or by the CP. The XML element used for this is called CPQuoteControl. However, Fourth will always seek to keep the records aligned between the CP and other properties. This means for a specific vendor, either all properties can manage pricing independently, or only the CP manages the vendor pricing.

Whenever a vendor is added to a property, Fourth checks to see if the vendor already exists in the CP:

  • If it doesn't exist, then the pricing is managed by the CPQuoteControl setting you have sent through. Adaco then creates a vendor record in the CP with this as the default setting.
  • If it does already exist, then the CPQuoteControl value in the CP is applied to the property.

To change the CPQuoteControl value, you must therefore update the CP. Fourth then applies the CPQuoteControl value to the vendor record in all other properties.

Base path

The base path for all vendor API requests is:

<ROOT>/{CustomerName}Service/API/incomingvendor.svc

This is made of:

  • The domain name of the Fourth cloud, referenced as <ROOT> above.
  • A customer-specific CustomerName — this is the same name in the URL that is used when the customer logs into Fourth Inventory for Hotels. You must also add "Service" to the name; e.g. "acmeService".

The Fourth integration specialist involved in your integration will provide the specific URL you need. You can access a Web Service Definition Language file (WSDL) from this URL.

Making Login method requests

The Login method establishes a session. This method accepts just two elements: username and password.

The response provides a Session ID that you will need to provide in the header for the other methods. The created session defaults to 90 minutes long.

Example request

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.fourthhospitality.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <ws:Login>
         <ws:userName>APIUser1234</ws:userName>
         <ws:password>Ex4mpl3P4ssw0rd</ws:password>
      </ws:Login>
   </soapenv:Body>
</soapenv:Envelope>

The response body returns a LoginResult element. This value is the session ID you need for further requests.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <LoginResponse xmlns="http://ws.fourthhospitality.com/">
         <LoginResult>ba99b4adb2dc44efb0cab40313d3d5c7</LoginResult>
      </LoginResponse>
   </s:Body>
</s:Envelope>

Making InsertVendors requests

The InsertVendors method adds one or more vendors to a property.

The response will confirm whether a record was created and if not, provide an error message for each vendor record you submitted.

Header

You must include the following in the SOAP header of InsertVendors requests:

  • ApplicationType — set this to Web.
  • PropertyNumber — the property that the user account exists in.
  • SessionID — the session ID retrieved via the login method.

Elements

See Elements in InsertVendors and UpdateVendors requests below for a description of the XML element accepted in requests.

Example with required elements only

The following example shows just the minimum required data you can include in a request.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.fourthhospitality.com/">
   <soapenv:Header>
      <ws:AuthenticationHeader>
         <ws:ApplicationType>Web</ws:ApplicationType>
         <ws:PropertyNumber>45</ws:PropertyNumber>
         <ws:SessionID>7f1d4fd553fb4144bb6258bd20ca7b06</ws:SessionID>
      </ws:AuthenticationHeader>
   </soapenv:Header>
   <soapenv:Body>
      <ws:InsertVendors>
         <ws:vendors>
            <ws:vendor>
               <ws:AccountsPayableXreference>LFV123</AccountsPayableXreference>
               <ws:PropertyNumber>1</PropertyNumber>
               <ws:VendorName>LUXURY FRUIT & VEGETABLES LLC</VendorName>
               <ws:CurrencyCode>en-GB</CurrencyCode>
               <ws:CPQuoteControl>1</CPQuoteControl>
            </ws:vendor>
         </ws:vendors>
      </ws:InsertVendors>
   </soapenv:Body>
</soapenv:Envelope>

Example with all elements

The following example shows all elements that you can include in the request body:

<Vendors>
   <Vendor>
      <AccountsPayableXreference>LFV123</AccountsPayableXreference>
      <PropertyNumber>1</PropertyNumber>
      <VendorName>LUXURY FRUIT & VEGETABLES LLC</VendorName>
      <CurrencyCode>en-GB</CurrencyCode>
      <Terms>30 Days Net</Terms>
      <Fob>Ex Works</Fob>
      <ShipVia>DHL</ShipVia>
      <ContactName>Jon Snow</ContactName>
      <ContactTitle>Sales Manager</ContactTitle>
      <AddressLine1>1, Main Street</AddressLine1>
      <AddressLine2>New Industrial Park</AddressLine2>
      <AddressLine3>Downtown Region</AddressLine3>
      <City>Sheffield</City>
      <State>Yorkshire</State>
      <PostalCode>S32 1AN</PostalCode>
      <CountryCode>United Kingdom</CountryCode>
      <VoicePhone>01433 126548 Ex 3</VoicePhone>
      <FaxPhone>01433 126549</FaxPhone>
      <ContactMobilePhone>07876 126985</ContactMobilePhone>
      <ContactEmail>jon.snow@myexamplevendor.com</ContactEmail>
      <WebAddress>www.myexamplevendor.com</WebAddress>
      <WillPalletize>1</WillPalletize>
      <CanCombineOutletOrders>1</CanCombineOutletOrders>
      <IsActive>1</IsActive>
      <VendorNotes>Preferred supplier of vegetables</VendorNotes>
      <HasMarketSegment>0</HasMarketSegment>
      <SepQuotes>0</SepQuotes>
      <MinimumOrder>1200.50</MinimumOrder>
      <MinimumOrderType>Price</MinimumOrderType>
      <CustomerReference>DPR123</CustomerReference>
      <UsesVendorProductNumber>1</UsesVendorProductNumber>
      <UsePurchaseUnit>0</UsePurchaseUnit>
      <AllowMultipleReceivings>1</AllowMultipleReceivings>
      <Email>orders@myexamplevendor.com</Email>
      <InvoiceTypeNumber>1</InvoiceTypeNumber>
      <AllowPOReceiptNotification>0</AllowPOCreatedNotification>
      <AllowPOCreatedNotification>0</AllowPOReceiptNotification>
      <CPQuoteControl>1</CPQuoteControl>
      <CreateEmailInterface>1</CreateEmailInterface>
   </Vendor>
</Vendors>

Making UpdateVendors requests

The UpdateVendors method updates one or more existing vendors in a property. The elements PropertyNumber and AccountsPayableXreference are used to identify the records you are updating. This request will update just the fields you include in the request. All other fields in Adaco will remain the same value.

Note that whether you can update the data field for an individual property is determined by the business' Adaco settings. The business can choose whether a data field is controlled by the CP or editable for each property. See the section above on Creating vendors in the central property vs other properties for more information.

The response will confirm whether a record was updated and if not, provide an error message for each vendor record you submitted.

Header

You must include the following in the SOAP header of InsertVendors requests:

  • ApplicationType — set this to Web.
  • PropertyNumber — the property that the user account exists in.
  • SessionID — the session ID retrieved via the login method.

Elements

The UpdateVendors method accepts the same XML elements as the InsertVendors method. See Elements in InsertVendors and UpdateVendors requests below for a description of the XML element accepted in requests.

Example request

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.fourthhospitality.com/">
   <soapenv:Header>
      <ws:AuthenticationHeader>
         <ws:ApplicationType>Web</ws:ApplicationType>
         <ws:PropertyNumber>45</ws:PropertyNumber>
         <ws:SessionID>7f1d4fd553fb4144bb6258bd20ca7b06</ws:SessionID>
      </ws:AuthenticationHeader>
   </soapenv:Header>
   <soapenv:Body>
      <ws:UpdateVendors>
         <ws:vendors>
            <ws:vendor>
               <ws:AccountsPayableXreference>LFV123</AccountsPayableXreference>
               <ws:PropertyNumber>1</PropertyNumber>
               <ws:VendorName>LUXURY FRUIT & VEGETABLES LLC</VendorName>
               <ws:CurrencyCode>en-GB</CurrencyCode>
               <ws:CPQuoteControl>1</CPQuoteControl>
               <ws:ContactName>Erika Mustermann</ContactName>
               <ws:ContactTitle>Sales Success Manager</ContactTitle>
               <ws:ContactEmail>erika.mustermann@myexamplevendor.com</ContactEmail>
            </ws:vendor>
         </ws:vendors>
      </ws:UpdateVendors>
   </soapenv:Body>
</soapenv:Envelope>

Data processing

Fourth uses these rules for processing your requests:

  • We truncate any string values that exceed the maximum field length. We return a "success" status for requests where this has happened.
  • We do not validate the data sent in free text fields (unless where stated). For example, we do not check whether a postcode is valid.
  • If an optional element contains the incorrect data type, Fourth ignores the value and the field is not updated, unless there is a default value. For example: <allowMultipleReceivings>No</allowMultipleReceivings> defaults to 1 (true) as the submitted value is not valid.
  • If a required element contains an incompatible data type or no value, Fourth will not process the record. Instead, we generate an error. For example <propertyNumber>MyHotel</propertyNumber> would cause an error as propertyNumber cannot be a string value.

Elements in InsertVendors and UpdateVendors requests

The InsertVendors and UpdateVendors methods accept the same XML elements and format.

In the below table, you must include elements that are described as Required in your request. All other elements are optional or include a default.

Node/Element Type Description
Vendors  

Required

Parent of Vendor.

Vendor  

Required

Parent of all other elements.

AccountsPayableXreference String(30) Required
A unique number or ID for the vendor from your (third-party) system. For example, CW123.
PropertyNumber Integer

Required

The unique number for an Adaco property. You can find this in the Fourth UI as "Property Number". During integration, Fourth will provide the values for existing properties. For example, 12.

VendorName String(50)

Required

Name of the vendor. For example, Chris’s Fruit & Veg.

CurrencyCode String(10)

Required

The currency in use with the vendor. You must use a culture and language tag defined in RFC7231/RFC5646; for example: en-GB for England (pounds) and en-US for the USA (US dollar).

Terms String(30)

Free text field for adding a note about terms and conditions related to the vendor. For example, 30 days net.

Fob String(40)

Free text field for adding any free/freight on board notes (this refers to the point at which the purchaser is responsible for shipping charges and risks). For example, FOB from Shanghai port.

ShipVia String(40)

Free text field for adding a delivery company or method. For example, DHL.

ContactName String(50)

Free text field for adding a contact name for the vendor. For example, Jon Snow.

ContactTitle String(50) Free text field for adding a job title for the contact. For example, Sales Manager.
AddressLine1 String(50)

Free text field for adding address details. For example, Norrie Business Center.

AddressLine2 String(50)

Free text field for adding address details. For example, 1 Tuffley Street.

AddressLine3 String(50) Free text field for adding address details. For example, Deptford.
City String(50) Free text field for adding address details. For example, Sheffield.
State String(50) Free text field for adding address details. For example, Yorkshire.
PostalCode String(25) Free text field for adding address details, such as a postal or zip code. For example, S32 1DU.
CountryCode String(100) Free text field for adding address details. For example, United Kingdom.
VoicePhone String(25)

Free text field for adding a business phone number. For example, 01433 126548 Ext 3.

FaxPhone String(25)

Free text field for adding a fax number. For example: 01433 126549.

ContactMobilePhone String(25)

Free text field for adding a mobile phone number for the named contact. For example: +44 7700 900809.

ContactEmail String(1000)

Free text field for adding an email address for the named contact. For example, jon.snow@example.com.

WebAddress String(200)

Free text field for adding the vendor's website. For example, https://vendor.example.com.

WillPalletize

Bit

Whether, for the same purchase order, the vendor will separate out the items for different outlets onto separate pallets.

  • 0 — False; they will send the items for all outlets together. 
  • 1 — True; they will send each outlet their items on separate pallets.

Default: 0

CanCombineOutletOrders Bit

Whether the customer allows outlet orders to be combined into a single PO for this vendor. This element is linked to the WillPalletize and MinimumOrder elements. Customers may want to separate POs if the vendors doesn't palletize orders. However, if a vendor has a large minimum order amount, customers may want to create one order for all outlets and palletize themselves.

  • 0 — False; users cannot or should not create an order spanning multiple outlets
  • 1 — True; users can create an order spanning multiple outlets

Default: 0

IsActive Bit

Whether this vendor is active, enabling users to create orders with them.

  • 0 — False; the vendor is deactivated for the customer. Users will not be able to create orders for this vendor.
  • 1 — True; the vendor is active for the customer.

Default: 1

VendorNotes String(250)

Free text field for any notes the customer has about the vendor.

For example, Preferred supplier of vegetables.

HasMarketSegment Bit

Whether the vendor has different prices based on location (for example, west coast vs east coast). Customers can allocate their Adaco properties to different segments, then allow them to select the right price catalogue. This enables customers to use the same vendor record but apply multiple price segment catalogues to the vendor.

  • 0 — False; the vendor does not have market segments.
  • 1 — True; the vendor does have market segments.

Default: 0

SepQuotes Bit

Whether the vendor has separate price catalogues for each market segment.

  • If HasMarketSegment is 0 (false) then SepQuotes must equal 0  (false).
  • If HasMarketSegment is 1 (true) then SepQuotes can equal 0 (false) or 1 (true).

Default: 0

MinimumOrder Decimal(18,3)

Include with MinimumOrderType if the vendor has a minimum order amount. This is the value of the quantity or price. For example, for a £1200.50 minimum order you would enter 1200.50.

MinimumOrderType String(50)

Include a value if you have set a MinimumOrder value. Either:

  • Quantity — The value of MinimumOrder is for a number of units. For example, a wine merchant may require a minimum order of 12 cases.
  • Price — The value of MinimumOrder is a minimum price in the vendor's currency.
CustomerReference String(50)

The vendor's own reference for the Adaco property. This is used when linking to TradeSimple. For example, DPR123.

UsesVendorProductNumber Bit

Whether the vendor uses their own product numbers in the price catalogues.

  • 0 — False; the vendor does not include product numbers; in these circumstances the Adaco product numbers are used instead when importing in the vendor's catalogue.
  • 1 — True; the vendor uses their own product numbers.

Default: 0

UsePurchaseUnit Bit

Whether the vendor uses separate product numbers for products that have multiple unit options. For example, a wine merchant may sell "Penfolds Grange 2017 (750ml)" per bottle using the product number 12345, and by case using the product number 54123.

This field can only equal 1 (true) if UsesVendorProductNumber is also 1.

  • 0 — False; the vendor sells a product using the same product number, regardless of unit type.
  • 1 — True; the vendor uses separate product numbers by unit type.

Default: 0

AllowMultipleReceivings Bit

Whether the customer allows back orders for this vendor; e.g. to send through products for the same PO over multiple days.

  • 0 — False; the PO is closed once the first order is received.
  • 1 — True; the PO remains open until all goods received.

Default: 1

Email String(250)

The vendor's email address for receiving purchase orders. You MUST include this field if the customer's POs are sent via email to the vendor. For example, sales@myexamplewines.com.

InvoiceTypeNumber Integer

The invoice type number. This is specific to each customer and enables users to select additional invoice types and behaviours based on the business's processes. For example, customers may have an invoice type number of 1 to indicates the invoice goes to accounts payable, and 2 to indicate that the payment comes out of petty cash.

By default, all customers have an invoice type number of 1 within Adaco.

Default: 1

AllowPOReceiptNotification Bit

Whether users are notified when the business receives goods from this vendor. This is of use to users where there is a long lead time to receiving goods; for example, vendors that are uniform manufacturers. Adaco only notifies the user who created the requisition.

  • 0 — False; users are not notified.
  • 1 — True; users are notified.

Default: 0

AllowPOCreatedNotification Bit

Whether users are notified when a POs has been created for this vendor. This is of use to users where a businesses has a lengthy requisition and approvals process for a vendor, which slows down ordering. Adaco only notifies the user who created the requisition.

  • 0 — False; users are not notified.
  • 1 — True; users are notified.

Default: 0

CPQuoteControl Bit

Required

Determines if the pricing for the vendor is managed by the central property (CP) or at per-property level.

  • 0 — False; the pricing is managed at the per-property level.
  • 1 — True; the pricing is managed by the CP.
CreateEmailInterface Bit

Whether to automatically create a vendor interface for the vendor. Adaco uses the value of the <Email> element as the contact address in the interface.

A vendor interface sets how users send through purchase orders to the vendor. Note that if the customer wishes to use another type of contact detail, such as Electronic Data Interchange (EDI), then they need to set this manually via the Adaco UI.

Adaco will only create the interface if the <Email> element has a value.

  • 0 — False; Adaco doesn't create an interface.
  • 1 — True; Adaco creates a vendor interface.

Default: 0

Additional data updated in Fourth

Adaco database field Value

Vendor.VendorNumber

An incremental primary key value for the vendor within Fourth.

Created only when the InsertVendors method used.

Vendor.CreatedByUserID

The ID of the user who authenticated with the service.

Added only when the InsertVendors method used.

Vendor.CreatedDateTime

The date and time when the vendor record was created in Fourth.

Added only when the InsertVendors method used. 

Vendor.ModifiedByUserID

The ID of the user who authenticated with the service.

Added or updated when both InsertVendors and UpdateVendors method used.

Vendor.ModifiedDateTime

The date and time when the vendor record was last modified in Fourth.

Added or updated when both InsertVendors and UpdateVendors method used.

Vendor.CMSVendor
  • 1 — the vendor exists in the central property (CP)
  • 0 — the vendor doesn't exist in the CP

Example using C# to submit vendor data

This example C# code is shown for illustration purposes only and does not include error checking or application specific requirements.

  1. Add a reference to the Vendor API to your code project (using the URL provided).
  2. Create an instance of the IncomingVendorClient class which is initialized with two parameters: HTTP Binding and the Endpoint Address:
    IncomingVendorClient client = new IncomingVendorClient(new BasicHttpBinding(), new EndpointAddress(ApiURL)); 
  3. Create an instance of the AuthenticationHeaderIncomingVendor class and assign it the property number from the property in which the user account exists:
    AuthenticationHeaderIncomingVendor header = new AuthenticationHeaderIncomingVendor
       {
          PropertyNumber = myPropertyNumber
       };
  4. Call the Login method of the client submitting the username and password as parameters and assign the resulting session ID to the Authentication Header:
    header.SessionID = client.Login(Username,Password);
  5. Call either the InsertVendors or UpdateVendors methods of the client submitting the authentication header and the vendor data (in XML) as arguments and assign the results to an instance of the ApiVendorResponse class.  Both the InsertVendors and the UpdateVendors methods are available as Async methods also:
    ApiVendorResponse vr = client.InsertVendors(header,vendorXML);