
Integration Best Practices
This page provides best practices and recommendations for integrating with the Solar Procurement Services API. It is intended to help developers design robust, efficient, and scalable integrations by correctly handling catalog data, product lifecycle, pricing, inventory, and order processing.
Handling the Full Product Catalog
When using the Solar Procurement Services API, you will receive the full product catalog, including products in all statuses.
This is by design and ensures that your system always has a complete and up-to-date view of the assortment, including any lifecycle changes. The API supports returning either the full catalog or only changes depending on how it is used.
To handle this correctly in your solution, it is important to actively use the product status as part of your integration logic.
The product statuses are:
10 – Active
11 – Active (stocked in another central warehouse)
33 – Being phased out
40 – Phased out
✅ Recommended approach
Compare with your previous data
Retrieve the catalog and compare it with your previous dataset to identify changes in product status.Handle phased-out products
Products with status 40 should be removed or marked as inactive in your system.Filter for downstream usage
When requesting price and availability:Include products with status 10, 11, 33
Exclude products with status 40
This ensures that your system remains aligned with Solar’s product assortment while avoiding processing products that are no longer available.
Use Delta Synchronization (lastChanged)
The product API supports retrieving only changed data using the lastChanged parameter.
If provided, only products changed after a specific timestamp will be returned. If omitted, the full product catalog is returned.
✅ Recommended approach
Use a full synchronization during initial load
Store the
lastChangedtimestamp per productUse delta requests for ongoing synchronization
Combine with product status handling to detect lifecycle changes
This reduces data volume and improves performance.
Handle Pagination Correctly
Several endpoints (e.g. categories and products) use pagination with:
limit(maximum number of records)nextPagetoken in the response
✅ Recommended approach
Always process responses until
isLastPage = trueUse the
nextPagevalue provided in the response for subsequent callsAvoid assuming that all data is returned in a single request
This ensures completeness of data retrieval.
Authentication and Security
All API requests require authentication using a token retrieved via the authentication endpoint.
The API requires:
Authorization header (Bearer token)
Subscription key (header or query parameter)
✅ Recommended approach
Securely store credentials (ClientId and Secret)
Cache and reuse tokens until expiration
Handle token expiration gracefully by refreshing the token
Use Consistent Product Identification
The API supports multiple product identifiers such as:
ElectricalNumber
HWSNumber
EANNumber
SAPMaterialNumber
For pricing and ordering, SAPMaterialNumber is the only identifier supported.
✅ Recommended approach
Internally standardize on SAPMaterialNumber
Convert other identifiers to SAPMaterialNumber where needed
Ensure consistency across catalog, pricing, inventory, and ordering
Requesting Price and Availability
Pricing and availability are not included in the catalog response and must be retrieved via dedicated endpoints:
/products/prices/products/atp
When using the Price API you will need an accountId parameter.
Why is Account ID Required?
Solar pricing is customer-specific.
The returned prices depend on:
Customer agreements
Discounts
Country
Account setup
Commercial conditions
For this reason, the API requires an accountId to determine the correct prices to return.
Retrieving the Account ID
The available account IDs depend on the user associated with the access token.
Before requesting prices, you must first retrieve the list of accounts available to your integration by calling the Get Accounts endpoint.
Step 1: Retrieve Available Accounts
GET /accounts
Authorization: Bearer {access_token}
Example response:
[{"accountId": "123456","accountName": "Solar Installation A/S","accountName2": "Copenhagen Branch"},{"accountId": "789012","accountName": "Solar Installation A/S","accountName2": "Aarhus Branch"}]
The response contains all accounts that the authenticated user has access to.
Step 2: Select the Appropriate Account
Choose the account that should be used for Pricing
Example:
{
"accountId": "123456",
"accountName": "Solar Installation A/S",
"accountName2": "Copenhagen Branch"
}Step 3: Use the Account ID When Requesting Prices
Example request:
POST /products/prices?accountId=123456&countrycode=dk
Authorization: Bearer {access_token}
Content-Type: application/json
Request body:
{
"productIdentifier": "SAPMaterialNumber",
"products": [
{
"productId": "1200521672"
},
{
"productId": "1200468795"
}
]
}Recommended Approach
Retrieve the list of available accounts once after authentication.
Let the user select the desired account if multiple accounts are available.
Store the selected account ID in your application.
Use the same account ID when requesting Prices
This ensures that all information returned by the Procurement Services APIs is consistent and based on the same customer account.
✅ Recommended approach
Always request price and ATP (availability) as separate calls
Batch requests where possible (respect limits, e.g. max 500 products for pricing)
Filter out irrelevant products (e.g. status 40) before requesting
Understanding Prices, Quantities and Units
The pricing API returns prices together with the quantity and unit to which the price applies.
Price Fields
Price: The price amount in the specified currency.
PriceQuantity: The quantity to which the price applies.
UnitCode: The unit of measure associated with the price.
Currency: Currency of the returned price.
How to Interpret Prices
The returned price always applies to the quantity specified in PriceQuantity and the unit specified in UnitCode.
Example 1: Product Sold per Meter
Response:
{
"Price": 6687.17,
"PriceType": "NetPrice",
"PriceQuantity": 1,
"UnitCode": "MTR",
"Currency": "DKK"
}Interpretation:
Net price is 6687.17 DKK for 1 meter (MTR)
Effective unit price:
6687.17 DKK per MTR
Example 2: Product Sold per Package
Response:
{
"Price": 834,
"PriceType": "NetPrice",
"PriceQuantity": 1,
"UnitCode": "PK",
"Currency": "DKK"
}Interpretation:
Net price is 834 DKK for 1 package (PK)
Effective unit price:
834 DKK per PK
Example 3: Price for Multiple Units
Response:
{
"Price": 800,
"PriceQuantity": 10,
"UnitCode": "PC",
"Currency": "DKK"
}Interpretation:
Price is 800 DKK for 10 pieces
Effective unit price:
800 / 10 = 80 DKK per PC
⚠️ Important
Data returned by the Price API must only be interpreted together with the fields returned by the Price API itself.
Consumers must not combine pricing calculations with catalog fields such as:
minimumOrderQuantitymultiplumpackageSizebaseUnitofMeasure
The fields Price, PriceQuantity, and UnitCode completely describe how the returned price should be interpreted.
Ordering constraints such as minimum quantities and order increments are described separately in the Product Catalog API and should only be used when validating order quantities.
Location-Specific Inventory Handling
For certain countries, inventory requests require additional information:
Postal code is required when multiple warehouses exist (e.g. Sweden)
✅ Recommended approach
Always include postal code where applicable
Treat inventory as location-dependent
Ensure correct delivery context when querying availability
Respect Units, Multiples, and Quantities
Products include fields such as:
unit(sales unit)baseUnitofMeasuresalesUnitofMeasure
multiplum(order increment)minimumOrderQuantity
✅ Recommended approach
Before placing orders, your system should validate requested quantities against these values to ensure that orders can be processed successfully.
Example 1: Product Sold in Packages
Product Data
{
"baseUnitofMeasure": "PCE",
"salesUnitofMeasure": "PK",
"packageSize": 10,
"minimumOrderQuantity": 1,
"multiplum": 1
}
Interpretation
The product is stored as individual pieces (PCE) but sold in packages (PK). Each package contains 10 pieces.
Valid Orders
1 PK
2 PK
5 PK
Invalid Order
5 PCE
Always use the salesUnitofMeasure when this field is available and you want to display prices, quantities, and creating orders.
Example 2: Minimum Order Quantity
Product Data
{
"salesUnitofMeasure": "PCE",
"minimumOrderQuantity": 25,
"multiplum": 1
}
Valid Orders
25 PCE
50 PCE
100 PCE
Invalid Orders
1 PCE
10 PCE
24 PCE
The ordered quantity must always be greater than or equal to the specified minimumOrderQuantity.
Example 3: Order Multiples (Multiplum)
Product Data
{
"salesUnitofMeasure": "M",
"minimumOrderQuantity": 10,
"multiplum": 5
}
Valid Orders
10 M
15 M
20 M
25 M
Invalid Orders
11 M
18 M
22 M
Quantities must be ordered in increments defined by the multiplum value.
Example 4: Cable Sold by Length
Product Data
{
"salesUnitofMeasure": "M",
"cableCut": true,
"minimumOrderQuantity": 10,
"multiplum": 1
}
Valid Orders
10 M
11 M
25 M
100 M
Because cableCut is set to true, the product can be ordered in custom lengths as long as the minimum order quantity is respected.
Example 5: Quantity Validation Logic
Product Data
{
"salesUnitofMeasure": "PCE",
"minimumOrderQuantity": 20,
"multiplum": 5
}
Validation Rule
Requested Quantity >= Minimum Order Quantity
AND
(Requested Quantity - Minimum Order Quantity) is divisible by Multiplum
Valid Orders
20 PCE
25 PCE
30 PCE
35 PCE
Invalid Orders
15 PCE
21 PCE
28 PCE
33 PCE
Recommended Validation Flow
Read salesUnitofMeasure
Read minimumOrderQuantity
Read multiplum
Validate the requested quantity
Display quantities using the sales unit returned by the API
Reject or adjust quantities that do not comply with the product's ordering rules
Following this approach ensures that orders comply with Solar's sales and logistics requirements and reduces the risk of order validation errors.
Order Creation Best Practices
Orders are created via the /orders endpoint and require:
Account ID
Product identifiers (SAPMaterialNumber)
Quantity
Delivery information
✅ Recommended approach
Validate product data before placing orders
Ensure correct delivery address selection
Include customer references for traceability
Handle errors and confirmation responses properly
General Integration Principles
Design for eventual consistency (catalog vs price vs inventory)
Treat the catalog as the source of truth for product metadata
Use stateless API calls combined with local caching
Monitor for changes using lastChanged + status transitions
Implement retry logic and error handling for resilience