Quick Start Guide
Get up and running with Q01 Core APIs in just a few minutes.
Prerequisites
Before you begin, ensure you have:
- Access to a Q01 environment - CoreService URL (e.g.,
https://coreservice.q01.io) - JWT token - Authentication token with valid claims
- Dimension registered - At least one dimension (e.g.,
PRDfor products) defined in TB_DIM - API client - curl, Postman, or your programming language's HTTP client
Step 1: Authenticate
Q01 Core APIs use JWT Bearer token authentication.
Your JWT should include claims:
{
"profile": "developer",
"peso": 100, // Permission weight (range: 0-100 or *)
"tenantId": "00000Q01-0000-0001-0000-000CUSTOMER",
"userId": "user123",
"ambiente": "1,2,3", // Environments you can access
"grants": {...} // Permission grants
}
For this guide, we'll assume you have a valid token.
Step 2: Query Data (Read Operation)
Example: List All Products
curl -X GET 'https://coreservice.q01.io/api/v4/core/PRD?source=productList¢er_dett=visualizza' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'
What's happening:
GET→ CoreService routes to CoreQuery (read operation)/api/v4/core/PRD→ Query the "PRD" dimension (products)source=productList→ Security area (COD_MENU)center_dett=visualizza→ List view context (returns fields with COD_ON_OFF='L')
Response:
[
{
"PRD_ID": 1,
"XPRD01": "Widget Pro",
"XPRD02": 49.99,
"XPRD03": "PRD-2025-00001"
},
{
"PRD_ID": 2,
"XPRD01": "Gadget Plus",
"XPRD02": 79.99,
"XPRD03": "PRD-2025-00002"
}
]
Example: Get Single Product
curl -X GET 'https://coreservice.q01.io/api/v4/core/PRD/1?source=productDetail¢er_dett=dettaglio' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'
Response:
{
"PRD_ID": 1,
"XPRD01": "Widget Pro",
"XPRD02": 49.99,
"XPRD03": "PRD-2025-00001",
"XPRD04": "Professional-grade widget with advanced features",
"XPRD05": "Electronics",
"OWNER": "user123",
"CDATA": "20251201120000"
}
Note: Detail view returns more fields (COD_ON_OFF contains 'D').
Example: Filter Products
curl -X GET 'https://coreservice.q01.io/api/v4/core/PRD?source=productList¢er_dett=visualizza&$filter=XPRD02 gt 50' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'
Response:
[
{
"PRD_ID": 2,
"XPRD01": "Gadget Plus",
"XPRD02": 79.99,
"XPRD03": "PRD-2025-00002"
}
]
What's happening:
$filter=XPRD02 gt 50→ CoreQuery addsWHERE XPRD02 > 50to SQL- Use operators (
gt,lt,eq,ne,ge,le) instead of symbols (>,<,=) to prevent SQL injection - Only products with price > 50 returned
Example: Sort and Paginate
curl -X GET 'https://coreservice.q01.io/api/v4/core/PRD?source=productList¢er_dett=visualizza&$order=XPRD02 DESC&$offset=0&$num_rows=10' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'
What's happening:
$order=XPRD02 DESC→ Sort by price descending$offset=0&$num_rows=10→ First page, 10 items
Step 3: Create Data (Write Operation)
Example: Create a Product
curl -X POST 'https://coreservice.q01.io/api/v4/core/PRD' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"source": "productManagement",
"XPRD01": "New Widget",
"XPRD02": 59.99
}'
What's happening:
POST→ CoreService routes to CoreWrite (write operation)source=productManagement→ Security area (must have grant level 4)- CoreWrite validates:
- JWT token is valid
- User has write permission for "productManagement"
XPRD01andXPRD02have COD_ON_OFF containing 'N' (required on create)- Field types match TB_COST definitions
- CoreWrite executes pre-insert functions (e.g., generates counter for XPRD03)
- CoreWrite creates record in transaction
- CoreWrite publishes outbox event to RabbitMQ
Response:
[
{
"code": 201,
"insertedId": "3",
"body": {
"PRD_ID": 3,
"XPRD01": "New Widget",
"XPRD02": 59.99,
"XPRD03": "PRD-2025-00003"
},
"fields": {
"XPRD01": {
"codice": "XPRD01",
"descrizione": "Product Name",
"tipo_campo": "text",
"visibilita": "D,N,M,L,R,S"
},
"XPRD02": {
"codice": "XPRD02",
"descrizione": "Price",
"tipo_campo": "prezzo",
"visibilita": "D,N,M,L,R,S"
}
}
}
]
Step 4: Update Data
Example: Full Update (PUT)
curl -X PUT 'https://coreservice.q01.io/api/v4/core/PRD/3' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"source": "productManagement",
"XPRD01": "Updated Widget",
"XPRD02": 64.99,
"XPRD04": "Updated description"
}'
What's happening:
PUT→ Full update (must provide all required fields with COD_ON_OFF='M')- CoreWrite validates grant level 2 (modify permission)
- Updates record, sets
LOWNERandLDATAautomatically - Creates outbox event
Response:
{
"code": 200,
"modifiedId": "3",
"body": {
"PRD_ID": 3,
"XPRD01": "Updated Widget",
"XPRD02": 64.99,
"XPRD04": "Updated description"
},
"fields": {
"XPRD01": {
"codice": "XPRD01",
"descrizione": "Product Name",
"tipo_campo": "text",
"visibilita": "D,N,M,L,R,S"
}
}
}
Example: Partial Update (PATCH)
curl -X PATCH 'https://coreservice.q01.io/api/v4/core/PRD/3' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"source": "productManagement",
"XPRD02": 69.99
}'
What's happening:
PATCH→ Partial update (only update specified fields)- Skips required field validation - can update just one field
- Still validates field types and permissions
Response:
{
"code": 200,
"modifiedId": "3",
"body": {
"PRD_ID": 3,
"XPRD02": 69.99
},
"fields": {
"XPRD02": {
"codice": "XPRD02",
"descrizione": "Price",
"tipo_campo": "prezzo",
"visibilita": "D,N,M,L,R,S"
}
}
}
Step 5: Delete Data
Example: Soft Delete (Logical Delete)
curl -X DELETE 'https://coreservice.q01.io/api/v4/core/PRD/3?source=productManagement' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'
What's happening:
- Sets
TREC='C'(cancelled) instead of physically deleting - Record still exists but marked as deleted
- Can be restored by setting
TREC='M' - Creates outbox event with operation="logicalDelete"
Response:
{
"status": 200,
"message": "Record deleted successfully"
}
Example: Physical Delete (Force Delete)
curl -X DELETE 'https://coreservice.q01.io/api/v4/core/PRD/3?source=productManagement&forceDelete=true' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'
What's happening:
- Physically removes record from database
- Cannot be restored
- Creates outbox event with operation="physicalDelete"
Step 6: Get Field Metadata
Example: Retrieve Field Definitions
curl -X GET 'https://coreservice.q01.io/api/v4/core/PRD/fields?source=productManagement¢er_dett=nuovo' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN'
What's happening:
- Returns metadata for fields visible in "nuovo" (create) context
- Filtered by COD_ON_OFF containing 'N'
- Filtered by user's peso (permission weight)
Response:
{
"XPRD01": {
"codice": "XPRD01",
"descrizione": "Product Name",
"tipo_campo": "text",
"obbligatorio": "1",
"visibilita": "L,D,N,M,R,S",
"sequenza": 10
},
"XPRD02": {
"codice": "XPRD02",
"descrizione": "Price",
"tipo_campo": "prezzo",
"obbligatorio": "1",
"visibilita": "L,D,N,M,R,S",
"sequenza": 20
}
}
Use this to:
- Build dynamic forms in UI
- Understand which fields are required
- Get field labels and types
- Know field ordering (COD_SEQUENZA)
JavaScript/TypeScript Example
// core-api-client.ts
class Q01CoreAPIClient {
private baseURL: string;
private token: string;
constructor(baseURL: string, token: string) {
this.baseURL = baseURL;
this.token = token;
}
// Read operation (GET)
async query(dim: string, params: {
source: string;
center_dett?: string;
filter?: string;
order?: string;
offset?: number;
num_rows?: number;
}) {
const query = new URLSearchParams(params as any);
const response = await fetch(
`${this.baseURL}/api/v4/core/${dim}?${query}`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${this.token}`,
},
}
);
return response.json();
}
// Write operation (POST)
async create(dim: string, data: any) {
const response = await fetch(
`${this.baseURL}/api/v4/core/${dim}`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
}
);
return response.json();
}
// Update operation (PUT)
async update(dim: string, id: number, data: any) {
const response = await fetch(
`${this.baseURL}/api/v4/core/${dim}/${id}`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
}
);
return response.json();
}
// Partial update (PATCH)
async patch(dim: string, id: number, data: any) {
const response = await fetch(
`${this.baseURL}/api/v4/core/${dim}/${id}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
}
);
return response.json();
}
// Delete operation
async delete(dim: string, id: number, source: string, forceDelete = false) {
const query = new URLSearchParams({ source, ...(forceDelete && { forceDelete: 'true' }) });
const response = await fetch(
`${this.baseURL}/api/v4/core/${dim}/${id}?${query}`,
{
method: 'DELETE',
headers: {
'Authorization': `Bearer ${this.token}`,
},
}
);
return response.json();
}
// Get field metadata
async getFields(dim: string, source: string, center_dett: string) {
const query = new URLSearchParams({ source, center_dett });
const response = await fetch(
`${this.baseURL}/api/v4/core/${dim}/fields?${query}`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${this.token}`,
},
}
);
return response.json();
}
}
// Usage
const client = new Q01CoreAPIClient('https://coreservice.q01.io', 'YOUR_JWT_TOKEN');
// Query products
const products = await client.query('PRD', {
source: 'productList',
center_dett: 'visualizza',
filter: 'XPRD02 gt 50',
order: 'XPRD02 DESC',
offset: 0,
num_rows: 10,
});
// Create product
const newProduct = await client.create('PRD', {
source: 'productManagement',
XPRD01: 'New Widget',
XPRD02: 59.99,
});
// Update product
await client.update('PRD', 3, {
source: 'productManagement',
XPRD01: 'Updated Widget',
XPRD02: 64.99,
});
// Partial update
await client.patch('PRD', 3, {
source: 'productManagement',
XPRD02: 69.99,
});
// Delete product
await client.delete('PRD', 3, 'productManagement');
// Get field metadata
const fields = await client.getFields('PRD', 'productManagement', 'nuovo');
Common Query Parameters
For Read Operations (GET)
| Parameter | Purpose | Example |
|---|---|---|
source | Security area (COD_MENU) | source=productList |
center_dett | View context | center_dett=visualizza (list), dettaglio (detail) |
$filter | WHERE conditions | $filter=XPRD02 gt 50 AND XPRD06 eq 1 |
$order | ORDER BY clause | $order=XPRD01 ASC, XPRD02 DESC |
$offset | LIMIT offset | $offset=100 (skip first 100 rows) |
$num_rows | LIMIT count | $num_rows=50 (return 50 rows) |
$select | Field projection | $select=XPRD01,XPRD02 (only these fields) |
$group | GROUP BY clause | $group=XPRD05 |
For Write Operations (POST/PUT/PATCH/DELETE)
| Parameter | Purpose | Example |
|---|---|---|
source | Security area (required) | source=productManagement |
forceDelete | Physical delete (DELETE only) | forceDelete=true |
Next Steps
Now that you've seen the basics, dive deeper:
- Understand the fundamentals → Core Concepts - CRITICAL section, don't skip!
- Master querying → Query Patterns - filtering, sorting, projections, relational queries
- Master writing → Write Patterns - validation, cascades, transactions, outbox
- Secure your API calls → Security - authentication, authorization, permissions
- Avoid mistakes → Best Practices - Anti-Patterns
Ready to build something amazing? Let's go! 🚀