API Overview
This document describes the conventions and patterns used throughout the B12 SIS API.
Base URL
Production: https://api.yourschool.edu/api
Development: http://localhost:8080/api
HTTP Methods
Method |
Usage |
|---|---|
GET |
Retrieve a single resource |
POST |
Create resource(s) or list with filters |
PUT |
Update a resource |
DELETE |
Soft-delete a resource |
Request Headers
Required Headers
Header |
Description |
Example |
|---|---|---|
|
JWT Bearer token |
|
|
Current team/campus UUID |
|
|
Request content type |
|
Optional Headers
Header |
Description |
|---|---|
|
Current academic session UUID |
|
Preferred language ( |
Response Format
Success Response
{
"success": true,
"message": "Operation description",
"data": { ... }
}
Error Response
{
"success": false,
"message": "Error description",
"errors": "Detailed error information"
}
List Response
{
"success": true,
"message": "Records retrieved successfully",
"data": {
"list": [ ... ],
"pagination": {
"page": 1,
"limit": 20,
"total": 100
},
"metadata": {
"field_definitions": { ... }
}
}
}
Standard CRUD Endpoints
Every module follows this endpoint pattern:
Endpoint |
Method |
Description |
|---|---|---|
|
POST |
Create a single record |
|
POST |
Create multiple records |
|
POST |
List records with pagination/filtering |
|
GET |
Get a single record by ID |
|
PUT |
Update a record |
|
DELETE |
Soft-delete a record |
|
DELETE |
Bulk soft-delete records |
|
POST |
Export records to Excel |
|
POST |
Import records from Excel |
Relationship Endpoints
Endpoint |
Method |
Description |
|---|---|---|
|
POST |
List related records |
|
PUT |
Add relationships |
|
DELETE |
Remove relationships |
List Request Format
All list endpoints accept a POST request with this body:
{
"page": 1,
"limit": 20,
"search": "search term",
"sort_field": "created_at",
"sort_direction": "desc",
"filter": {
"group": "AND",
"conditions": [
{"field": "status", "operator": "=", "value": "active"}
]
},
"preloads": ["Class", "Program"]
}
Parameters
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
int |
1 |
Page number |
|
int |
20 |
Records per page (max 100) |
|
string |
“” |
Full-text search across searchable fields |
|
string |
“created_at” |
Field to sort by |
|
string |
“desc” |
Sort direction: |
|
object |
null |
Filter conditions (see Filter System) |
|
array |
[] |
Related data to include |
Filter System
The filter system supports complex queries with AND/OR grouping:
Simple Filter
{
"filter": {
"group": "AND",
"conditions": [
{"field": "status", "operator": "=", "value": "active"}
]
}
}
Nested Filter (AND + OR)
{
"filter": {
"group": "AND",
"conditions": [
{"field": "status", "operator": "=", "value": "active"},
{
"group": "OR",
"conditions": [
{"field": "grade_level", "operator": "=", "value": "10"},
{"field": "grade_level", "operator": "=", "value": "11"}
]
}
]
}
}
Filter Operators
Operator |
Description |
Example |
|---|---|---|
|
Equals |
|
|
Not equals |
|
|
Greater than |
|
|
Less than |
|
|
Greater than or equal |
|
|
Less than or equal |
|
|
Contains substring |
|
|
Starts with |
|
|
Ends with |
|
|
Is NULL |
|
|
Is not NULL |
|
|
In array |
|
|
Not in array |
|
Pagination
List responses include pagination metadata:
{
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"total_pages": 8
}
}
Field Definitions
List responses include field definitions for dynamic form generation:
{
"metadata": {
"field_definitions": {
"name": {
"type": "text",
"label": "Name",
"required": true
},
"status": {
"type": "enum",
"label": "Status",
"options": ["active", "inactive"]
},
"class_id": {
"type": "relate",
"label": "Class",
"module": "Class"
}
}
}
}
Field Types
Type |
Description |
|---|---|
|
Single-line text input |
|
Multi-line text input |
|
Rich text editor |
|
Integer number |
|
Decimal number |
|
Boolean checkbox |
|
Date picker |
|
Date and time picker |
|
Single select dropdown |
|
Multi-select dropdown |
|
Foreign key relation (single) |
|
Many-to-many relation |
|
Image upload |
|
File upload |
|
Email input |
|
Phone number input |
|
Address input with autocomplete |
|
Password input |
Error Codes
HTTP Code |
Description |
|---|---|
200 |
Success |
201 |
Created |
400 |
Bad Request - Invalid input |
401 |
Unauthorized - Invalid or expired token |
403 |
Forbidden - Insufficient permissions |
404 |
Not Found - Resource doesn’t exist |
409 |
Conflict - Duplicate entry |
422 |
Unprocessable Entity - Validation failed |
429 |
Too Many Requests - Rate limited |
500 |
Internal Server Error |
Rate Limiting
API requests are rate limited:
Default: 100 requests per minute per user
Bulk operations: 10 requests per minute
When rate limited, you’ll receive:
{
"error": "Rate limit exceeded",
"retry_after": 60
}
Soft Delete
All records use soft delete. Deleted records:
Have
deleted_attimestamp setAre excluded from normal queries
Can be restored by admin
Are permanently purged after retention period
Audit Trail
All create, update, and delete operations are logged with:
User ID who performed the action
Timestamp
Before/after data snapshots
IP address and user agent
Multi-tenancy
Data is isolated by team (organization/campus):
X-Team-IDheader identifies the current teamAll queries automatically filter by team
New records inherit the team ID
Child teams can access parent team data
Preloading Relations
Request related data using the preloads parameter:
{
"preloads": ["Class", "Class.GradeLevel", "Program"]
}
This returns nested related objects:
{
"id": "student-id",
"name": "John Doe",
"class": {
"id": "class-id",
"name": "Class 10A",
"grade_level": {
"id": "grade-id",
"name": "Grade 10"
}
},
"program": {
"id": "program-id",
"name": "Academic Program"
}
}