Dokumentacja API cenowego Grula
Podłącz system ERP, sklep B2B lub aplikację ofertową do REST API Grula. Znajdziesz tu uwierzytelnianie, wycenę pojedynczą i wsadową oraz przykładowe żądania i odpowiedzi.
Szybki start
Przygotuj token API, wybierz endpoint i wyślij pierwsze żądanie o cenę.
Uwierzytelnianie
Do żądania dodaj nagłówek Authorization z tokenem Bearer wygenerowanym w panelu Grula.
Authorization: Bearer YOUR_API_TOKENBase URL
https://api.grula.netKluczowe koncepcje
Polityki cenowe (cenniki)
Polityka cenowa przechowuje ceny bazowe dla produktów i warunki ich zastosowania. Pełni rolę cennika używanego przez silnik wyceny.
Korekty ceny (rabaty i opłaty)
Reguły korekty zmieniają cenę bazową, gdy spełnione są określone warunki, na przykład grupa klienta lub wielkość zamówienia.
Oblicz pojedynczą cenęPOST
Wyślij czynniki cenowe, walutę i opcjonalną datę wyceny. API zwróci cenę obliczoną według pasujących polityk.
Endpoint
POST /api/v1/pricecurl -X POST "https://api.grula.net/api/v1/price" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"environmentId": "123e4567-e89b-12d3-a456-426614174000",
"priceDrivers": [
{
"name": "product",
"value": "laptop"
},
{
"name": "customer_tier",
"value": "premium"
}
],
"currencyThreeLetterCode": "USD",
"pricingDate": "2024-01-15T10:00:00Z"
}'import requests
import json
url = "https://api.grula.net/api/v1/price"
headers = {
"Authorization": "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
}
payload = {
"environmentId": "123e4567-e89b-12d3-a456-426614174000",
"priceDrivers": [
{
"name": "product",
"value": "laptop"
},
{
"name": "customer_tier",
"value": "premium"
}
],
"currencyThreeLetterCode": "USD",
"pricingDate": "2024-01-15T10:00:00Z"
}
response = requests.post(url, headers=headers, json=payload)
price_data = response.json()
print(f"Price: {price_data['amount']['amount']} {price_data['amount']['currencyThreeLetterCode']}")const axios = require('axios');
const getPricing = async () => {
try {
const response = await axios.post('https://api.grula.net/api/v1/price', {
environmentId: '123e4567-e89b-12d3-a456-426614174000',
priceDrivers: [
{
name: 'product',
value: 'laptop'
},
{
name: 'customer_tier',
value: 'premium'
}
],
currencyThreeLetterCode: 'USD',
pricingDate: '2024-01-15T10:00:00Z'
}, {
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json'
}
});
console.log(`Price: ${response.data.amount.amount} ${response.data.amount.currencyThreeLetterCode}`);
return response.data;
} catch (error) {
console.error('Error fetching price:', error.response?.data || error.message);
}
};
getPricing();using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
public class PricingClient
{
private readonly HttpClient _httpClient;
private const string BaseUrl = "https://api.grula.net";
public PricingClient(string apiToken)
{
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiToken}");
}
public async Task<PriceResponse> GetPriceAsync(PriceRequest request)
{
var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"{BaseUrl}/api/v1/price", content);
response.EnsureSuccessStatusCode();
var responseJson = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<PriceResponse>(responseJson);
}
}
// Usage
var client = new PricingClient("YOUR_API_TOKEN");
var request = new PriceRequest
{
EnvironmentId = Guid.Parse("123e4567-e89b-12d3-a456-426614174000"),
PriceDrivers = new[]
{
new PriceDriver { Name = "product", Value = "laptop" },
new PriceDriver { Name = "customer_tier", Value = "premium" }
},
CurrencyThreeLetterCode = "USD",
PricingDate = DateTime.Parse("2024-01-15T10:00:00Z")
};
var price = await client.GetPriceAsync(request);
Console.WriteLine($"Price: {price.Amount.Amount} {price.Amount.CurrencyThreeLetterCode}");import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.time.Duration;
import com.fasterxml.jackson.databind.ObjectMapper;
public class PricingClient {
private final HttpClient httpClient;
private final ObjectMapper objectMapper;
private final String apiToken;
private static final String BASE_URL = "https://api.grula.net";
public PricingClient(String apiToken) {
this.httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
this.objectMapper = new ObjectMapper();
this.apiToken = apiToken;
}
public PriceResponse getPrice(PriceRequest request) throws Exception {
String requestBody = objectMapper.writeValueAsString(request);
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/api/v1/price"))
.header("Authorization", "Bearer " + apiToken)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = httpClient.send(httpRequest,
HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
return objectMapper.readValue(response.body(), PriceResponse.class);
} else {
throw new RuntimeException("API call failed: " + response.statusCode());
}
}
}
// Usage
PricingClient client = new PricingClient("YOUR_API_TOKEN");
PriceRequest request = new PriceRequest();
request.setEnvironmentId(UUID.fromString("123e4567-e89b-12d3-a456-426614174000"));
request.setPriceDrivers(Arrays.asList(
new PriceDriver("product", "laptop"),
new PriceDriver("customer_tier", "premium")
));
request.setCurrencyThreeLetterCode("USD");
request.setPricingDate(Instant.parse("2024-01-15T10:00:00Z"));
PriceResponse price = client.getPrice(request);
System.out.println("Price: " + price.getAmount().getAmount() + " " +
price.getAmount().getCurrencyThreeLetterCode());Oblicz wiele cenPOST
Wyślij do 100 zestawów czynników cenowych w jednym żądaniu, aby uzyskać wyniki wyceny wsadowej.
Endpoint
POST /api/v1/pricescurl -X POST "https://api.grula.net/api/v1/prices" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"environmentId": "123e4567-e89b-12d3-a456-426614174000",
"priceRequests": [
{
"priceDrivers": [
{"name": "product", "value": "laptop"},
{"name": "customer_tier", "value": "premium"}
],
"currencyThreeLetterCode": "USD",
"pricingDate": "2024-01-15T10:00:00Z"
},
{
"priceDrivers": [
{"name": "product", "value": "desktop"},
{"name": "customer_tier", "value": "standard"}
],
"currencyThreeLetterCode": "EUR",
"pricingDate": "2024-01-15T10:00:00Z"
}
]
}'import requests
url = "https://api.grula.net/api/v1/prices"
headers = {
"Authorization": "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
}
payload = {
"environmentId": "123e4567-e89b-12d3-a456-426614174000",
"priceRequests": [
{
"priceDrivers": [
{"name": "product", "value": "laptop"},
{"name": "customer_tier", "value": "premium"}
],
"currencyThreeLetterCode": "USD",
"pricingDate": "2024-01-15T10:00:00Z"
},
{
"priceDrivers": [
{"name": "product", "value": "desktop"},
{"name": "customer_tier", "value": "standard"}
],
"currencyThreeLetterCode": "EUR",
"pricingDate": "2024-01-15T10:00:00Z"
}
]
}
response = requests.post(url, headers=headers, json=payload)
prices = response.json()
for i, price in enumerate(prices):
print(f"Price {i+1}: {price['amount']['amount']} {price['amount']['currencyThreeLetterCode']}")const axios = require('axios');
const getBatchPrices = async () => {
try {
const response = await axios.post('https://api.grula.net/api/v1/prices', {
environmentId: '123e4567-e89b-12d3-a456-426614174000',
priceRequests: [
{
priceDrivers: [
{ name: 'product', value: 'laptop' },
{ name: 'customer_tier', value: 'premium' }
],
currencyThreeLetterCode: 'USD',
pricingDate: '2024-01-15T10:00:00Z'
},
{
priceDrivers: [
{ name: 'product', value: 'desktop' },
{ name: 'customer_tier', value: 'standard' }
],
currencyThreeLetterCode: 'EUR',
pricingDate: '2024-01-15T10:00:00Z'
}
]
}, {
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json'
}
});
response.data.forEach((price, index) => {
console.log(`Price ${index + 1}: ${price.amount.amount} ${price.amount.currencyThreeLetterCode}`);
});
return response.data;
} catch (error) {
console.error('Error fetching batch prices:', error.response?.data || error.message);
}
};
getBatchPrices();Przykłady odpowiedzi
Przykładowa odpowiedź pokazuje wynik wyceny i składniki, które wpłynęły na cenę.
Odpowiedź z ceną
{
"amount": {
"amount": 1299.99,
"currencyThreeLetterCode": "USD"
},
"priceComponents": [
{
"pricingPolicyId": "123e4567-e89b-12d3-a456-426614174000",
"amount": {
"amount": 1499.99,
"currencyThreeLetterCode": "USD"
}
},
{
"priceAdjustmentPolicyId": "456e7890-e89b-12d3-a456-426614174001",
"amount": {
"amount": -200.00,
"currencyThreeLetterCode": "USD"
},
"priceAdjustmentPolicyActionName": "Premium Customer Discount",
"priceAdjustmentPolicyValue": 0.15
}
]
}Obsługa błędów
Kody HTTP informują, czy żądanie się powiodło oraz co poprawić w razie błędu.