SchoolCore Developer API opening soon

Build on the
Academic Identity Network

Integrate SchoolCore into your school management platform. Verify students, publish results, generate scratch pins and earn 30% of every pin sale — forever.
Base URL
https://api.schoolcore.ng/.netlify/functions
What is SchoolCore API?
The permanent student identity layer for any school system

SchoolCore is not just a school management platform — it is the identity infrastructure for academic records. Every student on SchoolCore has one permanent ID that follows them across every school they ever attend.

As a developer, you can integrate SchoolCore into your existing school management platform. Your students get SchoolCore IDs. Their records are stored on SchoolCore permanently. Your platform keeps all its users and functionality — you simply add SchoolCore as the identity and records layer underneath.

🪪
Verify Student Identity
Look up any student by their SchoolCore ID. Get name, photo, school history and current enrollment status instantly.
📋
Publish Verified Results
Submit a student's final processed result to SchoolCore. It becomes permanently verifiable by universities, employers and government agencies.
🔑
Generate Revenue Pins
Generate scratch pins for your schools. Students buy pins to unlock results. You earn 30% of every pin sale — lifetime.
🛡
Verify Any Result
Any result with a SchoolCore verification code can be confirmed instantly. Build verification into any platform — universities, employers, government portals.
💰
Earn on Every Pin
30% of every ₦850 pin your schools generate goes to your developer account. Track earnings in real time. Withdraw anytime.
Simple Integration
REST API over HTTPS. JSON requests and responses. Works with any language — JavaScript, PHP, Python, or any HTTP client.
Authentication
API Keys

Every request to the SchoolCore API must include your API key. Your API key is generated when your developer account is approved. Keep it secret — it identifies you on every request and is used to attribute pin revenue to your account.

Where to get your API key: Apply for API access using the button above. Once your application is reviewed and approved by the SchoolCore platform team, your API key is generated and displayed in your developer dashboard
Never expose your API key in client-side code. Your API key should only be used in server-side code (Node.js, PHP, Python backend). If exposed, anyone can make API calls under your account and access your earnings.
Sending Your API Key
Include your API key in the request body of every POST request, or as a query parameter for GET requests.
JavaScript
PHP
Python
JavaScript / Node.js
Copy
// POST request — API key in request body
const response = await fetch('https://api.schoolcore.ng/.netlify/functions/verifyStudent', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    apiKey: 'SC_API_YOUR_KEY_HERE',
    studentId: 'BFA-2026-0042'
  })
});

const data = await response.json();
console.log(data);
PHP
Copy
// POST request — API key in request body
$ch = curl_init('https://api.schoolcore.ng/.netlify/functions/verifyStudent');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
  'apiKey'   => 'SC_API_YOUR_KEY_HERE',
  'studentId' => 'BFA-2026-0042'
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = json_decode(curl_exec($ch), true);
Python
Copy
import requests

response = requests.post(
  'https://api.schoolcore.ng/.netlify/functions/verifyStudent',
  json={
    'apiKey':   'SC_API_YOUR_KEY_HERE',
    'studentId': 'BFA-2026-0042'
  }
)

data = response.json()
Revenue Model
How you earn from SchoolCore

Every result pin your schools generate through the SchoolCore API costs ₦850. SchoolCore splits this revenue 50/50 with you — the developer. Your schools generate pins, students pay for pins to unlock results, and your earnings accumulate in your developer account automatically.

This is lifetime revenue. As long as a school is connected to your platform and generating pins, you earn 30% of every pin sold — indefinitely.

