Portal Community

Endpoints

Two equivalent endpoints return the same JSON payload. Use the explicit .json suffix when your client sets Accept headers dynamically and you need format pinning regardless of header negotiation:

MethodURLFormat
GET /api/v1/expressions/multiquery/{templateCode} JSON (default)
GET /api/v1/expressions/multiquery/{templateCode}.json JSON (explicit)

Request

Headers

HeaderValueRequired
Authorization Bearer {token} Yes
Accept application/json Recommended

Path Parameters

ParameterTypeDescription
templateCode string The catalogue code identifying the Multi-Query template stored in dbo.Shared_Configurations. Must match the Code column exactly (case-insensitive).

Query Parameters

Any additional query string parameters are forwarded to the template engine as named SQL parameters. The engine matches them to @ParamName placeholders in any SQL node within the template tree. Parameter names are case-insensitive.

GET /api/v1/expressions/multiquery/PAYROLL_SUMMARY?DepartmentID=42&PayPeriod=2026-05
Authorization: Bearer eyJ...

In the example above, @DepartmentID and @PayPeriod become available in every SQL node of the template. @TenantID is always injected from the JWT and must not be passed by the caller.

Response Shape

The response is a JSON array at the root level. Each element represents one row from the root query. Nested child collections appear as named array properties on each row object. The property name for each child collection is taken from the collectionName field in the template definition.

// Structural schema
[
  {
    // ... columns from root query row
    "childCollectionName": [
      {
        // ... columns from child query row
        "grandchildCollectionName": [
          {
            // ... columns from grandchild query row
          }
        ]
      }
    ]
  }
]
TenantID Security

TenantID is extracted from the caller's JWT and injected into every SQL node in the template tree — at every depth. The caller cannot pass or override TenantID via query string or request body. This guarantees strict tenant isolation across all nested queries.

Sample Response

The following example shows a three-level hierarchy: EmployeesPayslipsDeductions. Each level is represented as an inline nested array on its parent object.

[
  {
    "EmployeeID": 1,
    "FirstName": "Alice",
    "LastName": "Nguyen",
    "DepartmentID": 42,
    "DepartmentName": "Engineering",
    "payslips": [
      {
        "PayslipID": 101,
        "Period": "2026-05",
        "GrossPay": 5000.00,
        "NetPay": 3850.00,
        "ProcessedOn": "2026-05-25T00:00:00",
        "deductions": [
          {
            "DeductionID": 201,
            "Type": "Tax",
            "Amount": 1000.00,
            "RuleRef": "TAX-PAYE-2026"
          },
          {
            "DeductionID": 202,
            "Type": "NationalInsurance",
            "Amount": 150.00,
            "RuleRef": "NI-CLASS1-2026"
          }
        ]
      },
      {
        "PayslipID": 102,
        "Period": "2026-04",
        "GrossPay": 5000.00,
        "NetPay": 3850.00,
        "ProcessedOn": "2026-04-25T00:00:00",
        "deductions": [
          {
            "DeductionID": 198,
            "Type": "Tax",
            "Amount": 1000.00,
            "RuleRef": "TAX-PAYE-2026"
          }
        ]
      }
    ]
  },
  {
    "EmployeeID": 2,
    "FirstName": "Marcus",
    "LastName": "Bell",
    "DepartmentID": 42,
    "DepartmentName": "Engineering",
    "payslips": []
  }
]

Key observations from the sample above:

Error Responses

HTTP StatusMeaningCommon Cause
401 Unauthorized Missing or invalid JWT Token expired, missing Authorization header, or invalid signature
403 Forbidden Insufficient role Caller's JWT does not include the TenantAdmin role required for this endpoint
404 Not Found Template not found templateCode does not match any record in dbo.Shared_Configurations for the caller's tenant
429 Too Many Requests Rate limit exceeded ApiLimit("MultiQuery.Execute") threshold reached — retry after the interval indicated in the Retry-After response header
500 Internal Server Error Execution failure SQL error in one of the template nodes, missing required parameter, or database connectivity issue

Rate Limiting

This endpoint is protected by the ApiLimit("MultiQuery.Execute") rate limit policy. Limits are configured per tenant by a platform administrator and are not exposed in this documentation. When a limit is exceeded, the server responds with 429 Too Many Requests and a Retry-After header indicating when the limit window resets.

For high-frequency consumers, consider using the cacheSeconds property in your template definition to serve repeated identical requests from cache without incurring additional database queries or rate-limit credits.