Offers API
Complete API reference for managing offer templates in the Billerang catalog.
Overview
An OfferTemplate is the top-level catalog entity that groups products/services into sellable bundles. Offers define what a customer can subscribe to and at what terms.
Endpoints
List Offers
GET /v1/catalog/offers?range=0-24&status=active
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
range | string | Pagination range (e.g., 0-24) |
status | string | Filter by status: draft, ready, live, retired |
category | string | Filter by category code |
seller | string | Filter by seller code |
sort | string | Sort field (prefix - for descending) |
fields | string | Partial response fields |
expand | string | Related entities to include |
Response:
[
{
"code": "SAAS_ENTERPRISE",
"name": "Enterprise SaaS Plan",
"status": "active",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": null,
"product_codes": ["PROD_PLATFORM", "PROD_SUPPORT"],
"category_codes": ["ENTERPRISE"],
"seller_codes": ["SELLER_EU"]
}
]
Headers:
Content-Range: offers 0-24/142
Accept-Range: offers 50
Link: </v1/catalog/offers?range=25-49>; rel="next"
Advanced Search
For complex queries, use the search DSL:
POST /v1/catalog/offers/search
{
"filters": {
"status": ["active", "launched"],
"valid_from": { "gte": "2024-01-01" },
"product_codes": { "contains": "PROD_PLATFORM" }
},
"sort": ["-created_at"],
"range": "0-24",
"expand": ["products"]
}
Get Offer
GET /v1/catalog/offers/{code}
Response:
{
"code": "SAAS_ENTERPRISE",
"name": "Enterprise SaaS Plan",
"description": "Full platform access with premium support",
"status": "active",
"valid_from": "2024-01-01T00:00:00Z",
"valid_to": null,
"product_codes": ["PROD_PLATFORM", "PROD_SUPPORT"],
"category_codes": ["ENTERPRISE"],
"seller_codes": ["SELLER_EU"],
"discount_plan_codes": ["DISC_ANNUAL_10"],
"auto_end_of_engagement": false,
"attributes": {
"min_commitment_months": 12,
"max_users": 500
}
}
With ?expand=products:
{
"code": "SAAS_ENTERPRISE",
"name": "Enterprise SaaS Plan",
"products": [
{
"code": "PROD_PLATFORM",
"name": "Platform Access",
"product_line": "SOFTWARE",
"current_version": {
"version": 2,
"status": "published",
"charge_codes": ["RC_PLATFORM_MONTHLY", "OS_SETUP_FEE"]
}
},
{
"code": "PROD_SUPPORT",
"name": "Premium Support",
"product_line": "SERVICES",
"current_version": {
"version": 1,
"status": "published",
"charge_codes": ["RC_SUPPORT_MONTHLY"]
}
}
]
}
Create Offer
POST /v1/catalog/offers
{
"code": "SAAS_ENTERPRISE",
"name": "Enterprise SaaS Plan",
"description": "Full platform access with premium support",
"product_codes": ["PROD_PLATFORM", "PROD_SUPPORT"],
"category_codes": ["ENTERPRISE"],
"seller_codes": ["SELLER_EU"]
}
Response: 201 Created + Location: /v1/catalog/offers/SAAS_ENTERPRISE
Upsert Offer
POST /v1/catalog/offers/{code}
- If offer exists: updates it (200 OK)
- If offer doesn't exist: creates it with that code (201 Created)
Supports newCode field to rename the offer's code:
{
"newCode": "SAAS_ENTERPRISE_V2",
"name": "Enterprise SaaS Plan v2",
"product_codes": ["PROD_PLATFORM_V2", "PROD_SUPPORT"]
}
Update Offer
PUT /v1/catalog/offers/{code}
Partial update -- only send fields you want to change:
{
"name": "Updated Enterprise Plan",
"status": "launched"
}
Delete Offer
DELETE /v1/catalog/offers/{code}
Response: 204 No Content
Only allowed for offers in draft status. Active/launched offers must be retired first.
Manage Products
Add product to offer:
POST /v1/catalog/offers/{code}/products
{ "product_code": "PROD_ADDON_ANALYTICS" }
Remove product from offer:
DELETE /v1/catalog/offers/{code}/products/{product_code}
Count
GET /v1/catalog/offers/count?status=active
Response:
{ "count": 42 }
Bulk Operations
POST /v1/catalog/offers/bulk
{
"operations": [
{
"action": "create",
"body": { "code": "OFFER_A", "name": "Plan A", "product_codes": ["PROD_1"] }
},
{
"action": "upsert",
"code": "OFFER_B",
"body": { "name": "Updated Plan B" }
},
{
"action": "delete",
"code": "OFFER_OLD"
}
]
}
Offer Lifecycle
Portal status mapping:
| Portal Status | Backend Statuses |
|---|---|
draft | IN_STUDY, IN_DESIGN, IN_TEST |
ready | ACTIVE |
live | LAUNCHED |
retired | RETIRED, OBSOLETE, REJECTED |
Offer Components
Offers group products through two models:
NEW Model (Recommended)
Products are linked via OfferComponent with CPQ product references:
{
"code": "SAAS_ENTERPRISE",
"products": [
{
"code": "PROD_PLATFORM",
"mandatory": true,
"default_quantity": 1,
"min_quantity": 1,
"max_quantity": 1
},
{
"code": "PROD_ADDON",
"mandatory": false,
"default_quantity": 0,
"min_quantity": 0,
"max_quantity": 10
}
]
}
OLD Model (Legacy)
Services linked via OfferServiceTemplate -- still supported for backward compatibility.
Error Codes
| Error Code | HTTP | Description |
|---|---|---|
OFFER_NOT_FOUND | 404 | Offer code doesn't exist |
OFFER_ALREADY_EXISTS | 409 | Duplicate offer code |
OFFER_VALIDATION_FAILED | 400 | Invalid payload |
OFFER_STATUS_TRANSITION_INVALID | 422 | Invalid status change |
OFFER_HAS_ACTIVE_SUBSCRIPTIONS | 422 | Cannot delete offer with active subscriptions |