Skip to main content

Quick Start Guide

Get up and running with Q01 Core APIs in just a few minutes.

Prerequisites

Before you begin, ensure you have:

  1. Access to a Q01 environment - CoreService URL (e.g., https://coreservice.q01.io)
  2. JWT token - Authentication token with valid claims
  3. Dimension registered - At least one dimension (e.g., PRD for products) defined in TB_DIM
  4. 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&center_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&center_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&center_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 adds WHERE XPRD02 > 50 to 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&center_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"
    • XPRD01 and XPRD02 have 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 LOWNER and LDATA automatically
  • 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&center_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)

ParameterPurposeExample
sourceSecurity area (COD_MENU)source=productList
center_dettView contextcenter_dett=visualizza (list), dettaglio (detail)
$filterWHERE conditions$filter=XPRD02 gt 50 AND XPRD06 eq 1
$orderORDER BY clause$order=XPRD01 ASC, XPRD02 DESC
$offsetLIMIT offset$offset=100 (skip first 100 rows)
$num_rowsLIMIT count$num_rows=50 (return 50 rows)
$selectField projection$select=XPRD01,XPRD02 (only these fields)
$groupGROUP BY clause$group=XPRD05

For Write Operations (POST/PUT/PATCH/DELETE)

ParameterPurposeExample
sourceSecurity area (required)source=productManagement
forceDeletePhysical delete (DELETE only)forceDelete=true

Next Steps

Now that you've seen the basics, dive deeper:

  1. Understand the fundamentalsCore Concepts - CRITICAL section, don't skip!
  2. Master queryingQuery Patterns - filtering, sorting, projections, relational queries
  3. Master writingWrite Patterns - validation, cascades, transactions, outbox
  4. Secure your API callsSecurity - authentication, authorization, permissions
  5. Avoid mistakesBest Practices - Anti-Patterns

Ready to build something amazing? Let's go! 🚀