SchoolCore — 70%
You (Developer) — 30%
₦850
Pin Price
₦595
SchoolCore
₦255
You (Developer)
Example: You have 20 schools connected. Each school generates 200 pins per term (3 terms per year). That is 200 × 3 × 20 = 12,000 pins per year × ₦255 = ₦3,060,000 per year in your developer account. Every year. Automatically.
Students
Verify Student
Check that a student ID is valid and exists on SchoolCore. Use this before enrolling a student in your school, to confirm they have a SchoolCore identity.
POST /verifyStudent Verify a student exists
Request Body
ParameterTypeRequiredDescription
apiKeystringRequiredYour SchoolCore developer API key
studentIdstringRequiredThe student's SchoolCore ID (e.g. BFA-2026-0042)
Response
200 Success
Copy
{
  "verified": true,
  "studentId": "BFA-2026-0042",
  "name": "Adaeze Mbachu",
  "gender": "Female",
  "photoUrl": "https://storage.googleapis.com/...",
  "currentSchoolId": "SCH-BRIGHTFUTURE-001",
  "schoolHistory": ["SCH-GREENFIELD-001", "SCH-BRIGHTFUTURE-001"],
  "schoolCount": 2,
  "status": "active"
}
Enroll Student
Link an existing SchoolCore student to a school on your platform. The student's history is preserved — you are adding a new enrollment, not replacing their record.
POST /enrollStudent Link student to a school
Request Body
ParameterTypeRequiredDescription
apiKeystringRequiredYour SchoolCore developer API key
studentIdstringRequiredThe student's SchoolCore ID
schoolIdstringRequiredYour school's ID on SchoolCore (provided in your developer dashboard)
classNamestringRequiredThe class the student is enrolling in (e.g. "SS2")
armNamestringOptionalThe arm or stream within the class (e.g. "Gold")
admissionNumberstringOptionalThe student's admission number at your school
Response
200 Success
{
  "enrolled": true,
  "studentId": "BFA-2026-0042",
  "studentName": "Adaeze Mbachu",
  "schoolId": "SCH-BRIGHTFUTURE-001",
  "className": "SS2",
  "enrolledAt": 1750000000000,
  "message": "Student successfully enrolled"
}
Get Student Records
Retrieve all published academic records for a student across all schools on SchoolCore. This includes results from your own platform and any other school the student attended.
POST /getStudentRecords All academic records for a student
Request Body
ParameterTypeRequiredDescription
apiKeystringRequiredYour API key
studentIdstringRequiredThe student's SchoolCore ID
includeSubjectsbooleanOptionalInclude subject-level breakdown in each result. Default: false
Response
200 Success
{
  "studentId": "BFA-2026-0042",
  "studentName": "Adaeze Mbachu",
  "totalResults": 6,
  "results": [
    {
      "session": "2025/2026",
      "term": "Third Term",
      "schoolName": "Bright Future Academy",
      "className": "SS2",
      "total": 874,
      "average": 87.4,
      "overallGrade": "A",
      "position": 1,
      "verificationCode": "SC-K7M2-P9X1-R4Q8",
      "publishedAt": 1750000000000
    }
  ]
}
Results
Publish Result

Submit a student's final processed result to SchoolCore. This is the most important endpoint. The result must be fully processed by your system before calling this endpoint — SchoolCore only accepts final completed results, not raw scores.

