Skip to main content

Mastering API Queries

🎯 Query Like a Pro

Master the art of efficient data retrieval with powerful filtering, pagination, and field selection techniques.

Quick Reference

🎯 Fields

Select specific columns to optimize response size and speed

?fields=id,name,price
🔍 Filter

Apply conditions to narrow down results

?filter=price>10&active=true
📄 Pagination

Navigate through large datasets efficiently

?page=2&limit=50

Understanding GET Requests

GET requests are your primary tool for retrieving data from the Juleb ERP API. They support powerful query parameters that allow you to precisely control what data you receive.

Core Query Parameters

ParameterPurposeDefaultRequired
fieldsSpecify which columns to returnAll fields
filterApply conditions to filter dataNone
pagePage number for pagination1
limitMaximum results per page10

🎯 Field Selection

Control exactly what data you receive to optimize performance and reduce bandwidth.

Why Use Field Selection?

❌ Without Field Selection
  • Downloads all columns (slower)
  • Larger response payloads
  • Higher bandwidth usage
  • Includes unnecessary data
✅ With Field Selection
  • Only downloads what you need
  • Smaller, faster responses
  • Reduced bandwidth costs
  • Cleaner, focused data

Field Selection Examples

Get only product ID and name
GET /api/v1/inventory/product?fields=id,name
curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
"https://$ACCOUNT_NAME.juleb.com/api/v1/inventory/product?fields=id,name"

Sample Response:

{
"data": [
{ "id": 1, "name": "Panadol" },
{ "id": 2, "name": "Aspirin" }
],
"meta": { "count": 2, "total": 150 }
}

🔍 Powerful Filtering

Apply precise conditions to find exactly the data you need.

Filter Operators Reference

OperatorSyntaxDescriptionExample
Equals=Exact matchname=Panadol
Not Equals!=Exclude exact matchname!=Panadol
Contains*Partial text matchname*pana
Not Contains!*Exclude partial matchname!*generic
Greater Than>Numeric comparisonprice>10
Greater/Equal>=Numeric comparisonprice>=10
Less Than<Numeric comparisonqty<50
Less/Equal<=Numeric comparisonqty<=50
In List[]Match any value in listid[1,2,3]
Not In List![]Exclude values in liststatus![draft,cancel]

Combining Filters

🔗 AND Logic (&)

All conditions must be true

name*Gel&price>5

Products containing "Gel" AND price greater than 5

🔀 OR Logic (|)

At least one condition must be true

categ_id=168|categ_id=169

Products in category 168 OR category 169


📄 Smart Pagination

Efficiently navigate through large datasets without overwhelming your application.

Pagination Strategy

📊 Default Limit

10 records - Perfect for UI lists

⚡ Optimal Range

25-100 records - Balance speed & data

🚨 Large Batches

500+ records - Use with caution

Pagination Examples

Get second page with 25 items
GET /api/v1/inventory/product?page=2&limit=25

Sample Response:

{
"data": [
/* 25 product records */
],
"meta": {
"count": 25,
"total": 1247
},
"pagination": {
"previousPage": 1,
"currentPage": 2,
"nextPage": 3,
"totalPages": 50
}
}

📊 Understanding API Responses

Multi-Record Response Structure

Complete response anatomy
{
"data": [
{
"id": 1,
"name": "Panadol Extra",
"default_code": "MED_1001",
"list_price": 12.5,
"qty_available": 150,
"active": true
},
{
"id": 2,
"name": "Aspirin 325mg",
"default_code": "MED_1002",
"list_price": 8.75,
"qty_available": 89,
"active": true
}
],
"meta": {
"count": 2, // Records in this response
"total": 1247 // Total matching records
},
"pagination": {
"previousPage": 1, // Previous page number (null if first)
"currentPage": 2, // Current page number
"nextPage": 3, // Next page number (null if last)
"totalPages": 624 // Total pages available
}
}
📊 data

Array of actual records returned by your query. Each object represents one record with the requested fields.

📈 meta
  • count: Records in current response
  • total: Total records matching your filter
📄 pagination

Navigation info for multi-page results. Use nextPage to continue fetching or check totalPages for progress.

Single Record Response

Single record by ID
{
"data": {
"id": 1,
"name": "Panadol Extra",
"default_code": "MED_1001",
"list_price": 12.5,
"qty_available": 150,
"active": true,
"categ_id": 168,
"create_date": "2024-01-15T10:30:00Z",
"write_date": "2025-01-28T14:22:00Z"
}
}
📋 Single vs Multiple Records
  • Multiple records: /inventory/product → Returns array in data with pagination
  • Single record: /inventory/product/123 → Returns object directly in data

🚀 Advanced Query Techniques

Combining All Parameters

Advanced inventory analysis query
GET /api/v1/inventory/product?
fields=id,name,default_code,qty_available,list_price,categ_id&
filter=categ_id[168,169,170]&qty_available>0&active=true&list_price>=5&
page=1&
limit=50
Complex query builder
class QueryBuilder {
constructor(baseUrl, endpoint) {
this.baseUrl = baseUrl;
this.endpoint = endpoint;
this.params = new URLSearchParams();
}

fields(...fieldNames) {
this.params.set("fields", fieldNames.join(","));
return this;
}

filter(filterString) {
const existing = this.params.get("filter");
if (existing) {
this.params.set("filter", `${existing}&${filterString}`);
} else {
this.params.set("filter", filterString);
}
return this;
}

page(pageNum) {
this.params.set("page", pageNum.toString());
return this;
}

limit(limitNum) {
this.params.set("limit", limitNum.toString());
return this;
}

build() {
return `${this.baseUrl}${this.endpoint}?${this.params.toString()}`;
}

async execute(apiKey) {
const url = this.build();
const response = await fetch(url, {
headers: { Authorization: `Bearer ${apiKey}` },
});
return response.json();
}
}

// Usage example
const query = new QueryBuilder(
`https://${accountName}.juleb.com/api/v1/`,
"inventory/product"
)
.fields("id", "name", "qty_available", "list_price")
.filter("categ_id[168,169]")
.filter("qty_available>10")
.filter("active=true")
.page(1)
.limit(25);

const results = await query.execute(apiKey);
console.log("Advanced query results:", results);