Goods/Services Inquiry by Goods Code (T144)
Batch query goods or services by their registered goods codes. This endpoint returns unit of measure configurations, scaling values, and alternative unit mappings for enabled goods. Request and response are encrypted.
Endpoint Overviewβ
| Property | Value |
|---|---|
| Interface Code | T144 |
| Request Encrypted | β Yes |
| Response Encrypted | β Yes |
| Request Body | { "goodsCode": "0001,0002", "tin": "..." } |
| Response Format | JSON Array |
Flow Descriptionβ
- Client submits one or more
goodsCodevalues (comma-separated) and optional principaltinfor agent queries. - Server validates goods codes against registered goods with
statusCode = 101(enabled). - Server returns configuration details for each matched goods:
- Primary unit of measure (
measureUnit) - Piece unit configuration (
havePieceUnit,pieceMeasureUnit, scaling values) - Alternative unit mappings (
haveOtherUnit,goodsOtherUnitsarray)
- Primary unit of measure (
- Client uses response to populate unit selectors, calculate conversions, or validate invoice line items.
π‘ Tip: Use T144 after T130 (Goods Upload) to verify unit configurations before issuing invoices. For agent invoicing, include the principal's
tinto query goods authorized for that agent.
- PHP
- JavaScript / TypeScript
- Python
try {
// Call T144: Goods Inquiry by Goods Code
$response = $client->queryGoodsByCode(
goodsCode: '0001,0002', // Comma-separated goods codes
tin: '1000029771' // Optional: principal TIN for agent queries
);
$items = $response['data']['content'] ?? $response;
if (is_array($items) && count($items) > 0) {
echo "β
Retrieved " . count($items) . " goods configuration(s)\n";
foreach ($items as $goods) {
echo " β’ Code: {$goods['goodsCode']}\n";
echo " Unit: {$goods['measureUnit']} (T115 rateUnit)\n";
// Piece unit info
if (($goods['havePieceUnit'] ?? '') === '101') {
echo " Piece Unit: {$goods['pieceMeasureUnit']} (scaled: {$goods['pieceScaledValue']})\n";
}
// Alternative units
if (($goods['haveOtherUnit'] ?? '') === '101' && !empty($goods['goodsOtherUnits'])) {
echo " Alternative Units:\n";
foreach ($goods['goodsOtherUnits'] as $alt) {
echo " - {$alt['otherUnit']}: scaled {$alt['otherScaled']}, pkg {$alt['packageScaled']}\n";
}
}
}
} else {
echo "β οΈ No enabled goods found for provided codes\n";
}
} catch (\UraEfrisSdk\Exceptions\APIException $e) {
echo "β Query failed: " . $e->getMessage() . "\n";
echo " Return Code: " . $e->getReturnCode() . "\n";
}
try {
// Call T144: Goods Inquiry by Goods Code
const response = await client.queryGoodsByCode(
'0001,0002', // goodsCode (comma-separated)
'1000029771' // tin (optional, for agent queries)
);
const items = response?.data?.content ?? response;
if (Array.isArray(items) && items.length > 0) {
console.log(`β
Retrieved ${items.length} goods configuration(s)`);
for (const goods of items) {
console.log(` β’ Code: ${goods.goodsCode}`);
console.log(` Unit: ${goods.measureUnit} (T115 rateUnit)`);
// Piece unit info
if (goods.havePieceUnit === '101') {
console.log(` Piece Unit: ${goods.pieceMeasureUnit} (scaled: ${goods.pieceScaledValue})`);
}
// Alternative units
if (goods.haveOtherUnit === '101' && Array.isArray(goods.goodsOtherUnits)) {
console.log(' Alternative Units:');
for (const alt of goods.goodsOtherUnits) {
console.log(` - ${alt.otherUnit}: scaled ${alt.otherScaled}, pkg ${alt.packageScaled}`);
}
}
}
return items;
} else {
console.warn('β οΈ No enabled goods found for provided codes');
return [];
}
} catch (error: any) {
console.error(`β Query failed: ${error.message}`);
if (error.returnCode) {
console.error(` Return Code: ${error.returnCode}`);
}
throw error;
}
try:
# Call T144: Goods Inquiry by Goods Code
response = client.query_goods_by_code(
goods_code='0001,0002', # Comma-separated goods codes
tin='1000029771' # Optional: principal TIN for agent queries
)
items = response.get("data", {}).get("content", response)
if isinstance(items, list) and len(items) > 0:
print(f"β
Retrieved {len(items)} goods configuration(s)")
for goods in items:
print(f" β’ Code: {goods['goodsCode']}")
print(f" Unit: {goods['measureUnit']} (T115 rateUnit)")
# Piece unit info
if goods.get("havePieceUnit") == "101":
print(f" Piece Unit: {goods['pieceMeasureUnit']} (scaled: {goods['pieceScaledValue']})")
# Alternative units
if goods.get("haveOtherUnit") == "101" and goods.get("goodsOtherUnits"):
print(" Alternative Units:")
for alt in goods["goodsOtherUnits"]:
print(f" - {alt['otherUnit']}: scaled {alt['otherScaled']}, pkg {alt['packageScaled']}")
else:
print("β οΈ No enabled goods found for provided codes")
except Exception as e:
print(f"β Query failed: {e}")
if hasattr(e, "return_code"):
print(f" Return Code: {e.return_code}")
raise
Request Structureβ
{
"data": {
"content": "BASE64_ENCRYPTED_PAYLOAD",
"signature": "JKQWJK34K32JJEK2JQWJ5678",
"dataDescription": {
"codeType": "1",
"encryptCode": "2",
"zipCode": "0"
}
},
"globalInfo": {
"interfaceCode": "T144",
"appId": "AP04",
"version": "1.1.20191201",
"tin": "1000029771",
"deviceNo": "TCS9e0df01728335239",
"taxpayerID": "1"
}
}
Request Fields (Encrypted Payload)β
| Field | Required | Type | Length | Description |
|---|---|---|---|---|
goodsCode | β Yes | String | Unlimited | One or more goods codes separated by commas (e.g., "0001,0002"). Only goods with statusCode=101 (enabled) are returned. |
tin | β No | String | β€20 | Principal agent TIN. Required when querying goods for agent invoicing workflows. |
π‘ Tip: Maximum practical limit for
goodsCodelist is ~50 codes per request. For larger batches, split into multiple calls.
Response Structureβ
{
"data": {
"content": [
{
"goodsCode": "0001",
"measureUnit": "101",
"havePieceUnit": "101",
"pieceMeasureUnit": "101",
"haveOtherUnit": "101",
"packageScaledValue": "1",
"pieceScaledValue": "500",
"goodsOtherUnits": [
{
"otherUnit": "AF",
"otherScaled": "1000",
"packageScaled": "1"
}
]
}
]
},
"globalInfo": {
"interfaceCode": "T144",
"returnStateInfo": {
"returnCode": "00",
"returnMessage": "SUCCESS"
}
}
}
Response Fieldsβ
Goods Configuration Array Itemsβ
| Field | Required | Type | Description |
|---|---|---|---|
goodsCode | β Yes | String (β€50) | Goods code (echoed from request) |
measureUnit | β Yes | String (3) | Primary unit of measure code from T115 rateUnit dictionary |
havePieceUnit | β Yes | String (3) | 101=Yes (has piece unit), 102=No |
pieceMeasureUnit | β No | String (3) | Piece unit code from T115 rateUnit; required if havePieceUnit=101, must be empty if 102 |
haveOtherUnit | β Yes | String (3) | 101=Yes (has alternative units), 102=No |
packageScaledValue | β Yes | Number | Scaling factor: 1 package = X measureUnit |
pieceScaledValue | β Yes | Number | Scaling factor: 1 piece = X measureUnit |
goodsOtherUnits | β No | Array | Alternative unit mappings (only if haveOtherUnit=101) |
goodsOtherUnits Array Itemsβ
| Field | Required | Type | Description |
|---|---|---|---|
otherUnit | β Yes | String (3) | Alternative unit code from T115 rateUnit; cannot equal measureUnit or pieceMeasureUnit |
otherScaled | β Yes | Number | Scaling factor: 1 otherUnit = X measureUnit |
packageScaled | β Yes | Number | Scaling factor: 1 package = X otherUnit |
π‘ Tip: Use scaling values to convert quantities between units during invoice preparation. Example: if
pieceScaledValue=500andmeasureUnit=101(per stick), then 1 piece = 500 sticks.
Return Codesβ
| Code | Message | Description |
|---|---|---|
00 | SUCCESS | Goods configurations retrieved successfully |
99 | Unknown error | Generic server error |
400 | Device does not exist | deviceNo not registered for this TIN |
402 | Device key expired | Device credentials expired; re-run T102 |
403 | Device status is abnormal | Device blocked or suspended |
2194 | goodsCode:cannot be empty! | Missing goodsCode in request |
2195 | goodsCode:Byte length cannot be greater than 50! | Individual goods code exceeds limit |
2255 | goodsCode:cannot be empty! | Empty goods code in comma-separated list |
2256 | goodsCode:Byte length cannot be greater than 50! | Individual code in list exceeds limit |
2835 | branchId:cannot be empty! | Agent query requires valid branchId context |
2836 | branchId:Byte length cannot be greater than 18! | Branch ID format error |
2837 | branchId does not belong to current taxpayer! | Branch not owned by authenticated TIN |
3104 | tin: If 'queryType' is 'Agent goods query', 'tin' cannot be empty | Agent query missing principal TIN |
3106 | branchId does not belong to taxpayer '*' | Branch ownership validation failed |
π‘ Tip: Goods not found or with
statusCodeβ 101are silently omitted from the response arrayβthis is not an error condition.
Common Use Casesβ
-
Invoice Line Validation
Verify unit of measure and scaling values before submitting T109 invoice lines to prevent2243(unit mismatch) errors. -
Agent Goods Authorization
Query goods authorized for a specific agent by including the principal'stinto filter eligible items. -
Unit Conversion Logic
UsepackageScaledValue,pieceScaledValue, andgoodsOtherUnitsto build client-side quantity converters for multi-unit goods. -
Goods Configuration Cache Refresh
Periodically call T144 for critical goods codes to detect URA-side unit configuration changes. -
Bulk Goods Setup Verification
After uploading goods via T130, use T144 to confirm all codes were registered with expected unit configurations. -
Fuel Product Unit Validation
ForgoodsTypeCode=102(fuel), verifymeasureUnitmatches EDC-compatible units from T171 before invoicing.
Integration Checklistβ
β
Validate each goodsCode is β€50 characters before joining with commas
β
Handle empty response array gracefully (goods not found or disabled)
β
Cache response data with TTL to reduce API calls for frequently-used goods
β
For agent workflows: validate tin belongs to an active principal before querying
β
Cross-reference measureUnit, pieceMeasureUnit, and otherUnit values against T115 dictionary
β
Use scaling values (packageScaledValue, pieceScaledValue, otherScaled) for accurate quantity conversions
β
Log queried goods codes for audit trails in multi-tenant or agent environments
β
Re-query goods configurations after T130 upload to confirm successful registration