Before calling this endpoint, your system must have already:
① Entered all CA and Exam scores per subject
② Calculated totals per subject
③ Calculated the class average
④ Calculated class positions for all students
⑤ Assigned grades based on your grading system
⑥ Had the principal/admin review and approve
⑦ Shown a preview to the administrator
SchoolCore does not receive raw scores. Only publish the final approved result.
POST /publishResult Publish a final processed result
Request Body
ParameterTypeRequiredDescription
apiKeystringRequiredYour API key
studentIdstringRequiredThe student's SchoolCore ID
schoolIdstringRequiredYour school's SchoolCore ID
sessionstringRequiredAcademic session (e.g. "2025/2026")
termstringRequiredTerm name (e.g. "Third Term", "First Semester")
classNamestringRequiredThe student's class (e.g. "SS2")
subjectsarrayRequiredArray of subject result objects (see structure below)
totalnumberRequiredSum of all subject totals
averagenumberRequiredAverage score across all subjects (1 decimal place)
overallGradestringRequiredOverall grade (e.g. "A", "B", "C")
positionnumberRequiredStudent's position in class
classSizenumberOptionalTotal number of students in the class
teacherRemarkstringOptionalClass teacher's remark
principalRemarkstringOptionalPrincipal's comment
conductRatingstringOptionalConduct rating (e.g. "Excellent", "Good")
nextTermBeginsstringOptionalNext term start date (e.g. "September 15, 2026")
Subject Object Structure
subjects array — each item
{
  "name": "Mathematics",      // Subject name — required
  "caScore": 35,              // Continuous Assessment score
  "examScore": 55,            // Exam score
  "total": 90,                // caScore + examScore — required
  "grade": "A",               // Grade letter — required
  "remark": "Excellent"       // Grade remark
}
Full Request Example
JavaScript
Copy
const result = await fetch('https://api.schoolcore.ng/.netlify/functions/publishResult', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    apiKey:        'SC_API_YOUR_KEY_HERE',
    studentId:     'BFA-2026-0042',
    schoolId:      'SCH-BRIGHTFUTURE-001',
    session:       '2025/2026',
    term:          'Third Term',
    className:     'SS2',
    total:         874,
    average:       87.4,
    overallGrade:  'A',
    position:      1,
    classSize:     42,
    teacherRemark: 'An exceptional student.',
    principalRemark: 'Outstanding performance.',
    conductRating: 'Excellent',
    nextTermBegins: 'September 15, 2026',
    subjects: [
      { name: 'Mathematics', caScore: 35, examScore: 55, total: 90, grade: 'A', remark: 'Excellent' },
      { name: 'English Language', caScore: 32, examScore: 50, total: 82, grade: 'A', remark: 'Excellent' },
      { name: 'Physics', caScore: 30, examScore: 52, total: 82, grade: 'A', remark: 'Excellent' }
    ]
  })
});

