Skip to content

Rate Card Module APIs

The Unified Rate Card Module API is designed to manage and maintain comprehensive pricing structures within the system. This API enables businesses to create, retrieve, and manage complete rate cards with matrices, rows, dimensions, filters, and charges in a single transaction. The system supports complex pricing configurations with tenant-specific assignments and provides comprehensive functionality for managing the complete rate card lifecycle while ensuring data consistency and access control across different tenants.

API Documentation

Base URL

Terminal window
# Production
https://apis.prayog.io/gateway/ure/api
# Sandbox
https://sandbox-apis.prayog.io/gateway/ure/api

Available Endpoints

  1. Create Complete Rate Card
  2. Get All Rate Cards with Pagination
  3. Get Rate Card by ID
  4. Update Rate Card (Partial)
  5. Delete Rate Card (Soft Delete)
  6. Assign Rate Card to Tenant

API Endpoints

1. Create Complete Rate Card

Creates a complete rate card with matrices, rows, dimensions, filters, and charges in a single transaction.

Endpoint: POST /rate-cards/unified

Request Headers:

{
"Content-Type": "application/json",
"X-Tenant-Id": "550e8400-e29b-41d4-a716-446655440000"
}

Request Body Parameters

ParameterRequiredTypeDescription
nameYesstringRate card name
productTypeYesstringProduct type
isActiveNobooleanIs active (default: true)
isDefaultNobooleanIs default (default: false)
matricesNoarrayArray of matrices with rows. Each matrix can have allowedFilterKeys to define valid filters, and each row can have filters to apply conditional pricing
chargesNoarrayArray of charges
Request Body - Courier Rate Card Example
{
"name": "SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": true,
"isDefault": true,
"matrices": [
{
"matrixKey": "standard",
"allowedFilterKeys": [
{ "key": "Document type", "values": ["DOCS", "NON-DOCS"] },
{ "key": "Delivery mode", "values": ["SURFACE", "AIR"] }
],
"rows": [
{
"rate": 20,
"currency": "INR",
"location": "local",
"filters": [
{ "filterKey": "Document type", "filterValue": "DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 25,
"currency": "INR",
"location": "withinState",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 30,
"currency": "INR",
"location": "metro",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 35,
"currency": "INR",
"location": "roi",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 40,
"currency": "INR",
"location": "specialLocation",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 8,
"currency": "INR",
"location": "local",
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500,
"isLastSlab": true,
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 5001,
"maxValue": null,
"unit": "GRAMS"
}
]
}
]
},
{
"matrixKey": "express",
"rows": [
{
"rate": 30,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 35,
"currency": "INR",
"location": "withinState",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
},
{
"matrixKey": "premium",
"rows": [
{
"rate": 40,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
}
],
"charges": [
{
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 50
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"isDefault": true
},
{
"chargeName": "Insurance Charges",
"chargeCode": "INSURANCE_CHARGES",
"chargeType": "FORMULA",
"chargeLevel": "ORDER",
"calculationConfig": {
"formula": "percentage * productValue / 100",
"variables": {
"percentage": "10",
"productValue": "userOptions.insurance.amount"
},
"userOptions": {
"required": ["insurance"]
}
},
"taxConfig": {
"isTaxable": true,
"taxRate": 18
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 2,
"isActive": true,
"isTax": false,
"isDefault": false
},
{
"chargeName": "Cash on Delivery Charges",
"chargeCode": "COD_CHARGES",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 20,
"userOptions": {
"required": ["cod"]
}
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 3,
"isActive": true,
"isTax": false,
"isDefault": true
},
{
"chargeName": "Weight-Based Handling Fee",
"chargeCode": "WEIGHT_HANDLING_FEE",
"chargeType": "SLAB",
"chargeLevel": "ORDER",
"calculationConfig": {
"baseDimension": "weight",
"slabs": [
{
"from": 0,
"to": 1000,
"rate": 20
},
{
"from": 1001,
"to": 2000,
"rate": 25
},
{
"from": 2001,
"to": 3000,
"rate": 30
},
{
"from": 3001,
"to": 4000,
"rate": 35
},
{
"from": 4001,
"to": 5000,
"rate": 40
},
{
"from": 5001,
"to": null,
"rate": 18,
"isLastSlab": true,
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500
}
]
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 9,
"isActive": true,
"isTax": false,
"isDefault": true
},
{
"chargeName": "Goods and Services Tax",
"chargeCode": "GST",
"chargeType": "PERCENTAGE",
"chargeLevel": "ORDER",
"calculationConfig": {
"percentage": 18
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 8,
"isActive": true,
"isTax": true,
"isDefault": true
}
]
}
Request Body - Gym Rate Card Example
{
"name": "IronFlex Gym Rate Card",
"productType": "GYM",
"isActive": true,
"isDefault": true,
"matrices": [
{
"matrixKey": "membership",
"allowedFilterKeys": [
{ "key": "membershipType", "values": ["basic", "gold", "platinum", "diamond"] },
{ "key": "duration", "values": ["1_month", "3_months", "6_months", "12_months"] }
],
"rows": [
{
"rate": 3000,
"unit": "PACKAGE",
"currency": "INR",
"location": "all_branches",
"dimensions": [],
"filters": [
{ "filterKey": "membershipType", "filterValue": "basic" },
{ "filterKey": "duration", "filterValue": "1_month" }
]
},
{
"rate": 25000,
"unit": "PACKAGE",
"currency": "INR",
"location": "all_branches",
"dimensions": [],
"filters": [
{ "filterKey": "membershipType", "filterValue": "basic" },
{ "filterKey": "duration", "filterValue": "12_months" }
]
},
{
"rate": 4500,
"unit": "PACKAGE",
"currency": "INR",
"location": "premium_branch",
"dimensions": [],
"filters": [
{ "filterKey": "membershipType", "filterValue": "gold" },
{ "filterKey": "duration", "filterValue": "1_month" }
]
},
{
"rate": 80000,
"unit": "PACKAGE",
"currency": "INR",
"location": "premium_branch",
"dimensions": [],
"filters": [
{ "filterKey": "membershipType", "filterValue": "diamond" },
{ "filterKey": "duration", "filterValue": "12_months" }
]
}
]
},
{
"matrixKey": "personal_training",
"allowedFilterKeys": [
{ "key": "trainerLevel", "values": ["junior", "senior", "expert"] }
],
"rows": [
{
"rate": 500,
"unit": "SESSION",
"currency": "INR",
"location": "any",
"dimensions": [
{ "dimensionKey": "sessions", "minValue": 1, "maxValue": 5, "unit": "SESSIONS" }
],
"filters": [
{ "filterKey": "trainerLevel", "filterValue": "junior" }
]
},
{
"rate": 700,
"unit": "SESSION",
"currency": "INR",
"location": "any",
"excessCalculationUnit": "SESSION",
"excessCalculationValue": 1,
"isLastSlab": true,
"dimensions": [
{ "dimensionKey": "sessions", "minValue": 11, "maxValue": null, "unit": "SESSIONS" }
],
"filters": [
{ "filterKey": "trainerLevel", "filterValue": "expert" }
]
}
]
},
{
"matrixKey": "group_classes",
"allowedFilterKeys": [
{ "key": "classType", "values": ["yoga", "zumba", "pilates"] }
],
"rows": [
{
"rate": 200,
"unit": "SESSION",
"currency": "INR",
"location": "any",
"dimensions": [
{ "dimensionKey": "sessions", "minValue": 1, "maxValue": 10, "unit": "SESSIONS" }
],
"filters": [
{ "filterKey": "classType", "filterValue": "yoga" }
]
},
{
"rate": 230,
"unit": "SESSION",
"currency": "INR",
"location": "any",
"excessCalculationUnit": "SESSION",
"excessCalculationValue": 1,
"isLastSlab": true,
"dimensions": [
{ "dimensionKey": "sessions", "minValue": 11, "maxValue": null, "unit": "SESSIONS" }
],
"filters": [
{ "filterKey": "classType", "filterValue": "zumba" }
]
}
]
},
{
"matrixKey": "equipment_rental",
"allowedFilterKeys": [
{ "key": "equipmentType", "values": ["treadmill", "elliptical", "rowing_machine"] }
],
"rows": [
{
"rate": 50,
"unit": "HOUR",
"currency": "INR",
"location": "any",
"dimensions": [
{ "dimensionKey": "hours", "minValue": 1, "maxValue": 4, "unit": "HOURS" }
],
"filters": [
{ "filterKey": "equipmentType", "filterValue": "treadmill" }
]
},
{
"rate": 90,
"unit": "HOUR",
"currency": "INR",
"location": "any",
"excessCalculationUnit": "HOUR",
"excessCalculationValue": 1,
"isLastSlab": true,
"dimensions": [
{ "dimensionKey": "hours", "minValue": 5, "maxValue": null, "unit": "HOURS" }
],
"filters": [
{ "filterKey": "equipmentType", "filterValue": "rowing_machine" }
]
}
]
}
],
"charges": [
{
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": { "fixedAmount": 300 },
"applicableFilters": { "service_type": ["membership", "personal_training", "group_classes", "equipment_rental"] },
"priority": 1,
"isActive": true,
"isTax": false
},
{
"chargeName": "Locker Charges",
"chargeCode": "LOCKER_CHARGES",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 200,
"userOptions": { "required": ["locker"] }
},
"applicableFilters": { "service_type": ["membership", "personal_training", "group_classes"] },
"priority": 2,
"isActive": true,
"isTax": false
}
]
}
Response
{
"status": "success",
"message": "Rate card created successfully",
"data": {
"id": "67ee7910e0e74a6679a68356",
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"name": "SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": true,
"isDefault": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"matrices": [
{
"id": "matrix-123",
"matrixKey": "standard",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": [
{
"id": "row-123",
"rate": 20,
"currency": "INR",
"location": "local",
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"id": "row-124",
"rate": 25,
"currency": "INR",
"location": "withinState",
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
},
{
"id": "matrix-124",
"matrixKey": "express",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": [
{
"id": "row-125",
"rate": 30,
"currency": "INR",
"location": "local",
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
}
],
"charges": [
{
"id": "charge-123",
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 50
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
},
{
"id": "charge-124",
"chargeName": "Insurance Charges",
"chargeCode": "INSURANCE_CHARGES",
"chargeType": "FORMULA",
"chargeLevel": "ORDER",
"calculationConfig": {
"formula": "percentage * productValue / 100",
"variables": {
"percentage": "10",
"productValue": "userOptions.insurance.amount"
},
"userOptions": {
"required": ["insurance"]
}
},
"taxConfig": {
"isTaxable": true,
"taxRate": 18
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 2,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
]
}
}

Error Responses:

  1. Validation Error (400 Bad Request)
{
"status": "error",
"statusCode": 400,
"message": "Missing Required Header: X-Tenant-Id",
"details": {}
}
  1. Conflict Error (409)
{
"statusCode": 409,
"message": "Rate card already exists",
"error": "Conflict"
}
  1. Internal server Error (500)
{
"statusCode": 500,
"error": "Failed to create rate card",
"data": null
}

2. Get All Rate Cards with Pagination

Returns paginated rate cards for the specified tenant with optional search and filtering.

Endpoint: GET /rate-cards/unified/all

Request Headers:

{
"Content-Type": "application/json",
"X-Tenant-Id": "550e8400-e29b-41d4-a716-446655440000"
}

Query Parameters

ParameterTypeRequiredDescriptionDefault
pagenumberNoPage number1
limitnumberNoPage size (max: 100)10
searchNamestringNoSearch rate card name (partial match)-
searchProductTypestringNoSearch product type (partial match)-
isActivebooleanNoFilter by active status-
isDefaultbooleanNoFilter by default status-
createdFromstringNoStart date for created date range (ISO string)-
createdTostringNoEnd date for created date range (ISO string)-

Example Request:

GET /rate-cards/unified/all?page=1&limit=10&searchName=courier&isActive=true
Response
{
"status": "success",
"message": "Rate cards retrieved successfully",
"data": [
{
"id": "67ee7910e0e74a6679a68356",
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"name": "SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": true,
"isDefault": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"matrices": [
{
"id": "matrix-123",
"matrixKey": "standard",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": []
},
{
"id": "matrix-124",
"matrixKey": "express",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": []
},
{
"id": "matrix-125",
"matrixKey": "premium",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": []
}
],
"charges": [
{
"id": "charge-123",
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 50
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
]
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}

Error Response: (400 Bad Request)

{
"statusCode": 400,
"message": "Missing Required Header: X-Tenant-Id",
"error": "Bad Request"
}

3. Get Rate Card by ID

Returns complete rate card details including all matrices, rows, and charges.

Endpoint: GET /rate-cards/unified/:id

Request Headers:

{
"Content-Type": "application/json",
"X-Tenant-Id": "550e8400-e29b-41d4-a716-446655440000"
}

Path Parameters:

  • id: Rate card ID (UUID)

Example Request:

GET /rate-cards/unified/67ee7910e0e74a6679a68356
Response
{
"status": "success",
"message": "Rate card retrieved successfully",
"data": {
"id": "67ee7910e0e74a6679a68356",
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"name": "SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": true,
"isDefault": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"matrices": [
{
"id": "matrix-123",
"matrixKey": "standard",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": [
{
"id": "row-123",
"rate": 20,
"currency": "INR",
"location": "local",
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"id": "row-124",
"rate": 25,
"currency": "INR",
"location": "withinState",
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"id": "row-125",
"rate": 8,
"currency": "INR",
"location": "local",
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500,
"isLastSlab": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 5001,
"maxValue": null,
"unit": "GRAMS"
}
]
}
]
},
{
"id": "matrix-124",
"matrixKey": "express",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": [
{
"id": "row-126",
"rate": 30,
"currency": "INR",
"location": "local",
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
}
],
"charges": [
{
"id": "charge-123",
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 50
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
},
{
"id": "charge-124",
"chargeName": "Insurance Charges",
"chargeCode": "INSURANCE_CHARGES",
"chargeType": "FORMULA",
"chargeLevel": "ORDER",
"calculationConfig": {
"formula": "percentage * productValue / 100",
"variables": {
"percentage": "10",
"productValue": "userOptions.insurance.amount"
},
"userOptions": {
"required": ["insurance"]
}
},
"taxConfig": {
"isTaxable": true,
"taxRate": 18
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 2,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
},
{
"id": "charge-125",
"chargeName": "Weight-Based Handling Fee",
"chargeCode": "WEIGHT_HANDLING_FEE",
"chargeType": "SLAB",
"chargeLevel": "ORDER",
"calculationConfig": {
"baseDimension": "weight",
"slabs": [
{
"from": 0,
"to": 1000,
"rate": 20
},
{
"from": 1001,
"to": 2000,
"rate": 25
},
{
"from": 2001,
"to": 3000,
"rate": 30
},
{
"from": 3001,
"to": 4000,
"rate": 35
},
{
"from": 4001,
"to": 5000,
"rate": 40
},
{
"from": 5001,
"to": null,
"rate": 18,
"isLastSlab": true,
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500
}
]
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 9,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
]
}
}

Error Response: (404 Not Found)

{
"statusCode": 404,
"message": "Rate card not found",
"error": "Not Found"
}

4. Update Rate Card (Partial)

Updates rate card with partial data. Supports updating basic details, matrices, and charges.

Endpoint: PATCH /rate-cards/unified/:id

Request Headers:

{
"Content-Type": "application/json",
"X-Tenant-Id": "550e8400-e29b-41d4-a716-446655440000"
}

Request Parameters

ParameterRequiredTypeDescription
idYesstringRate card ID (UUID)

Request Body Parameters

ParameterRequiredTypeDescription
nameNostringRate card name
productTypeNostringProduct type
isActiveNobooleanIs active
isDefaultNobooleanIs default
matricesNoarrayArray of matrices with rows
chargesNoarrayArray of charges
Request Body - Update Example
{
"name": "Updated SMILE Courier Rate Card",
"isActive": false,
"charges": [
{
"chargeName": "Updated Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 75
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false
}
]
}
Response
{
"status": "success",
"message": "Rate card updated successfully",
"data": {
"id": "67ee7910e0e74a6679a68356",
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Updated SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": false,
"isDefault": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T11:00:00.000Z",
"matrices": [
{
"id": "matrix-123",
"matrixKey": "standard",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": []
}
],
"charges": [
{
"id": "charge-123",
"chargeName": "Updated Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 75
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T11:00:00.000Z"
}
]
}
}

Error Responses:

  1. Validation Error (400 Bad Request)
{
"statusCode": 400,
"message": "Invalid data or missing header",
"error": "Bad Request"
}
  1. Not Found Error (404)
{
"statusCode": 404,
"message": "Rate card not found",
"error": "Not Found"
}

5. Delete Rate Card (Soft Delete)

Soft deletes rate card by marking it as inactive.

Endpoint: DELETE /rate-cards/unified/:id

Request Headers:

{
"Content-Type": "application/json",
"X-Tenant-Id": "550e8400-e29b-41d4-a716-446655440000"
}

Path Parameters:

  • id: Rate card ID (UUID)

Example Request:

DELETE /rate-cards/unified/67ee7910e0e74a6679a68356
Response
{
"status": "success",
"message": "Rate card deleted successfully"
}

Error Response: (404 Not Found)

{
"statusCode": 404,
"message": "Rate card not found",
"error": "Not Found"
}

6. Assign Rate Card to Tenant

Assigns a rate card to the tenant.

Endpoint: POST /rate-cards/unified/assign

Request Headers:

{
"Content-Type": "application/json",
"X-Tenant-Id": "550e8400-e29b-41d4-a716-446655440000"
}

Request Body Parameters

ParameterRequiredTypeDescription
assignToTenantIdYesstringTenant ID to assign the rate card to
rateCardIdYesstringRate card ID to assign
assignedByUserIdYesstringUser ID of the assigner
fromDateNostring (ISO date)From date (default: immediate)
toDateNostring (ISO date)To date (default: permanent)
Request Body
{
"assignToTenantId": "child-tenant-123",
"rateCardId": "67ee7910e0e74a6679a68356",
"assignedByUserId": "user-456",
"fromDate": "2024-01-15T00:00:00.000Z",
"toDate": "2024-12-31T23:59:59.999Z"
}
Response
{
"status": "success",
"message": "Rate card assigned successfully",
"data": {
"assignedRateCardId": "assignment-789",
"assignedToTenantId": "child-tenant-123",
"assignedByUserId": "user-456",
"fromDate": "2024-01-15T00:00:00.000Z",
"toDate": "2024-12-31T23:59:59.999Z",
"isActive": true,
"assignedAt": "2024-01-15T10:30:00.000Z"
}
}

Error Response: (400 Bad Request)

{
"statusCode": 400,
"message": "Missing header or invalid data",
"error": "Bad Request"
}

[1 tool called]

Example Usage

Below are examples of how to use the Unified Rate Card Module API with cURL using the real courier rate card data.

Create a Complete Courier Rate Card

Create a Complete Courier Rate Card
Terminal window
curl --location 'https://apis.prayog.io/gateway/ure/api/rate-cards/unified' \
--header 'X-Tenant-Id: 550e8400-e29b-41d4-a716-446655440000' \
--header 'Content-Type: application/json' \
--data '{
"name": "SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": true,
"isDefault": true,
"matrices": [
{
"matrixKey": "standard",
"rows": [
{
"rate": 20,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 25,
"currency": "INR",
"location": "withinState",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 30,
"currency": "INR",
"location": "metro",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 35,
"currency": "INR",
"location": "roi",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 40,
"currency": "INR",
"location": "specialLocation",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 8,
"currency": "INR",
"location": "local",
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500,
"isLastSlab": true,
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 5001,
"maxValue": null,
"unit": "GRAMS"
}
]
}
]
},
{
"matrixKey": "express",
"rows": [
{
"rate": 30,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
}
],
"charges": [
{
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 50
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"isDefault": true
},
{
"chargeName": "Insurance Charges",
"chargeCode": "INSURANCE_CHARGES",
"chargeType": "FORMULA",
"chargeLevel": "ORDER",
"calculationConfig": {
"formula": "percentage * productValue / 100",
"variables": {
"percentage": "10",
"productValue": "userOptions.insurance.amount"
},
"userOptions": {
"required": ["insurance"]
}
},
"taxConfig": {
"isTaxable": true,
"taxRate": 18
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 2,
"isActive": true,
"isTax": false,
"isDefault": false
},
{
"chargeName": "Weight-Based Handling Fee",
"chargeCode": "WEIGHT_HANDLING_FEE",
"chargeType": "SLAB",
"chargeLevel": "ORDER",
"calculationConfig": {
"baseDimension": "weight",
"slabs": [
{
"from": 0,
"to": 1000,
"rate": 20
},
{
"from": 1001,
"to": 2000,
"rate": 25
},
{
"from": 2001,
"to": 3000,
"rate": 30
},
{
"from": 3001,
"to": 4000,
"rate": 35
},
{
"from": 4001,
"to": 5000,
"rate": 40
},
{
"from": 5001,
"to": null,
"rate": 18,
"isLastSlab": true,
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500
}
]
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 9,
"isActive": true,
"isTax": false,
"isDefault": true
}
]
}'

Response:

{
"status": "success",
"message": "Rate card created successfully",
"data": {
"id": "67ee7910e0e74a6679a68356",
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"name": "SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": true,
"isDefault": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"matrices": [
{
"id": "matrix-123",
"matrixKey": "standard",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": [
{
"id": "row-123",
"rate": 20,
"currency": "INR",
"location": "local",
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
}
],
"charges": [
{
"id": "charge-123",
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 50
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
]
}
}

Get All Rate Cards with Pagination

Get All Rate Cards with Pagination
Terminal window
curl --location 'https://apis.prayog.io/gateway/ure/api/rate-cards/unified/all?page=1&limit=10&searchName=courier&isActive=true' \
--header 'X-Tenant-Id: 550e8400-e29b-41d4-a716-446655440000'

Response:

{
"status": "success",
"message": "Rate cards retrieved successfully",
"data": [
{
"id": "67ee7910e0e74a6679a68356",
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"name": "SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": true,
"isDefault": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"matrices": [
{
"id": "matrix-123",
"matrixKey": "standard",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": []
},
{
"id": "matrix-124",
"matrixKey": "express",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": []
},
{
"id": "matrix-125",
"matrixKey": "premium",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": []
}
],
"charges": [
{
"id": "charge-123",
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 50
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
]
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}

Get Rate Card by ID

Get Rate Card by ID
Terminal window
curl --location 'https://apis.prayog.io/gateway/ure/api/rate-cards/unified/67ee7910e0e74a6679a68356' \
--header 'X-Tenant-Id: 550e8400-e29b-41d4-a716-446655440000'

Response:

{
"status": "success",
"message": "Rate card retrieved successfully",
"data": {
"id": "67ee7910e0e74a6679a68356",
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"name": "SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": true,
"isDefault": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"matrices": [
{
"id": "matrix-123",
"matrixKey": "standard",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": [
{
"id": "row-123",
"rate": 20,
"currency": "INR",
"location": "local",
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"id": "row-124",
"rate": 25,
"currency": "INR",
"location": "withinState",
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"id": "row-125",
"rate": 8,
"currency": "INR",
"location": "local",
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500,
"isLastSlab": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 5001,
"maxValue": null,
"unit": "GRAMS"
}
]
}
]
}
],
"charges": [
{
"id": "charge-123",
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 50
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
},
{
"id": "charge-124",
"chargeName": "Insurance Charges",
"chargeCode": "INSURANCE_CHARGES",
"chargeType": "FORMULA",
"chargeLevel": "ORDER",
"calculationConfig": {
"formula": "percentage * productValue / 100",
"variables": {
"percentage": "10",
"productValue": "userOptions.insurance.amount"
},
"userOptions": {
"required": ["insurance"]
}
},
"taxConfig": {
"isTaxable": true,
"taxRate": 18
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 2,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
]
}
}

Update Rate Card

Update Rate Card
Terminal window
curl --location --request PATCH 'https://apis.prayog.io/gateway/ure/api/rate-cards/unified/67ee7910e0e74a6679a68356' \
--header 'X-Tenant-Id: 550e8400-e29b-41d4-a716-446655440000' \
--header 'Content-Type: application/json' \
--data '{
"name": "Updated SMILE Courier Rate Card",
"isActive": false,
"charges": [
{
"chargeName": "Updated Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 75
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false
}
]
}'

Response:

{
"status": "success",
"message": "Rate card updated successfully",
"data": {
"id": "67ee7910e0e74a6679a68356",
"tenantId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Updated SMILE Courier Rate Card",
"productType": "COURIER",
"isActive": false,
"isDefault": true,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T11:00:00.000Z",
"matrices": [
{
"id": "matrix-123",
"matrixKey": "standard",
"createdAt": "2024-01-15T10:30:00.000Z",
"rows": []
}
],
"charges": [
{
"id": "charge-123",
"chargeName": "Updated Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"chargeLevel": "ORDER",
"calculationConfig": {
"fixedAmount": 75
},
"applicableFilters": {
"service_type": ["standard", "express", "premium"]
},
"priority": 1,
"isActive": true,
"isTax": false,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T11:00:00.000Z"
}
]
}
}

Delete Rate Card

Delete Rate Card
Terminal window
curl --location --request DELETE 'https://apis.prayog.io/gateway/ure/api/rate-cards/unified/67ee7910e0e74a6679a68356' \
--header 'X-Tenant-Id: 550e8400-e29b-41d4-a716-446655440000'

Response:

{
"status": "success",
"message": "Rate card deleted successfully"
}

Assign Rate Card

Assign Rate Card
Terminal window
curl --location 'https://apis.prayog.io/gateway/ure/api/rate-cards/unified/assign' \
--header 'X-Tenant-Id: 550e8400-e29b-41d4-a716-446655440000' \
--header 'Content-Type: application/json' \
--data '{
"assignToTenantId": "child-tenant-123",
"rateCardId": "67ee7910e0e74a6679a68356",
"assignedByUserId": "user-456",
"fromDate": "2024-01-15T00:00:00.000Z",
"toDate": "2024-12-31T23:59:59.999Z"
}'

Response:

{
"status": "success",
"message": "Rate card assigned successfully",
"data": {
"assignedRateCardId": "assignment-789",
"assignedToTenantId": "child-tenant-123",
"assignedByUserId": "user-456",
"fromDate": "2024-01-15T00:00:00.000Z",
"toDate": "2024-12-31T23:59:59.999Z",
"isActive": true,
"assignedAt": "2024-01-15T10:30:00.000Z"
}
}

Error Codes

Error CodeTitleDescription
400Bad RequestThe request payload is invalid or missing required fields.
401UnauthorizedAuthentication token is missing or invalid.
403ForbiddenThe authenticated user does not have permission to access this resource.
404Not FoundThe requested resource does not exist.
409ConflictThe request conflicts with the current state of the server.
429Too Many RequestsRate limit exceeded. Please try again later.
500Internal Server ErrorAn unexpected error occurred on the server.

Data Models

Unified Rate Card

  • id: Unique identifier for the rate card
  • tenantId: Tenant ID associated with the rate card
  • name: Name of the rate card
  • productType: Type of product (e.g., COURIER, LOGISTICS, GYM)
  • isActive: Whether the rate card is active
  • isDefault: Whether this is the default rate card
  • createdAt: Creation timestamp
  • updatedAt: Last update timestamp
  • matrices: Array of matrices with rows
  • charges: Array of charges

Unified Matrix

  • id: Unique identifier for the matrix
  • matrixKey: Matrix key (e.g., standard, express, premium)
  • allowedFilterKeys: Optional array of allowed filter keys with their allowed values for rows in this matrix
  • createdAt: Creation timestamp
  • rows: Array of matrix rows

Unified Matrix Row

  • id: Unique identifier for the matrix row
  • rate: Rate value
  • currency: Currency (default: INR)
  • location: Location for the rate (e.g., local, withinState, metro, roi, specialLocation)
  • excessCalculationUnit: Unit for excess calculation (e.g., GRAMS)
  • excessCalculationValue: Value for excess calculation
  • isLastSlab: Whether this is the last slab
  • filters: Optional array of filters that apply to this row (filterKey, filterValue pairs)
  • dimensions: Array of dimensions for this row
  • createdAt: Creation timestamp

Unified Matrix Row Filter

  • filterKey: Filter key (e.g., “Document type”, “Delivery mode”)
  • filterValue: Filter value (e.g., “DOCS”, “SURFACE”, “AIR”)

Allowed Filter Key

  • key: Filter key name (e.g., “Document type”, “Delivery mode”)
  • values: Optional array of allowed values for this filter key (if not provided, any value is allowed)

Unified Charge

  • id: Unique identifier for the charge
  • chargeName: Name of the charge
  • chargeCode: Code for the charge
  • chargeType: Type of charge (FIXED, PERCENTAGE, SLAB, FORMULA)
  • chargeLevel: Level of charge (ORDER, INVOICE)
  • calculationConfig: Configuration for calculation
  • applicableFilters: Filters where this charge applies
  • priority: Priority of the charge
  • isActive: Whether the charge is active
  • isTax: Whether this is a tax charge
  • taxConfig: Tax configuration (if applicable)
  • createdAt: Creation timestamp
  • updatedAt: Last update timestamp

Unified Matrix Row Dimension

  • dimensionKey: Dimension key (e.g., weight, distance)
  • minValue: Minimum value
  • maxValue: Maximum value (null for open-ended ranges)
  • unit: Unit (e.g., GRAMS, KM)

Unified Charge Calculation Config

  • fixedAmount: Fixed amount for FIXED type
  • percentage: Percentage for PERCENTAGE type
  • baseDimension: Base dimension for SLAB type
  • slabs: Slabs for SLAB type
  • formula: Formula for FORMULA type
  • variables: Variables for formula
  • defaultValues: Default values for variables
  • userOptions: User options configuration

Unified Tax Config

  • isTaxable: Is taxable
  • taxRate: Tax rate percentage
  • taxOnAmount: Tax on amount type (CHARGE_AMOUNT, BASE_RATE)

Important Notes

  1. X-Tenant-Id Header: All endpoints require the X-Tenant-Id header with a valid UUID. This is mandatory for all requests.

  2. Unified Approach: These endpoints allow you to create complete rate cards with all related data (matrices, rows, charges) in a single transaction, making it more efficient than the individual endpoints.

  3. Pagination: The list endpoint supports pagination with configurable page size (max 100 items per page).

  4. Search and Filtering: The list endpoint supports search by name and product type, plus filtering by active/default status and date ranges.

  5. Soft Delete: The delete operation performs a soft delete by marking the rate card as inactive rather than removing it from the database.

  6. Partial Updates: The update endpoint supports partial updates, allowing you to update only the fields you need to change.

  7. Real-world Examples: The examples in this documentation are based on actual courier rate card configurations, including:

    • Multiple service types (standard, express, premium)
    • Location-based pricing (local, withinState, metro, roi, specialLocation)
    • Weight-based dimensions with excess calculation
    • Complex charge structures including fixed, percentage, slab, and formula-based charges
    • Tax configurations and user options
    • Matrix filters for document type (DOCS/NON-DOCS) and delivery mode (SURFACE/AIR)
  8. Matrix Filters: Matrices can define filter keys that restrict which filter values can be used in matrix rows. This allows for:

    • Different pricing based on document type (Documents vs Non-Documents)
    • Different pricing based on delivery mode (Surface vs Air)
    • Validation of filter values against allowed values
    • Flexible pricing structures without creating separate matrices
  9. Charge Types Supported:

    • FIXED: Fixed amount charges (e.g., Registration Fee, COD Charges)
    • PERCENTAGE: Percentage-based charges (e.g., GST, Fragile Handling)
    • SLAB: Slab-based charges with weight ranges (e.g., Weight-Based Handling Fee)
    • FORMULA: Formula-based charges with variables (e.g., Insurance Charges, SMS Charges)

Understanding Different Types of Charges in Rate Cards

Based on the courier rate card example, here’s a simple explanation of the different types of charges that can be applied to your shipping orders:

1. FIXED Charges 💰

What it is: A set amount that’s always the same, regardless of package weight or value.

Real Examples from the Rate Card:

  • Registration Fee: ₹50 (always charged for every order)
  • Cash on Delivery (COD): ₹20 (only when customer pays on delivery)
  • Signature Required: ₹30 (only when signature is needed)

When to use: For services that have a standard cost regardless of package details.

Configuration Example:

{
"chargeName": "Registration Fee",
"chargeCode": "REGISTRATION_FEE",
"chargeType": "FIXED",
"calculationConfig": {
"fixedAmount": 50
}
}

2. PERCENTAGE Charges 📊

What it is: A percentage of the base rate or package value.

Real Examples from the Rate Card:

  • GST: 18% of the total amount (government tax)
  • Fragile Handling: 2.5% of base rate (for delicate items)
  • Fuel Surcharge: 2.5% of base rate (fuel cost adjustment)

When to use: For charges that should scale with the package value or base rate.

Configuration Example:

{
"chargeName": "Goods and Services Tax",
"chargeCode": "GST",
"chargeType": "PERCENTAGE",
"calculationConfig": {
"percentage": 18
}
}

3. SLAB Charges ⚖️

What it is: Different rates based on weight ranges (like a staircase pricing).

Real Examples from the Rate Card:

  • Weight-Based Handling Fee:
    • 0-1000g: ₹20
    • 1001-2000g: ₹25
    • 2001-3000g: ₹30
    • 3001-4000g: ₹35
    • 4001-5000g: ₹40
    • 5001g+: ₹18 per 500g excess

When to use: For charges that increase with package weight in specific ranges.

Configuration Example:

{
"chargeName": "Weight-Based Handling Fee",
"chargeCode": "WEIGHT_HANDLING_FEE",
"chargeType": "SLAB",
"calculationConfig": {
"baseDimension": "weight",
"slabs": [
{
"from": 0,
"to": 1000,
"rate": 20
},
{
"from": 1001,
"to": 2000,
"rate": 25
},
{
"from": 5001,
"to": null,
"rate": 18,
"isLastSlab": true,
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500
}
]
}
}

4. FORMULA Charges 🧮

What it is: Complex calculations using formulas with variables.

Real Examples from the Rate Card:

  • Insurance Charges: 10% of declared value (when customer chooses insurance)
  • SMS Charges: ₹2 per SMS (when customer wants SMS updates)
  • Address Correction: ₹50 (when address needs correction)

When to use: For charges that require complex calculations or depend on customer choices.

Configuration Example:

{
"chargeName": "Insurance Charges",
"chargeCode": "INSURANCE_CHARGES",
"chargeType": "FORMULA",
"calculationConfig": {
"formula": "percentage * productValue / 100",
"variables": {
"percentage": "10",
"productValue": "userOptions.insurance.amount"
},
"userOptions": {
"required": ["insurance"]
}
}
}

5. Tax Charges 🏛️

What it is: Government taxes that are calculated on other charges.

Real Examples from the Rate Card:

  • GST on Insurance: 18% tax on insurance charges
  • GST on Fragile Handling: 18% tax on fragile handling charges
  • GST on SMS: 18% tax on SMS charges

When to use: For government taxes that apply to specific services.

Configuration Example:

{
"chargeName": "GST on Insurance",
"chargeCode": "GST_INSURANCE",
"chargeType": "PERCENTAGE",
"calculationConfig": {
"percentage": 18
},
"taxConfig": {
"isTaxable": true,
"taxRate": 18
}
}

How Charges Are Calculated

Step-by-Step Example:

Let’s say you’re shipping a 1.5kg package with insurance worth ₹1000:

  1. Base Rate: ₹25 (from weight matrix)
  2. Registration Fee: ₹50 (FIXED)
  3. Weight Handling Fee: ₹25 (SLAB - falls in 1001-2000g range)
  4. Insurance: ₹100 (FORMULA - 10% of ₹1000)
  5. GST on Insurance: ₹18 (PERCENTAGE - 18% of ₹100)
  6. Total: ₹218

Charge Priority:

Charges are applied in order of priority (1 = first, 9 = last):

  1. Registration Fee (Priority 1)
  2. Insurance Charges (Priority 2)
  3. COD Charges (Priority 3)
  4. Weight Handling Fee (Priority 9)
  5. GST (Priority 8)

User Options:

Some charges require customer input:

  • Insurance: Customer must declare value
  • COD: Customer must choose cash on delivery
  • SMS: Customer must opt for SMS updates
  • Signature: Customer must request signature

Filters:

Charges can be applied to specific service types:

  • Standard Service: All charges apply
  • Express Service: All charges apply
  • Premium Service: All charges apply

Understanding Matrix Creation for Rate Cards

A matrix is like a pricing table that defines how much to charge based on different factors like weight, location, and service type. Think of it as a menu with different prices for different combinations.

What is a Matrix?

A matrix is a collection of pricing rules organized by:

  • Service Type: Standard, Express, Premium
  • Location: Local, Within State, Metro, ROI, Special Location
  • Weight Ranges: Different prices for different weight brackets

Matrix Structure

1. Matrix Key (Service Type)

This defines what type of service the matrix is for:

  • "standard" - Regular delivery service
  • "express" - Faster delivery service
  • "premium" - Premium delivery service

2. Allowed Filter Keys (Optional)

Define what filters can be used in this matrix’s rows:

  • key: Name of the filter (e.g., “Document type”, “Delivery mode”)
  • values: Optional list of allowed values (if omitted, any value is allowed)

3. Matrix Rows (Pricing Rules)

Each row defines a specific pricing rule with:

  • Rate: The price to charge
  • Location: Where this price applies
  • Dimensions: Weight ranges for this price
  • Filters: Optional filters that apply to this row (e.g., document type, delivery mode)
  • Currency: Usually INR

Simple Matrix Example

Let’s create a simple courier matrix:

{
"matrixKey": "standard",
"allowedFilterKeys": [
{ "key": "Document type", "values": ["DOCS", "NON-DOCS"] },
{ "key": "Delivery mode", "values": ["SURFACE", "AIR"] }
],
"rows": [
{
"rate": 20,
"currency": "INR",
"location": "local",
"filters": [
{ "filterKey": "Document type", "filterValue": "DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 25,
"currency": "INR",
"location": "withinState",
"filters": [
{ "filterKey": "Document type", "filterValue": "DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
}

What this means:

  • Standard service for packages up to 1kg (1000 grams)
  • Local delivery: ₹20
  • Within state delivery: ₹25

Weight-Based Pricing (Slabs)

For packages over 1kg, you need multiple rows with different weight ranges:

{
"matrixKey": "standard",
"rows": [
{
"rate": 20,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
},
{
"rate": 25,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 1001,
"maxValue": 2000,
"unit": "GRAMS"
}
]
},
{
"rate": 30,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 2001,
"maxValue": 3000,
"unit": "GRAMS"
}
]
}
]
}

What this means:

  • 0-1kg: ₹20
  • 1.001-2kg: ₹25
  • 2.001-3kg: ₹30

Excess Weight Calculation

For packages over your highest weight slab, you can set an excess calculation:

{
"rate": 8,
"currency": "INR",
"location": "local",
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500,
"isLastSlab": true,
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 5001,
"maxValue": null,
"unit": "GRAMS"
}
]
}

What this means:

  • For packages over 5kg
  • Charge ₹8 for every additional 500 grams
  • Example: 6kg package = ₹8 + ₹8 = ₹16 (for the extra 1kg)

Complete Matrix Example with Filters

Here’s a complete matrix for standard courier service with filters:

{
"matrixKey": "standard",
"allowedFilterKeys": [
{ "key": "Document type", "values": ["DOCS", "NON-DOCS"] },
{ "key": "Delivery mode", "values": ["SURFACE", "AIR"] }
],
"rows": [
{
"rate": 15,
"currency": "INR",
"location": "local",
"filters": [
{ "filterKey": "Document type", "filterValue": "DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 250,
"unit": "GRAMS"
}
]
},
{
"rate": 22,
"currency": "INR",
"location": "local",
"filters": [
{ "filterKey": "Document type", "filterValue": "DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 250,
"maxValue": 500,
"unit": "GRAMS"
}
]
},
{
"rate": 24,
"currency": "INR",
"location": "local",
"filters": [
{ "filterKey": "Document type", "filterValue": "NON-DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": null,
"unit": "GRAMS"
}
],
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 1000,
"isLastSlab": true
},
{
"rate": 75,
"currency": "INR",
"location": "withinState",
"filters": [
{ "filterKey": "Document type", "filterValue": "NON-DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "AIR" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": null,
"unit": "GRAMS"
}
],
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 1000,
"isLastSlab": true
},
{
"rate": 15,
"currency": "INR",
"location": "local",
"filters": [
{ "filterKey": "Document type", "filterValue": "DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 500,
"isLastSlab": true,
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 500,
"maxValue": null,
"unit": "GRAMS"
}
]
}
]
}

Pricing Summary:

  • Documents (DOCS) + Surface + Local (0-250g): ₹15
  • Documents (DOCS) + Surface + Local (250-500g): ₹22
  • Documents (DOCS) + Surface + Local (500g+): ₹15 per additional 500g
  • Non-Documents (NON-DOCS) + Surface + Local: ₹24 per kg
  • Non-Documents (NON-DOCS) + Air + Within State: ₹75 per kg

Multiple Service Types

You can create different matrices for different service types:

"matrices": [
{
"matrixKey": "standard",
"rows": [
{
"rate": 20,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
},
{
"matrixKey": "express",
"rows": [
{
"rate": 30,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
},
{
"matrixKey": "premium",
"rows": [
{
"rate": 40,
"currency": "INR",
"location": "local",
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 1000,
"unit": "GRAMS"
}
]
}
]
}
]

Service Pricing:

  • Standard: ₹20
  • Express: ₹30 (50% more for faster delivery)
  • Premium: ₹40 (100% more for premium service)

Matrix Creation Tips

  1. Start Simple: Begin with basic weight ranges (0-1kg, 1-2kg, etc.)
  2. Location-Based: Create different rates for different delivery locations
  3. Service Types: Have separate matrices for standard, express, premium
  4. Use Filters: Leverage filters to handle variations (document type, delivery mode) without creating separate matrices
  5. Define Filter Keys: Always define allowedFilterKeys with allowed values for validation
  6. Excess Weight: Always include an excess calculation for heavy packages
  7. Test Your Matrix: Make sure all weight ranges and filter combinations are covered without gaps
  8. Realistic Pricing: Set prices that make business sense

Common Matrix Patterns

Pattern 1: Simple Weight-Based

  • 0-1kg: ₹20
  • 1-2kg: ₹25
  • 2-3kg: ₹30
  • 3kg+: ₹8 per 500g excess

Pattern 2: Location-Based

  • Local: ₹20
  • Within State: ₹25
  • Metro: ₹30
  • ROI: ₹35
  • Special Location: ₹40

Pattern 3: Service Type-Based

  • Standard: Base rate
  • Express: Base rate × 1.5
  • Premium: Base rate × 2

This matrix system gives you complete control over your pricing while keeping it organized and easy to understand.

Understanding Matrix Filters

Matrix filters allow you to create different pricing rules for the same service type based on additional criteria like document type, delivery mode, package type, etc. This is more flexible than creating separate matrices for each combination.

What are Matrix Filters?

Filters enable you to:

  • Apply different rates based on package characteristics (e.g., Documents vs Non-Documents)
  • Handle different delivery modes (e.g., Surface vs Air)
  • Create conditional pricing without duplicating matrices

How Filters Work

1. Define Allowed Filter Keys at Matrix Level

At the matrix level, you define what filter keys are allowed and optionally restrict their values:

{
"matrixKey": "standard",
"allowedFilterKeys": [
{ "key": "Document type", "values": ["DOCS", "NON-DOCS"] },
{ "key": "Delivery mode", "values": ["SURFACE", "AIR"] }
],
"rows": [...]
}

What this means:

  • This matrix allows rows to use “Document type” and “Delivery mode” filters
  • “Document type” can only be “DOCS” or “NON-DOCS”
  • “Delivery mode” can only be “SURFACE” or “AIR”
  • If values is omitted or empty, any value is allowed for that key

2. Apply Filters to Matrix Rows

Each row specifies which filters apply to it:

{
"rate": 15,
"currency": "INR",
"location": "local",
"filters": [
{ "filterKey": "Document type", "filterValue": "DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 250,
"unit": "GRAMS"
}
]
}

What this means:

  • This row applies only to Documents (DOCS) sent via Surface delivery
  • When calculating rates, the system matches all provided filters

Real-World Filter Example

Here’s a complete example showing how filters work for a courier service:

{
"matrixKey": "standard",
"allowedFilterKeys": [
{ "key": "Document type", "values": ["DOCS", "NON-DOCS"] },
{ "key": "Delivery mode", "values": ["SURFACE", "AIR"] }
],
"rows": [
{
"rate": 15,
"currency": "INR",
"location": "local",
"filters": [
{ "filterKey": "Document type", "filterValue": "DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": 250,
"unit": "GRAMS"
}
]
},
{
"rate": 24,
"currency": "INR",
"location": "local",
"filters": [
{ "filterKey": "Document type", "filterValue": "NON-DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "SURFACE" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": null,
"unit": "GRAMS"
}
],
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 1000,
"isLastSlab": true
},
{
"rate": 75,
"currency": "INR",
"location": "withinState",
"filters": [
{ "filterKey": "Document type", "filterValue": "NON-DOCS" },
{ "filterKey": "Delivery mode", "filterValue": "AIR" }
],
"dimensions": [
{
"dimensionKey": "weight",
"minValue": 0,
"maxValue": null,
"unit": "GRAMS"
}
],
"excessCalculationUnit": "GRAMS",
"excessCalculationValue": 1000,
"isLastSlab": true
}
]
}

Pricing Summary:

  • Documents (DOCS) + Surface + Local (0-250g): ₹15
  • Non-Documents (NON-DOCS) + Surface + Local: ₹24 per kg
  • Non-Documents (NON-DOCS) + Air + Within State: ₹75 per kg

Filter Matching During Rate Calculation

When calculating a rate, you provide filters in your request:

{
"rateCardId": "rate-card-id",
"serviceType": "standard",
"location": "local",
"filters": {
"Document type": "DOCS",
"Delivery mode": "SURFACE"
},
"dimensions": {
"weight": 200
}
}

The system will:

  1. Find the matching matrix (by serviceType)
  2. Filter rows by location (local)
  3. Filter rows by provided filters (Document type: DOCS, Delivery mode: SURFACE)
  4. Find the row matching weight dimensions (200g)
  5. Return the rate (₹15 in this example)

Filter Validation

When creating or updating a rate card:

  • All filter keys in rows must be defined in allowedFilterKeys
  • All filter values must match the allowed values (if specified)
  • If allowedFilterKeys is empty or omitted, any filters are allowed (backward compatibility)

Benefits of Using Filters

  1. Reduced Duplication: One matrix can handle multiple scenarios
  2. Better Organization: Related pricing rules grouped together
  3. Validation: Ensures only valid filter combinations are used
  4. Flexibility: Easy to add new filter combinations without restructuring

Filter Best Practices

  1. Define Allowed Values: Always specify allowed values in allowedFilterKeys for validation
  2. Use Clear Names: Use descriptive filter key names (e.g., “Document type” not “doc”)
  3. Consistent Values: Use consistent value formats (e.g., always uppercase: “DOCS”, “NON-DOCS”)
  4. Complete Coverage: Ensure all filter combinations have matching rows
  5. Documentation: Document what each filter means for your use case

User Options Based Charges

Some charges are only applied when customers make specific choices. Here are simple examples:

1. Insurance Charges (Customer Choice)

What it is: Only charged when customer chooses insurance.

Configuration:

{
"chargeName": "Insurance Charges",
"chargeCode": "INSURANCE_CHARGES",
"chargeType": "FORMULA",
"calculationConfig": {
"formula": "percentage * productValue / 100",
"variables": {
"percentage": "10",
"productValue": "userOptions.insurance.amount"
},
"userOptions": {
"required": ["insurance"]
}
}
}

How it works:

  • Customer must select insurance option
  • Customer must declare value (e.g., ₹1000)
  • Charge = 10% of declared value = ₹100
  • If no insurance selected, no charge applied

2. COD Charges (Payment Method Choice)

What it is: Only charged when customer chooses Cash on Delivery.

Configuration:

{
"chargeName": "Cash on Delivery Charges",
"chargeCode": "COD_CHARGES",
"chargeType": "FIXED",
"calculationConfig": {
"fixedAmount": 20,
"userOptions": {
"required": ["cod"]
}
}
}

How it works:

  • Only applied when customer chooses COD payment
  • Fixed charge of ₹20
  • If customer pays online, no COD charge

3. SMS Notification Charges (Optional Service)

What it is: Only charged when customer wants SMS updates.

Configuration:

{
"chargeName": "SMS Notification Charges",
"chargeCode": "SMS_CHARGES",
"chargeType": "FORMULA",
"calculationConfig": {
"formula": "smsCount * ratePerSMS",
"variables": {
"smsCount": "userOptions.sms.count",
"ratePerSMS": "2"
},
"userOptions": {
"required": ["sms"]
}
}
}

How it works:

  • Customer can choose SMS notifications
  • Customer can select number of SMS (1-5)
  • Charge = SMS count × ₹2 per SMS
  • If customer chooses 3 SMS = ₹6 total

4. Signature Required Charges (Optional Service)

What it is: Only charged when customer wants signature confirmation.

Configuration:

{
"chargeName": "Signature Required Charges",
"chargeCode": "SIGNATURE_CHARGES",
"chargeType": "FIXED",
"calculationConfig": {
"fixedAmount": 30,
"userOptions": {
"required": ["signature"]
}
}
}

How it works:

  • Only applied when customer requests signature
  • Fixed charge of ₹30
  • If no signature requested, no charge

Simple Example:

Package: 1kg, Local delivery, with insurance ₹1000 and SMS notifications

Charges Applied:

  1. Base Rate: ₹20
  2. Registration Fee: ₹50 (always applied)
  3. Insurance: ₹100 (10% of ₹1000 - customer choice)
  4. SMS: ₹2 (1 SMS - customer choice)
  5. Total: ₹172

If same package without insurance and SMS:

  1. Base Rate: ₹20
  2. Registration Fee: ₹50 (always applied)
  3. Total: ₹70