Integration Guide — Points Configuration
Microservice: XDPeople.Soba.WebAPI (Core API)
Authentication: Bearer token (JWT) and tenant context — see Combined Login
Introduction
This guide describes the integration with the API to manage points configurations (rules for assigning points per document or per line).
The field criteriaType (PointsConfigCriteriaType) defines which nested criterion must be filled in the request:
| Value | Name | JSON Object |
|---|---|---|
0 | Header | defaultHeaderCriteria (rule at the document header level). |
1 | DefaultDetailsWithItemSearchCriteria | defaultDetailsItemCriteria (details with search by item). |
2 | DefaultDetailsWithFamilySearchCriteria | defaultDetailsFamilyCriteria (details with search by family). |
The other two criteria objects must be null or omitted, so that only the branch corresponding to criteriaType is defined in the body.
Available Endpoints
Public prefix: /gateway/points-config.
| Method | URL | Brief Description |
|---|---|---|
| GET | /gateway/points-config | Lists configurations with optional pagination (page, pageSize); see pagination rules. |
| GET | /gateway/points-config/{id} | Retrieves a configuration by Guid. |
| GET | /gateway/points-config/next-order | Returns the next suggested order number for a new entry. |
| POST | /gateway/points-config | Creates a configuration; response 201 Created with Guid in the body. |
| PUT | /gateway/points-config | Updates an existing configuration; the id is in the body (PointsConfigDTO.Id); response 204 No Content. |
| DELETE | /gateway/points-config/{id} | Deletes by Guid; response 204 No Content. |
List Configurations
URL: /gateway/points-config — Method: GET
Get by Identifier
URL: /gateway/points-config/{id} — Method: GET
Next Order
URL: /gateway/points-config/next-order — Method: GET
Create
URL: /gateway/points-config — Method: POST
Update
URL: /gateway/points-config — Method: PUT (identifier in body, not in route)
Delete
URL: /gateway/points-config/{id} — Method: DELETE
Body Structure (PointsConfigDTO)
| Field | Type | Description |
|---|---|---|
id | Guid? | Required on update; omitted or empty on create. |
order | int | Presentation / priority order (validation: see validations section). |
description | string | Description (required in the model). |
active | bool | Active configuration. |
cumulative | bool | Allow accumulation with other assignments. |
allowDecimalPoints | bool | Allow decimal points. |
startDate | date-time | Start of validity. |
endDate | date-time | End of validity. |
criteriaType | int (enum) | Criteria type (table above). |
defaultHeaderCriteria | object? | Header criterion; see below. |
defaultDetailsItemCriteria | object? | Item detail criterion; see below. |
defaultDetailsFamilyCriteria | object? | Family detail criterion; see below. |
Auxiliary listing fields (StartDateHolder, EndDateHolder, ActiveHolder, IsPreCompiled, etc.) may exist in the generated contract; for REST integration focus on the fields above and the nested criteria.
Common Base for Criteria (BaseCriteriaDTO)
Present in any non-null criterion:
| Field | Type | Description |
|---|---|---|
totalPoints | decimal | Total points (model; often 0 on creation). |
pointsBase | decimal | Points base (numeric validation in DTO). |
eachY | decimal | Denominator “Y” when the formula is X per Y; otherwise typically 0. |
formulaBase | int (enum) | 0 = XTimes, 1 = XForY. |
defaultHeaderCriteria (DefaultHeaderCriteriaDTO)
Includes the fields from BaseCriteriaDTO plus:
| Field | Type | Description |
|---|---|---|
documentField | int (enum) | Document field used as the calculation base (document total, net, taxes, amount paid, etc.). |
defaultDetailsItemCriteria / defaultDetailsFamilyCriteria
Extend BaseCriteriaDTO with:
| Field | Type | Description |
|---|---|---|
detailField | int (enum) | Detail line field (quantity, prices, totals, etc.). |
searchType | int (enum) | 0 = list, 1 = individual. |
searchPool | array | Set of references; each element follows DefaultDetailsItemDTO (item) or DefaultDetailsFamilyDTO (family), depending on the criterion. |
searchPool Elements
| Criterion | Element DTO | Properties |
|---|---|---|
defaultDetailsItemCriteria | DefaultDetailsItemDTO | id, description, keyId |
defaultDetailsFamilyCriteria | DefaultDetailsFamilyDTO | id, description, idParent (ancestor in the family hierarchy) |
The searchType field in the detail criterion indicates the search mode (0 = list, 1 = individual). The persistence service mainly validates that searchPool is not empty when the corresponding criterion is present; keep searchType consistent with business intent and model consumers.
Enums (numeric values in JSON)
Expected values in the JSON body.
PointsConfigCriteriaType (criteriaType): 0 Header, 1 Item detail, 2 Family detail.
FormulaBaseEnum (formulaBase in criteria): 0 XTimes, 1 XForY.
SearchTypeEnum (searchType in detail criteria): 0 List, 1 Individual.
DocumentFieldsEnum (documentField in defaultHeaderCriteria):
| Value | Meaning |
|---|---|
0 | Document total |
1 | Net total |
2 | Taxes total |
3 | Amount paid |
DetailFieldsEnum (detailField in detail criteria):
| Value | Meaning |
|---|---|
0 | Quantity |
1 | Price with VAT |
2 | Line total with VAT |
3 | Price without VAT |
4 | Line total without VAT |
Payload Requirements and Consistency
By criteriaType and formulaBase
criteriaType | Criterion to send | searchPool | documentField / detailField |
|---|---|---|---|
0 (Header) | defaultHeaderCriteria filled; other criteria null / omitted. | Not applicable. | documentField required in the criterion object. |
1 (Item detail) | defaultDetailsItemCriteria filled; others null. | Non-empty list when criterion is not null (server validation). | detailField required in the object. |
2 (Family detail) | defaultDetailsFamilyCriteria filled; others null. | Non-empty list when criterion is not null (server validation). | detailField required in the object. |
formulaBase | Additional requirement (server + model) |
|---|---|
0 (XTimes) | eachY can be 0; focus on pointsBase. |
1 (XForY) | eachY must be strictly greater than zero (eachY > 0) whenever the nested criterion exists and is validated; values 0 or negative fail with PointsConfig.InvalidEachY (on server the condition is eachY <= 0). |
Unknown or unmapped criteriaType
If criteriaType has a value not present in the service’s internal validator dictionary, ValidateCriteria does not execute any type-specific validators and returns success at this stage (only date validation continues to apply). For valid integrations, always use 0, 1, or 2 according to the PointsConfigCriteriaType enum.
Date Range
startDatecannot be afterendDate. Otherwise:PointsConfig.InvalidDateRange.
null Criterion on Server
If the criterion object corresponding to the criteriaType is null, the specific validation branch (empty pool, eachY by type) is not executed and returns success for that part. For consistent data, always send the criterion aligned with criteriaType following the rules above.
Validations:
Create and Update
Applied before persisting. On update, if the id does not exist in ConfigList, the API returns PointsConfig.NotFound after loading definitions and before saving.
| Rule | Error Code |
|---|---|
startDate > endDate | PointsConfig.InvalidDateRange |
Header type, non-null criterion, formulaBase == XForY and eachY <= 0 | PointsConfig.InvalidEachY |
Item detail type, non-null criterion, empty searchPool | PointsConfig.InvalidItemSearchPool |
Item detail type, non-null criterion, XForY and eachY <= 0 | PointsConfig.InvalidEachY |
Family detail type, non-null criterion, empty searchPool | PointsConfig.InvalidFamilySearchPool |
Family detail type, non-null criterion, XForY and eachY <= 0 | PointsConfig.InvalidEachY |
Other Error Results
| Code | When it occurs (summary) |
|---|---|
PointsConfig.NotFound | GET/PUT/DELETE with non-existent identifier in saved list. |
PointsConfigCreate.Fail | Exception or unexpected failure on creation. |
PointsConfigUpdate.Fail | Exception or unexpected failure on update. |
PointsConfigDelete.Fail | Exception or unexpected failure on deletion. |
PointsConfigSave.Fail | IConfigProvider.UpdateAsync returned false when saving definitions. |
PointsGetAll.Fail | Failure listing (e.g., exception in GetAllAsync). |
PointsGetById.Fail | Failure retrieving by id (e.g., exception). |
PointsGetNextOrder.Fail | Failure calculating next order. |
CreateDefaultSettingsFail.Fail | Failure creating default settings when none exist yet. |
Config.NotFound | Constant in error module; associated with missing configurations in configuration scenarios. |
Listing Validations (GET)
In GetAllAsync, query parameters are normalized in memory:
| Parameter | Behavior |
|---|---|
page | If omitted or less than 1, page 1 is used. |
pageSize | If omitted or less than or equal to 0, 20 is used; otherwise the requested value is applied up to a maximum of 100 (MaxPageSize). |
Body Examples (POST / PUT)
URL: POST /gateway/points-config (create) or PUT /gateway/points-config (update with id in body).
Properties in camelCase. The other two criteria must be null (as below) or omitted.
Header — X times formula (criteriaType: 0, formulaBase: 0)
{
"order": 1,
"description": "One point per euro on the document total",
"active": true,
"cumulative": true,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 0,
"defaultHeaderCriteria": {
"totalPoints": 0,
"pointsBase": 1,
"eachY": 0,
"formulaBase": 0,
"documentField": 0
},
"defaultDetailsItemCriteria": null,
"defaultDetailsFamilyCriteria": null
}
documentField: 0 document total, 1 net total, 2 taxes total, 3 amount paid.
Header — X per Y formula (criteriaType: 0, formulaBase: 1)
eachY must be greater than zero; otherwise the server returns PointsConfig.InvalidEachY.
{
"order": 2,
"description": "10 points for every 50 € of net total",
"active": true,
"cumulative": false,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 0,
"defaultHeaderCriteria": {
"totalPoints": 0,
"pointsBase": 10,
"eachY": 50,
"formulaBase": 1,
"documentField": 1
},
"defaultDetailsItemCriteria": null,
"defaultDetailsFamilyCriteria": null
}
Detail by Item (criteriaType: 1, defaultDetailsItemCriteria)
searchPool cannot be empty when the criterion is filled (PointsConfig.InvalidItemSearchPool). Each element: id, description, keyId (item identifier in the system).
List (searchType: 0) — points apply to lines whose item belongs to the defined set.
{
"order": 3,
"description": "One point per quantity unit on selected items",
"active": true,
"cumulative": true,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 1,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": {
"totalPoints": 0,
"pointsBase": 1,
"eachY": 0,
"formulaBase": 0,
"detailField": 0,
"searchType": 0,
"searchPool": [
{ "id": 101, "description": "Item A", "keyId": "ART-001" },
{ "id": 102, "description": "Item B", "keyId": "ART-002" }
]
},
"defaultDetailsFamilyCriteria": null
}
Individual search (searchType: 1) — same structure; searchPool usually has a single item when the business rule is “a specific item”.
{
"order": 4,
"description": "2 points per euro on the line total (VAT) — single item",
"active": true,
"cumulative": false,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 1,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": {
"totalPoints": 0,
"pointsBase": 2,
"eachY": 0,
"formulaBase": 0,
"detailField": 2,
"searchType": 1,
"searchPool": [
{ "id": 200, "description": "Premium item", "keyId": "PREM-01" }
]
},
"defaultDetailsFamilyCriteria": null
}
Item detail with X per Y — formulaBase: 1 and eachY > 0.
{
"order": 5,
"description": "1 point for every 5 € of price with VAT on lines of listed items",
"active": true,
"cumulative": true,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 1,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": {
"totalPoints": 0,
"pointsBase": 1,
"eachY": 5,
"formulaBase": 1,
"detailField": 1,
"searchType": 0,
"searchPool": [
{ "id": 301, "description": "Cola soft drink 33cl", "keyId": "BEB-001" }
]
},
"defaultDetailsFamilyCriteria": null
}
Detail by Family (criteriaType: 2, defaultDetailsFamilyCriteria)
searchPool cannot be empty (PointsConfig.InvalidFamilySearchPool). Each element: id, description, idParent (ancestor in the family hierarchy).
{
"order": 6,
"description": "Points per quantity on lines of selected families",
"active": true,
"cumulative": true,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 2,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": null,
"defaultDetailsFamilyCriteria": {
"totalPoints": 0,
"pointsBase": 1,
"eachY": 0,
"formulaBase": 0,
"detailField": 0,
"searchType": 0,
"searchPool": [
{ "id": 10, "description": "Grocery", "idParent": 0 },
{ "id": 11, "description": "Beverages", "idParent": 10 }
]
}
}
Family with X per Y on line total without VAT (detailField: 4):
{
"order": 7,
"description": "3 points for every 2 € of line total without VAT (listed families)",
"active": false,
"cumulative": false,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 2,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": null,
"defaultDetailsFamilyCriteria": {
"totalPoints": 0,
"pointsBase": 3,
"eachY": 2,
"formulaBase": 1,
"detailField": 4,
"searchType": 0,
"searchPool": [
{ "id": 20, "description": "Promotional bellflower", "idParent": 0 }
]
}
}
Replace id, keyId, idParent, and descriptions with valid values in your tenant.
Integration Notes
- Use
GET /gateway/points-config/next-orderto fillorderin new configurations. - On update, send
idwith the sameGuidthat identifies the record. - Keep one nested criterion consistent with
criteriaType; avoid sending all three objects filled if the product expects exclusivity. order >= 1is recommended, consistent with[Range]inPointsConfigDTOand the value suggested byGET .../next-order.
Conclusion
Points configuration management exposes CRUD over /gateway/points-config with validations dependent on criteriaType, formulaBase, and date range. Test in staging combinations of header vs detail, list vs minimal set in searchPool, and XTimes vs XForY formulas before production.
Related Resources
Last updated: May 14, 2026