const { verificationCode, resultId } = await result.json();
console.log('Published! Code:', verificationCode);
Response
201 Created
{
  "published": true,
  "resultId": "RES_API_ABC123",
  "studentId": "BFA-2026-0042",
  "verificationCode": "SC-K7M2-P9X1-R4Q8",
  "message": "Result published and permanently stored on SchoolCore",
  "publishedAt": 1750000000000
}
The verificationCode in the response should be printed on the student's result slip. Universities, employers and government agencies can verify it at schoolcore.ng/verify
Get Results
Retrieve all published results for a student from SchoolCore. Useful for displaying a student's academic history inside your platform.
POST /getResults Get published results for a student
Request Body
ParameterTypeRequiredDescription
apiKeystringRequiredYour API key
studentIdstringRequiredThe student's SchoolCore ID
sessionstringOptionalFilter by session (e.g. "2025/2026"). Returns all sessions if omitted.
Verify Result by Code
Check the authenticity of a result using its verification code. This is a public endpoint — no API key required. Build this into university admissions portals, employer HR systems or government verification tools.
POST /verifyCode Verify a result by its code — public endpoint
Request Body
ParameterTypeRequiredDescription
verificationCodestringRequiredThe verification code from the result slip (e.g. SC-K7M2-P9X1-R4Q8)
Response
200 Verified
{
  "verified": true,
  "studentName": "Adaeze Mbachu",
  "studentId": "BFA-2026-0042",
  "schoolName": "Bright Future Academy",
  "session": "2025/2026",
  "term": "Third Term",
  "className": "SS2",
  "overallGrade": "A",
  "average": 87.4,
  "issuedAt": 1750000000000,
  "source": "schoolcore",
  "tamperProof": true
}
Unlock Result with Pin
Allow a student in your platform to unlock their result using a SchoolCore scratch pin. Once unlocked, the result is permanently accessible in the student's SchoolCore account with no further pin required.
POST /unlockResult Student checks result with scratch pin
Request Body
ParameterTypeRequiredDescription
apiKeystringRequiredYour API key
studentIdstringRequiredThe student's SchoolCore ID
pinstringRequiredThe scratch pin the student purchased (XXXX-XXXXXX-XXXX)
Response
200 Unlocked
{
  "unlocked": true,
  "studentId": "BFA-2026-0042",
  "session": "2025/2026",
  "term": "Third Term",
  "result": {
    "total": 874,
    "average": 87.4,
    "overallGrade": "A",
    "position": 1,
    "subjects": [ /* full subjects array */ ]
  },
  "verificationCode": "SC-K7M2-P9X1-R4Q8",
  "permanentlyStored": true,
  "message": "Result unlocked and permanently saved to student account"
}
Pins
Generate Result Pins
Generate a batch of result scratch pins for a school connected to your platform. Each pin costs ₦850. SchoolCore earns ₦255, your account is credited ₦255 per pin. Revenue is calculated automatically and tracked in your developer dashboard.
Important: Calling this endpoint confirms you have collected payment from the school for the pins. SchoolCore will credit your account with 30% of the total batch value. Only call this endpoint when you have confirmed payment.
POST /generatePins Generate scratch pins for a school
Request Body
ParameterTypeRequiredDescription
apiKeystringRequiredYour API key
schoolIdstringRequiredThe school's SchoolCore ID
sessionstringRequiredAcademic session these pins are for
termstringRequiredTerm these pins are for
quantitynumberRequiredNumber of pins to generate (max 500 per request)
Response
201 Generated
{
  "generated": true,
  "quantity": 200,
  "totalValue": 20000,
  "yourRevenue": 10000,
  "schoolcoreRevenue": 10000,
  "pins": [
    "ABCD-EFGHJK-LMNP",
    "QRST-UVWXYZ-2345",
    // ... all 200 pins
  ],
  "balanceAfter": 47000,
  "message": "200 pins generated. ₦10,000 credited to your account"
}
Check Pin Status
Check whether a specific pin is valid and unused before presenting it to a student.
POST /checkPin Check if a pin is valid and unused
Request Body
ParameterTypeRequiredDescription
apiKeystringRequiredYour API key
pinstringRequiredThe pin code to check
Response
200
{
  "valid": true,
  "used": false,
  "session": "2025/2026",
  "term": "Third Term",
  "schoolId": "SCH-BRIGHTFUTURE-001"
}
Earnings
Get Earnings
Get the current balance and earnings breakdown for your developer account.
POST /getEarnings Get developer account balance and earnings
Response
200
{
  "totalEarned": 87500,
  "totalPaid": 50000,
  "balance": 37500,
  "totalPinsGenerated": 1750,
  "schoolsConnected": 14,
  "currency": "NGN",
  "lastActivity": 1750000000000
}
Request Withdrawal
Submit a withdrawal request from your earnings balance. SchoolCore processes withdrawals manually within 6–12 hours. Your bank details must be set in your developer dashboard before requesting.
POST /requestWithdrawal Request a payout from earnings
Request Body
ParameterTypeRequiredDescription
apiKeystringRequiredYour API key
amountnumberRequiredAmount to withdraw in Naira (min ₦5,000, max = available balance)
withdrawPinstringRequiredYour 4-digit security PIN set in the developer portal
Response
201 Request Submitted
{
  "submitted": true,
  "requestId": "WD-2026-0042",
  "amount": 20000,
  "status": "pending",
  "expectedBy": "Within 6-12 hours",
  "balancePending": 20000,
  "balanceAvailable": 17500
}
Reference
Error Codes
All errors return a JSON object with an error field describing what went wrong and a code field for programmatic handling.
Error Response Format
{
  "error": "Student not found",
  "code": "STUDENT_NOT_FOUND",
  "status": 404
}
HTTP StatusError CodeDescription
401INVALID_API_KEYThe API key provided does not exist or has been revoked.
403ACCOUNT_SUSPENDEDYour developer account has been suspended. Contact support.
404STUDENT_NOT_FOUNDNo student exists with the provided student ID.
409ALREADY_ENROLLEDThe student is already enrolled as active in this school.
409RESULT_EXISTSA result already exists for this student/session/term combination.
410PIN_ALREADY_USEDThe scratch pin has already been used to unlock a result.
404PIN_NOT_FOUNDThe pin does not exist in the SchoolCore system.
404VERIFICATION_CODE_NOT_FOUNDNo result matches the provided verification code.
400INSUFFICIENT_BALANCEWithdrawal amount exceeds available balance.
400BELOW_MINIMUM_WITHDRAWALWithdrawal amount is below the minimum of ₦5,000.
400INVALID_WITHDRAW_PINThe 4-digit security PIN is incorrect.
400MISSING_REQUIRED_FIELDOne or more required fields are missing from the request body.
429RATE_LIMIT_EXCEEDEDToo many requests. Wait before retrying. See rate limits section.
500SERVER_ERRORInternal server error. Try again after a few seconds. Contact support if persistent.
Rate Limits
SchoolCore API applies rate limits per API key to ensure fair usage and platform stability.
EndpointLimitWindow
/verifyStudent500 requestsPer hour
/enrollStudent200 requestsPer hour
/publishResult100 requestsPer hour
/generatePins50 requestsPer hour
/verifyCodeUnlimitedPublic endpoint
/unlockResult200 requestsPer hour
Rate limit headers are included in every response: X-RateLimit-Remaining (calls left this window) and X-RateLimit-Reset (Unix timestamp when the window resets).
Sandbox Environment
Test your integration without affecting live data. The sandbox uses a separate Firebase environment with pre-seeded test students and schools.
Sandbox URL
https://api-sandbox.schoolcore.ng/.netlify/functions
Test credentials for sandbox:
API Key: SC_API_TEST_KEY_12345
Test Student ID: TEST-2026-0001
Test School ID: SCH-TEST-001
Test Pin: TEST-SANDBOX-XXXX
Getting Started
Quick Start — 5 Minutes to Integration
1
Apply for API Access
Visit the developer portal and submit your application. Tell us about your platform — what it does, how many schools you work with, and how you plan to integrate SchoolCore. We review within 24–48 hours.
2
Get Your API Key
Once approved, your API key and developer account are created. Your key is displayed in your developer dashboard. Store it securely in your server environment variables.
3
Add a "SchoolCore ID" Field to Student Enrollment
Add one optional field to your student registration form. When a student has a SchoolCore ID, they enter it here. Your platform calls /verifyStudent to confirm it's valid before saving.
4
Build Your Result Processing Pipeline
Build or keep your existing result processing — scoring, grading, position calculation. When the principal approves the final result, call /publishResult with the complete processed data. SchoolCore stores it permanently.
5
Generate Pins and Earn
When a school wants to issue result pins, call /generatePins. The pins are created, your account is credited 30% of the batch value. Students use pins to unlock results — in your app or on SchoolCore directly.
Complete Integration Example
JavaScript
PHP
Python
JavaScript / Node.js — Complete Example
Copy
const SC_API = 'https://api.schoolcore.ng/.netlify/functions';
const API_KEY = process.env.SCHOOLCORE_API_KEY;

