EDM Overview
The Enterprise Data Model (EDM) is the backbone of the cPod platform. It defines every entity your organization works with — people, assets, projects, risks, helpdesk tickets, financial records, and more — in a single, graph-connected schema that all four SDKs speak natively.
Think of it as the "type system for your enterprise." Instead of every application inventing its own User, Account, or Ticket shape, the EDM gives you one canonical definition that every SDK, emulator stub, and production backend agrees on.
Architecture#
┌─────────────────────────────────────────────────────────┐
│ data-model/schemas/ │
│ 84 JSON Schema Draft 2020-12 files │
│ (single source of truth for all shapes) │
└───────────────────────┬─────────────────────────────────┘
│ generates / validates
┌───────────────┼───────────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ TypeScript │ │ Python │ │ Go / .NET │
│ @cpod/sdk │ │ cpod-sdk │ │ SDKs │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└────────────────┼──────────────────────┘
│ REST + JSON
┌───────────┴────────────┐
│ │
▼ ▼
┌─────────────────────┐ ┌──────────────────────────┐
│ Local Emulator │ │ cpod-backend (prod) │
│ :4000 │ │ cyberpod.app │
│ In-memory stubs │ │ MongoDB · ClickHouse │
│ for all 88 entities│ │ FalkorDB · MinIO │
└─────────────────────┘ └──────────────────────────┘
│ │
└───────────┬────────────┘
│
┌───────────▼────────────┐
│ Your Applications │
│ (same SDK call either │
│ way — just change │
│ the base URL) │
└────────────────────────┘
Domain Map#
The EDM is organized into 34 domains across 6 categories. Every domain maps directly to a set of JSON schemas and an SDK namespace.
People & HR#
| Domain | Key Entities | SDK Namespace |
|---|---|---|
| People | Person | sdk.people |
| Groups | Group | sdk.groups |
| Employee Experience | PersonSkill, CalendarEvent, LeaveRequest, MeetingNote | sdk.employee |
| Performance & Development | PerformanceReview, PersonGoal, LearningRecord | sdk.performance |
| HR Lifecycle | JobPosting, Applicant, OnboardingTask, OffboardingTask | sdk.hr |
| Org | Location, Department | sdk.org |
Work & Projects#
| Domain | Key Entities | SDK Namespace |
|---|---|---|
| Projects | Project, Task, Sprint, Feature | sdk.projects |
| Work & Time | TimeEntry, Comment, Capacity | sdk.work |
| OKR | Objective, KeyResult | sdk.okr |
Customer & Revenue#
| Domain | Key Entities | SDK Namespace |
|---|---|---|
| Customer | Account, Contact, Deal, Activity | sdk.customer |
| RFP | RfpRecord, RfpQuestion, RfpResponse | sdk.rfp |
| Finance | Invoice, PurchaseOrder, Expense, Budget, BudgetLine | sdk.finance |
IT & Security#
| Domain | Key Entities | SDK Namespace |
|---|---|---|
| Technology | TechnologyAsset, AccessEntitlement | sdk.technology |
| Assets | PhysicalAsset, CloudResource | sdk.assets |
| Licenses | SoftwareLicense, LicenseAssignment | sdk.licenses |
| Technology Investment | TechPortfolioItem, CostCenter | sdk.investments |
| GRC | GrcFramework, GrcControl, GrcEvidence, GrcIncident, GrcRisk | sdk.grc |
| SOC | SocAlert, SocInvestigation, SocPlaybook | sdk.soc |
| Risk & Compliance | Vulnerability, ComplianceControl, RiskItem | sdk.risk |
Operations#
| Domain | Key Entities | SDK Namespace |
|---|---|---|
| Helpdesk | Ticket, SlaPolicy | sdk.helpdesk |
| Approvals | ApprovalRequest, ApprovalStep | sdk.approvals |
| Notifications | Notification, Announcement | sdk.notifications |
| Catalog | Product, ProductCategory | sdk.catalog |
| Procurement | Supplier | sdk.procurement |
Platform#
| Domain | Key Entities | SDK Namespace |
|---|---|---|
| Knowledge | Document, Chunk, KnowledgeEntity | sdk.knowledge |
| Learning | Cohort, Assessment | sdk.learning |
| Integration | Application, Connector, ApiKey, Webhook | sdk.integration |
| Storage | StorageObject, StorageRecord | sdk.storage |
| Telemetry | AuditEvent, AppEvent, Trace | sdk.telemetry |
| Contracts | Vendor, Contract, ContractObligation | sdk.contracts |
How It All Connects#
The EDM is graph-connected — every entity carries typed foreign keys (UUIDs) that reference canonical owners. Some key traversal paths:
Person ──► TimeEntry ──► Project ──► Customer (Account)
│ │
│ └──► Task (projects domain)
│
├──► LeaveRequest (employee domain)
├──► PerformanceReview (performance domain)
├──► PersonSkill (employee domain)
└──► LearningRecord (performance domain)
TechnologyAsset ──► AccessEntitlement ──► Person
SoftwareLicense ──► LicenseAssignment ──► Person
Ticket ──► SlaPolicy
──► Person (assignee)
──► Account (customer)
ApprovalRequest ──► ApprovalStep[] ──► Person (approver)
──► (any entity — polymorphic subject)
Deal ──► RfpRecord ──► RfpQuestion[] ──► RfpResponse[]
──► Project (auto-created on close-won)
Budget ──► BudgetLine[] ──► CostCenter
Invoice ──► PurchaseOrder ──► Supplier
Cross-domain references are always by UUID — never by name match. The Relationship entity (common domain) provides a generic edge type for relationships not expressed by inline foreign keys.
Emulator vs. Production Backend#
| Concern | Local Emulator (:4000) | cpod-backend (production) |
|---|---|---|
| Purpose | Fast local development, no credentials needed | Live tenant data, full auth/authz |
| Data store | In-memory (resets on restart) | MongoDB, ClickHouse, FalkorDB, MinIO |
| Auth | Accepts any Bearer token | OIDC / SCIM via core-sdk |
| Coverage | All 88 entities stubbed | Full implementation |
| Speed | Instant startup | Requires full stack |
Switch between them by changing a single environment variable — the SDK call is identical:
// Emulator
const sdk = new CpodClient({ baseUrl: 'http://localhost:4000', token: 'dev' })
// Production
const sdk = new CpodClient({ baseUrl: 'https://api.cyberpod.app', token: process.env.CPOD_TOKEN })# Emulator
sdk = CpodClient(base_url="http://localhost:4000", token="dev")
# Production
sdk = CpodClient(base_url="https://api.cyberpod.app", token=os.environ["CPOD_TOKEN"])// Emulator
sdk := cpod.New(cpod.WithBaseURL("http://localhost:4000"), cpod.WithToken("dev"))
// Production
sdk := cpod.New(cpod.WithBaseURL("https://api.cyberpod.app"), cpod.WithToken(os.Getenv("CPOD_TOKEN")))// Emulator
var sdk = new CpodClient(new CpodClientOptions { BaseUrl = "http://localhost:4000", Token = "dev" });
// Production
var sdk = new CpodClient(new CpodClientOptions { BaseUrl = "https://api.cyberpod.app", Token = Environment.GetEnvironmentVariable("CPOD_TOKEN") });Getting Started#
Step 1 — Install the SDK
TypeScript
npm install @cpod/sdkPython
pip install cpod-sdkGo
go get github.com/ZySec-AI/cpod-sdk/sdks/go.NET
dotnet add package Cpod.SDKStep 2 — Start the local emulator
cd emulator && npm start
# Emulator running at http://localhost:4000
# All 88 entities available with seeded mock dataPython/Go/.NET install via the commands above; the emulator is a portal toggle.
Step 3 — Make your first call
import { CpodClient } from '@cpod/sdk'
const sdk = new CpodClient({ baseUrl: 'http://localhost:4000', token: 'dev' })
// List all people
const { data: people } = await sdk.people.persons.list()
console.log(people)
// Create a ticket
const ticket = await sdk.helpdesk.createTicket({
title: 'Cannot access VPN',
priority: 'high',
requesterId: people[0].id,
})from cpod import CpodClient
sdk = CpodClient(base_url="http://localhost:4000", token="dev")
# List all people
people = await sdk.people.list()
print(people.data)
# Create a ticket
ticket = await sdk.helpdesk.create_ticket(
title="Cannot access VPN",
priority="high",
requester_id=people.data[0].id,
)client := cpod.New(cpod.WithBaseURL("http://localhost:4000"), cpod.WithToken("dev"))
// List all people
people, _ := client.People.List(ctx, nil)
fmt.Println(people.Data)
// Create a ticket
ticket, _ := client.Helpdesk.CreateTicket(ctx, &cpod.CreateTicketInput{
Title: "Cannot access VPN",
Priority: "high",
RequesterID: people.Data[0].ID,
})var sdk = new CpodClient(new CpodClientOptions { BaseUrl = "http://localhost:4000", Token = "dev" });
// List all people
var people = await sdk.People.ListAsync();
Console.WriteLine(people.Data.Count);
// Create a ticket
var ticket = await sdk.Helpdesk.CreateTicketAsync(new CreateTicketInput
{
Title = "Cannot access VPN",
Priority = "high",
RequesterId = people.Data[0].Id,
});For full SDK reference see SDK Reference, and for authentication against the production backend see Authentication.