// Helper function
async function scCall(endpoint, data) {
  const res = await fetch(`${SC_API}/${endpoint}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ apiKey: API_KEY, ...data })
  });
  return res.json();
}

// ─── Step 1: Verify student on enrollment ───
async function enrollStudent(schoolcoreId, className) {
  const check = await scCall('verifyStudent', { studentId: schoolcoreId });
  if (!check.verified) throw new Error('Invalid SchoolCore ID');

  // Save to your own database
  await db.students.create({ schoolcoreId, name: check.name, className });

  // Link on SchoolCore
  await scCall('enrollStudent', {
    studentId: schoolcoreId,
    schoolId: 'SCH-YOUR-SCHOOL-001',
    className
  });
  return check.name;
}

// ─── Step 2: Publish result after approval ───
async function publishResult(processedResult) {
  const { verificationCode } = await scCall('publishResult', {
    studentId:       processedResult.schoolcoreId,
    schoolId:        'SCH-YOUR-SCHOOL-001',
    session:         processedResult.session,
    term:            processedResult.term,
    className:       processedResult.className,
    subjects:        processedResult.subjects,
    total:           processedResult.total,
    average:         processedResult.average,
    overallGrade:    processedResult.grade,
    position:        processedResult.position,
    classSize:       processedResult.classSize,
    teacherRemark:   processedResult.teacherRemark,
    principalRemark: processedResult.principalRemark
  });

  // Print verificationCode on student's result slip
  return verificationCode;
}

// ─── Step 3: Generate pins for a school ───
async function orderPins(schoolId, quantity) {
  const { pins, yourRevenue } = await scCall('generatePins', {
    schoolId,
    session: '2025/2026',
    term: 'Third Term',
    quantity
  });
  console.log(`Generated ${pins.length} pins. Your revenue: ₦${yourRevenue}`);
  return pins; // Array of pin codes to distribute to students
}
PHP — Complete Example
Copy
class SchoolCoreAPI {
  private string $apiKey;
  private string $baseUrl = 'https://api.schoolcore.ng/.netlify/functions';

  public function __construct(string $apiKey) {
    $this->apiKey = $apiKey;
  }

  private function call(string $endpoint, array $data): array {
    $payload = array_merge(['apiKey' => $this->apiKey], $data);
    $ch = curl_init("{$this->baseUrl}/{$endpoint}");
    curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POST => true,
      CURLOPT_POSTFIELDS => json_encode($payload),
      CURLOPT_HTTPHEADER => ['Content-Type: application/json']
    ]);
    return json_decode(curl_exec($ch), true);
  }

  public function verifyStudent(string $studentId): array {
    return $this->call('verifyStudent', ['studentId' => $studentId]);
  }

  public function publishResult(array $resultData): array {
    return $this->call('publishResult', $resultData);
  }

  public function generatePins(string $schoolId, int $qty): array {
    return $this->call('generatePins', [
      'schoolId'  => $schoolId,
      'quantity'  => $qty,
      'session'   => '2025/2026',
      'term'      => 'Third Term'
    ]);
  }
}

// Usage
$sc = new SchoolCoreAPI($_ENV['SCHOOLCORE_API_KEY']);
$student = $sc->verifyStudent('BFA-2026-0042');
if ($student['verified']) {
  echo "Found: {$student['name']}";
}
Python — Complete Example
Copy
import requests
import os

class SchoolCoreAPI:
  BASE_URL = 'https://api.schoolcore.ng/.netlify/functions'

  def __init__(self, api_key=None):
    self.api_key = api_key or os.environ['SCHOOLCORE_API_KEY']

  def _call(self, endpoint, data):
    response = requests.post(
      f'{self.BASE_URL}/{endpoint}',
      json={'apiKey': self.api_key, **data}
    )
    return response.json()

  def verify_student(self, student_id):
    return self._call('verifyStudent', {'studentId': student_id})

  def publish_result(self, result_data):
    return self._call('publishResult', result_data)

  def generate_pins(self, school_id, quantity):
    return self._call('generatePins', {
      'schoolId': school_id,
      'quantity': quantity,
      'session':  '2025/2026',
      'term':     'Third Term'
    })

# Usage
sc = SchoolCoreAPI()
student = sc.verify_student('BFA-2026-0042')
if student['verified']:
  print(f"Found: {student['name']}")
Ready to integrate SchoolCore?
Apply for API access. Build on the academic identity network. Earn 30% of every pin your schools generate — forever.
Apply for API Access → Contact Developer Support
Applications reviewed within 24–48 hours · No setup fee · Free sandbox access