This document defines the Phosra Child Safety Spec (PCSS), an open technical framework for technology platforms that serve minors. Platforms SHOULD implement this spec to align with emerging child safety regulations and industry best practices.
PCSS establishes a universal policy framework spanning 45 safety categories across 12 domains: Content, Time, Purchase, Social, Web, Privacy, Monitoring, Algorithmic Safety, Notifications, Advertising & Data, and Access Control. Platforms SHALL expose compliance endpoints that accept policy enforcement requests from the Phosra Enforcement Engine.
This spec is published by Phosra and designed to align with current and emerging child safety regulations. Platforms adopting this spec position themselves ahead of regulatory requirements.
45
Policy Categories
5
Rating Systems
15
Regulated Platforms
3
Compliance Levels
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
All regulated platforms MUST authenticate using JWT bearer tokens. The authentication system implements refresh token rotation with SHA-256 hashing for security.
Platforms MUST include a valid JWT in the Authorization header. Tokens expire after 15 minutes.
Authorization: Bearer <access_token>
Platforms MUST implement token rotation. Each refresh request returns a new token pair and revokes the previous refresh token. Platforms MUST NOT reuse expired refresh tokens.
/auth/registerCreate a new user account. Returns the user object and a token pair (access + refresh). The access token expires in 15 minutes; use the refresh endpoint to obtain a new one.
emailValid email address
passwordMinimum 8 characters
nameDisplay name
userCreated user
tokensJWT token pair
curl -X POST https://api.phosra.com/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "parent@example.com",
"password": "securepass123",
"name": "Jane Parent"
}'{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "parent@example.com",
"name": "Jane Parent",
"created_at": "2025-01-15T10:30:00Z"
},
"tokens": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "dGhpcyBpcyBhIHJlZnJl...",
"expires_at": "2025-01-15T10:45:00Z"
}
}/auth/loginAuthenticate with email and password. Returns a user object and token pair. Previous refresh tokens remain valid until explicitly revoked via logout.
emailRegistered email address
passwordAccount password
userAuthenticated user
tokensJWT token pair
curl -X POST https://api.phosra.com/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "parent@example.com",
"password": "securepass123"
}'{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "parent@example.com",
"name": "Jane Parent",
"created_at": "2025-01-15T10:30:00Z"
},
"tokens": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "dGhpcyBpcyBhIHJlZnJl...",
"expires_at": "2025-01-15T10:45:00Z"
}
}/auth/refreshExchange a valid refresh token for a new token pair. The old refresh token is revoked (rotation). No Authorization header required.
refresh_tokenValid refresh token from login or previous refresh
access_tokenJWT access token (15 min TTL)
refresh_tokenRefresh token for obtaining new access tokens
expires_atAccess token expiration timestamp
curl -X POST https://api.phosra.com/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "dGhpcyBpcyBhIHJlZnJl..."
}'{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "bmV3IHJlZnJlc2ggdG9r...",
"expires_at": "2025-01-15T11:00:00Z"
}/auth/logoutRevoke all refresh tokens for the current user. The access token remains valid until its TTL expires (15 min). Requires a valid access token.
curl -X POST https://api.phosra.com/api/v1/auth/logout \
-H "Authorization: Bearer <access_token>"// 204 No Content/auth/meReturn the authenticated user's profile. Requires a valid access token.
idUnique user identifier
emailUser email address
nameUser display name
created_atAccount creation timestamp
curl https://api.phosra.com/api/v1/auth/me \
-H "Authorization: Bearer <access_token>"{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "parent@example.com",
"name": "Jane Parent",
"created_at": "2025-01-15T10:30:00Z"
}The family data model SHALL support multiple guardians per family unit with role-based access control. Child profiles MUST include birth date for age-based policy computation.
Full administrative control. MAY delete the family unit.
MAY manage children, policies, and compliance links.
Read-only access. MUST NOT modify policies or compliance links.
/familiesReturn all families the authenticated user belongs to, including families where the user is owner, parent, or guardian.
[]Array of family objects
curl https://api.phosra.com/api/v1/families \
-H "Authorization: Bearer <access_token>"[
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Smith Family",
"created_at": "2025-01-10T08:00:00Z"
}
]/familiesCreate a new family group. The authenticated user becomes the owner automatically. A user can belong to multiple families.
nameFamily display name
idFamily identifier
nameFamily display name
created_atFamily creation timestamp
curl -X POST https://api.phosra.com/api/v1/families \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "name": "Smith Family" }'{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Smith Family",
"created_at": "2025-01-10T08:00:00Z"
}/families/{familyID}Retrieve details of a specific family. Caller must be a member of the family.
idFamily identifier
nameFamily display name
created_atFamily creation timestamp
curl https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer <access_token>"{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Smith Family",
"created_at": "2025-01-10T08:00:00Z"
}/families/{familyID}Update family properties. Only the family owner can perform updates.
nameNew family display name
curl -X PUT https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "name": "Smith-Jones Family" }'// 200 OK/families/{familyID}Permanently delete a family and all associated children, policies, and connections. Only the family owner can delete. This action cannot be undone.
curl -X DELETE https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer <access_token>"// 204 No Content/families/{familyID}/childrenList all children belonging to a family. Caller must be a family member.
[]Array of child objects
curl https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890/children \
-H "Authorization: Bearer <access_token>"[
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Alex",
"birth_date": "2015-06-20",
"avatar_url": null,
"created_at": "2025-01-10T08:15:00Z"
}
]/families/{familyID}/childrenAdd a child to a family. The birth date is used for age-based policy generation and content rating calculations.
nameChild display name
birth_dateDate of birth in YYYY-MM-DD format
idChild identifier
family_idParent family identifier
nameChild display name
birth_dateDate of birth (YYYY-MM-DD)
avatar_urlOptional avatar URL
created_atRecord creation timestamp
curl -X POST https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890/children \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Alex",
"birth_date": "2015-06-20"
}'{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Alex",
"birth_date": "2015-06-20",
"avatar_url": null,
"created_at": "2025-01-10T08:15:00Z"
}/children/{childID}Retrieve details of a specific child. Caller must be a member of the child's family.
idChild identifier
family_idParent family identifier
nameChild display name
birth_dateDate of birth (YYYY-MM-DD)
avatar_urlOptional avatar URL
created_atRecord creation timestamp
curl https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901 \
-H "Authorization: Bearer <access_token>"{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Alex",
"birth_date": "2015-06-20",
"avatar_url": null,
"created_at": "2025-01-10T08:15:00Z"
}/children/{childID}Update a child's profile. Only family members with parent or owner role can update.
nameUpdated display name
birth_dateUpdated date of birth
curl -X PUT https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901 \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "name": "Alexander" }'// 200 OK/children/{childID}Remove a child and all associated policies and sync history. Only the family owner can delete children.
curl -X DELETE https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901 \
-H "Authorization: Bearer <access_token>"// 204 No Content/children/{childID}/age-ratingsReturn age-appropriate content ratings for a child across all supported rating systems (MPAA, TV Parental Guidelines, ESRB, PEGI, Common Sense Media). Calculated from the child's birth date.
ageChild's current age in years
ratingsMap of rating system ID to maximum allowed rating
curl https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/age-ratings \
-H "Authorization: Bearer <access_token>"{
"age": 10,
"ratings": {
"mpaa": {
"code": "PG",
"name": "Parental Guidance Suggested",
"min_age": 8
},
"tv": {
"code": "TV-PG",
"name": "Parental Guidance Suggested",
"min_age": 8
},
"esrb": {
"code": "E10+",
"name": "Everyone 10+",
"min_age": 10
},
"pegi": {
"code": "PEGI 12",
"name": "PEGI 12",
"min_age": 12
},
"csm": {
"code": "10+",
"name": "Age 10+",
"min_age": 10
}
}
}Families support multi-guardian access with role-based permissions. Members MAY be added to share access to children, policies, and enforcement controls. The family data model supports co-parenting, caregiver delegation, and institutional use cases.
Full administrative control. MAY add/remove members, manage all policies, and delete the family.
MAY manage children, modify policies, trigger enforcement, and view reports.
Read-only access. MAY view policies and reports. MUST NOT modify rules.
/families/{familyID}/membersList all members of a family with their roles and permissions. Roles include owner (full admin), parent (manage children and policies), and guardian (read-only access).
[]Array of family member objects
curl https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890/members \
-H "Authorization: Bearer <access_token>"[
{
"id": "m1a2b3c4-d5e6-7890-abcd-ef1234567890",
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"role": "owner",
"email": "parent@example.com",
"name": "Jane Parent",
"joined_at": "2025-01-10T08:00:00Z"
}
]/families/{familyID}/membersInvite a user to join a family. The invited user must have an existing Phosra account. Only the family owner can add new members. Supported roles: parent, guardian.
emailEmail address of the user to invite
roleOne of: parent, guardian
idMember record identifier
user_idUser account identifier
family_idFamily identifier
roleOne of: owner, parent, guardian
emailMember email address
nameMember display name
joined_atWhen the member joined the family
curl -X POST https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890/members \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"email": "coparent@example.com",
"role": "parent"
}'{
"id": "m2b3c4d5-e6f7-8901-bcde-f12345678901",
"user_id": "660e8400-e29b-41d4-a716-446655440001",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"role": "parent",
"email": "coparent@example.com",
"name": "John Co-Parent",
"joined_at": "2025-01-12T14:30:00Z"
}/families/{familyID}/members/{memberID}Remove a member from a family. Only the family owner can remove members. The owner cannot remove themselves — use Delete Family instead. Removed members immediately lose access to all family data.
curl -X DELETE https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890/members/m2b3c4d5-e6f7-8901-bcde-f12345678901 \
-H "Authorization: Bearer <access_token>"// 204 No ContentSafety policies define protection rules for each child. Each policy contains rules across 45 categories spanning 12 domains. Platforms MUST implement enforcement for all categories they claim capability in. Rules are stored as JSONB with category-specific schemas.
Policies transition through states: draft →active →paused. Only active policies SHALL be enforced on platforms.
/children/{childID}/policiesList all safety policies for a child, ordered by priority. Each child can have multiple policies (e.g. weekday vs weekend).
[]Array of policy objects
curl https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/policies \
-H "Authorization: Bearer <access_token>"[
{
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "School Days",
"status": "active",
"priority": 1,
"created_at": "2025-01-10T09:00:00Z"
}
]/children/{childID}/policiesCreate a new safety policy for a child. The policy starts in draft status. Add rules, then activate it to begin enforcement.
namePolicy display name (e.g. "School Days", "Weekend")
idPolicy identifier
child_idAssociated child identifier
namePolicy display name
statusOne of: active, paused, draft
priorityEvaluation priority (lower = higher precedence)
created_atPolicy creation timestamp
curl -X POST https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/policies \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "name": "School Days" }'{
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "School Days",
"status": "draft",
"priority": 1,
"created_at": "2025-01-10T09:00:00Z"
}/policies/{policyID}/activateTransition a policy from draft or paused to active. An active policy's rules will be enforced on the next sync. Only one policy per child can be active at a time; activating one pauses others.
curl -X POST https://api.phosra.com/api/v1/policies/c3d4e5f6-a7b8-9012-cdef-123456789012/activate \
-H "Authorization: Bearer <access_token>"// 200 OK/policies/{policyID}/pausePause an active policy. Rules remain configured but will not be enforced until reactivated. Pausing does not remove already-pushed rules from providers.
curl -X POST https://api.phosra.com/api/v1/policies/c3d4e5f6-a7b8-9012-cdef-123456789012/pause \
-H "Authorization: Bearer <access_token>"// 200 OK/policies/{policyID}/generate-from-ageAutomatically generate a full set of policy rules based on the child's current age. Uses the built-in age-to-setting mapping across all 45 rule categories. Existing rules on the policy are replaced.
[]Generated rules
curl -X POST https://api.phosra.com/api/v1/policies/c3d4e5f6-a7b8-9012-cdef-123456789012/generate-from-age \
-H "Authorization: Bearer <access_token>"[
{
"id": "d4e5f6a7-b8c9-0123-def0-123456789abc",
"policy_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"category": "web_filtering",
"enabled": true,
"config": {
"block_categories": [
"adult",
"gambling",
"violence"
]
},
"created_at": "2025-01-10T09:05:00Z"
},
{
"id": "e5f6a7b8-c9d0-1234-ef01-23456789abcd",
"policy_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"category": "screen_time",
"enabled": true,
"config": {
"daily_limit_minutes": 120,
"bedtime": "21:00"
},
"created_at": "2025-01-10T09:05:00Z"
}
]/policies/{policyID}/rulesList all rules in a policy. Rules are returned in category order across all 45 supported categories.
[]Array of rule objects
curl https://api.phosra.com/api/v1/policies/c3d4e5f6-a7b8-9012-cdef-123456789012/rules \
-H "Authorization: Bearer <access_token>"[
{
"id": "d4e5f6a7-b8c9-0123-def0-123456789abc",
"policy_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"category": "web_filtering",
"enabled": true,
"config": {
"block_categories": [
"adult",
"gambling",
"violence"
]
},
"created_at": "2025-01-10T09:05:00Z"
}
]/policies/{policyID}/rulesAdd a rule to a policy. The category must be one of the 45 supported categories. Config schema varies per category (see Category Reference).
categoryRule category (e.g. web_filtering, screen_time, app_restrictions)
enabledWhether the rule is active (default: true)
configCategory-specific configuration object
idRule identifier
policy_idParent policy identifier
categoryOne of 45 rule categories (e.g. web_filtering, screen_time)
enabledWhether this rule is active
configCategory-specific configuration (JSONB)
created_atRule creation timestamp
curl -X POST https://api.phosra.com/api/v1/policies/c3d4e5f6-a7b8-9012-cdef-123456789012/rules \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"category": "screen_time",
"enabled": true,
"config": {
"daily_limit_minutes": 120,
"bedtime": "21:00",
"wake_time": "07:00"
}
}'{
"id": "f6a7b8c9-d0e1-2345-f012-3456789abcde",
"policy_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"category": "screen_time",
"enabled": true,
"config": {
"daily_limit_minutes": 120,
"bedtime": "21:00",
"wake_time": "07:00"
},
"created_at": "2025-01-10T09:10:00Z"
}/rules/{ruleID}Update an existing policy rule's configuration or enabled status. The category cannot be changed — delete and recreate if a different category is needed.
enabledWhether the rule is active
configUpdated category-specific configuration
idRule identifier
policy_idParent policy identifier
categoryOne of 45 rule categories (e.g. web_filtering, screen_time)
enabledWhether this rule is active
configCategory-specific configuration (JSONB)
created_atRule creation timestamp
curl -X PUT https://api.phosra.com/api/v1/rules/d4e5f6a7-b8c9-0123-def0-123456789abc \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"config": { "daily_limit_minutes": 90, "bedtime": "20:00" }
}'{
"id": "d4e5f6a7-b8c9-0123-def0-123456789abc",
"policy_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"category": "time_daily_limit",
"enabled": true,
"config": {
"daily_limit_minutes": 90,
"bedtime": "20:00"
},
"created_at": "2025-01-10T09:05:00Z"
}/rules/{ruleID}Remove a rule from a policy. The rule is permanently deleted. To temporarily disable a rule, set enabled to false instead.
curl -X DELETE https://api.phosra.com/api/v1/rules/d4e5f6a7-b8c9-0123-def0-123456789abc \
-H "Authorization: Bearer <access_token>"// 204 No Content/policies/{policyID}/rules/bulkCreate or update multiple rules in a single request. For each entry, if a rule with the given category already exists on the policy it is updated; otherwise a new rule is created. This is the recommended way to configure multiple categories at once.
rulesArray of rule objects with category, enabled, and config
createdNumber of new rules created
updatedNumber of existing rules updated
curl -X PUT https://api.phosra.com/api/v1/policies/c3d4e5f6-a7b8-9012-cdef-123456789012/rules/bulk \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{ "category": "web_filter_level", "config": { "level": "strict" } },
{ "category": "time_daily_limit", "config": { "daily_limit_minutes": 120 } },
{ "category": "content_rating", "config": { "max_mpaa": "PG", "max_esrb": "E" } }
]
}'{
"created": 1,
"updated": 2
}PCSS v1.0 defines 45 policy categories across 12 domains. The 19 new legislation-driven categories are backed by specific child safety laws and MUST be enforced by all compliant platforms.
algo_feed_controlControl algorithmic feed recommendations; enforce chronological mode for minors
addictive_design_controlDisable infinite scroll, autoplay, streaks, like counts, and daily rewards
notification_curfewSuppress notifications during defined quiet hours (e.g., 20:00-07:00)
usage_timer_notificationPeriodic usage reminders at configurable intervals (15/30/45/60 min)
targeted_ad_blockBlock all targeted/behavioral advertising for minors
dm_restrictionRestrict direct messaging: none, contacts_only, or everyone
age_gateRequire age verification before platform access
data_deletion_requestEnable one-click data deletion request for child accounts
geolocation_opt_inDefault geolocation sharing to off; require explicit opt-in
csam_reportingEnsure CSAM detection/reporting mechanisms are enabled on platforms
library_filter_complianceCIPA E-rate filtering for schools and libraries
ai_minor_interactionRestrict AI systems that exploit or manipulate children
social_media_min_ageEnforce hard minimum age ban for social media access
image_rights_minorProtect minors' image rights; restrict unauthorized sharing
parental_consent_gateRequire verifiable parental consent before account creation or data collection
parental_event_notificationNotify parents when minors create accounts or encounter flagged content
screen_time_reportGenerate and deliver screen time usage reports to parents
commercial_data_banBan commercial sale, sharing, or profiling of minor data
algorithmic_auditRequire algorithmic transparency reports and independent audits
See the complete API reference below for full JSON schemas, field constraints, age-based defaults, platform support, and code examples for all 45 categories.
All technology platforms serving minors SHALL register with the Phosra platform registry. Each platform declares its category, compliance level, supported capabilities, and authentication mechanism.
/providersList all available providers with their integration tier, supported capabilities, and authentication method. This endpoint is public and does not require authentication.
[]Array of provider objects
curl https://api.phosra.com/api/v1/providers[
{
"id": "nextdns",
"name": "NextDNS",
"category": "dns",
"tier": "live",
"description": "DNS-level web filtering and analytics",
"auth_type": "api_key",
"capabilities": [
"web_filtering",
"safe_search",
"youtube_restricted",
"block_bypass_methods"
]
},
{
"id": "cleanbrowing",
"name": "CleanBrowsing",
"category": "dns",
"tier": "live",
"description": "Family-friendly DNS filtering",
"auth_type": "api_key",
"capabilities": [
"web_filtering",
"safe_search"
]
}
]/platforms/{platformID}Get detailed information about a specific provider including capabilities, authentication method, and integration tier. This endpoint is public.
idProvider slug (e.g. nextdns, cleanbrowing)
nameProvider display name
categoryOne of: dns, streaming, gaming, device, browser
tierIntegration level: live, partial, or stub
descriptionHuman-readable provider description
auth_typeOne of: api_key, oauth2, manual
capabilitiesSupported rule categories for this provider
curl https://api.phosra.com/api/v1/platforms/nextdns{
"id": "nextdns",
"name": "NextDNS",
"category": "dns",
"tier": "live",
"description": "DNS-level web filtering and analytics",
"auth_type": "api_key",
"capabilities": [
"web_filtering",
"safe_search",
"youtube_restricted",
"block_bypass_methods"
]
}/platforms/by-categoryFilter platforms by category (dns, streaming, gaming, device, browser). Useful for discovering which platforms serve a particular need. Query parameter: ?category=dns
categoryPlatform category filter (query parameter)
curl "https://api.phosra.com/api/v1/platforms/by-category?category=dns"[
{
"id": "nextdns",
"name": "NextDNS",
"tier": "live"
},
{
"id": "cleanbrowsing",
"name": "CleanBrowsing",
"tier": "live"
}
]/platforms/by-capabilityFilter platforms by supported rule category. Returns all platforms that can enforce a specific rule type. Query parameter: ?capability=web_filter_level
capabilityRule category to filter by (query parameter)
curl "https://api.phosra.com/api/v1/platforms/by-capability?capability=web_filter_level"[
{
"id": "nextdns",
"name": "NextDNS",
"tier": "live",
"support": "full"
},
{
"id": "cleanbrowsing",
"name": "CleanBrowsing",
"tier": "live",
"support": "partial"
}
]Full API enforcement. Real-time policy push.
Limited API. Partial enforcement capability.
No API. Manual compliance instructions provided.
Platforms MUST establish a compliance link to prove they can receive enforcement instructions. Credentials are encrypted with AES-256-GCM at rest. Platforms SHALL support periodic re-verification.
Credential Security: All platform credentials MUST be encrypted using AES-256-GCM before storage. Plaintext credentials MUST NOT be logged or stored unencrypted at any point in the pipeline.
/connectionsEstablish a connection between a family and a provider. Credentials are encrypted with AES-256-GCM before storage. The connection is verified immediately upon creation.
family_idFamily to connect the provider to
provider_idProvider slug (e.g. nextdns, android)
credentialsProvider-specific credentials (API key, OAuth token, etc.)
idConnection identifier
family_idOwning family identifier
provider_idConnected provider slug
statusOne of: connected, disconnected, error
last_sync_atLast successful sync timestamp
last_sync_statusStatus of last sync attempt
connected_atInitial connection timestamp
curl -X POST https://api.phosra.com/api/v1/connections \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"provider_id": "nextdns",
"credentials": "your-nextdns-api-key"
}'{
"id": "e5f6a7b8-c9d0-1234-ef01-23456789abcd",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"provider_id": "nextdns",
"status": "connected",
"last_sync_at": null,
"last_sync_status": null,
"connected_at": "2025-01-10T10:00:00Z"
}Compliance links connect a child to a specific platform for enforcement. Each link stores encrypted platform credentials (AES-256-GCM) and tracks verification status, supported capabilities, and enforcement history. Platforms MUST be re-verified when credentials are rotated.
Lifecycle: Create link → Verify credentials → Enforce rules → Monitor health → Re-verify on rotation
/complianceCreate a compliance link between a child and a platform. Credentials are encrypted with AES-256-GCM before storage. The platform is contacted immediately to verify that the credentials are valid.
platformPlatform identifier (e.g. nextdns, android, apple_mdm)
credentialsPlatform-specific credential object
child_idChild to link the platform to
idCompliance link identifier
platformPlatform identifier
child_idLinked child identifier
statusOne of: verified, auth_failed, manual, pending
capabilitiesRule categories this platform can enforce
verified_atLast successful verification timestamp
last_sync_atLast enforcement sync timestamp
curl -X POST https://api.phosra.com/api/v1/compliance \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"platform": "nextdns",
"credentials": { "api_key": "ndns_abc...", "profile_id": "abc123" },
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
}'{
"id": "cl_abc123",
"platform": "nextdns",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"status": "verified",
"capabilities": [
"web_filter_level",
"web_safesearch",
"web_category_block"
],
"verified_at": "2025-01-10T10:00:00Z"
}/families/{familyID}/complianceList all compliance links (platform connections) across all children in a family. Shows verification status, capabilities, and last sync time for each link.
[]Array of compliance link objects
curl https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890/compliance \
-H "Authorization: Bearer <access_token>"[
{
"id": "cl_abc123",
"platform": "nextdns",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"status": "verified",
"capabilities": [
"web_filter_level",
"web_safesearch"
],
"verified_at": "2025-01-10T10:00:00Z",
"last_sync_at": "2025-01-12T18:00:00Z"
}
]/compliance/{linkID}/verifyRe-verify a compliance link with new or existing credentials. Use this when platform credentials have been rotated or when a previous verification has expired. Credentials are re-encrypted on update.
credentialsUpdated platform credentials (optional — re-verifies existing if omitted)
curl -X POST https://api.phosra.com/api/v1/compliance/cl_abc123/verify \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"credentials": { "api_key": "ndns_NEW_key...", "profile_id": "abc123" }
}'{
"id": "cl_abc123",
"platform": "nextdns",
"status": "verified",
"previous_status": "auth_failed",
"verified_at": "2025-01-15T09:15:00Z"
}/compliance/{linkID}Permanently remove a compliance link. Encrypted credentials are deleted. Future enforcement will skip this platform. Active rules on the platform are not automatically removed — run enforcement with the platform disconnected to clear them.
curl -X DELETE https://api.phosra.com/api/v1/compliance/cl_abc123 \
-H "Authorization: Bearer <access_token>"// 204 No Content/compliance/{linkID}/enforceTrigger enforcement on a single compliance link. Unlike child-wide enforcement which pushes to all linked platforms, this targets a specific platform connection. Useful for re-pushing rules after re-verification.
curl -X POST https://api.phosra.com/api/v1/compliance/cl_abc123/enforce \
-H "Authorization: Bearer <access_token>"{
"job_id": "f6a7b8c9-d0e1-2345-f012-3456789abcde",
"platform": "nextdns",
"status": "pending",
"created_at": "2025-01-15T09:20:00Z"
}The Quick Setup API provides a single-call onboarding flow that creates a family (if needed), registers a child, generates all 45 age-appropriate policy rules, and activates the policy. This endpoint SHOULD be the primary entry point for parent-facing applications.
POST /setup/quick
{
"family_id": "uuid (optional — omit to create new family)",
"family_name": "string (optional — used when creating new family)",
"child_name": "string (required)",
"birth_date": "YYYY-MM-DD (required)",
"strictness": "recommended | strict | relaxed"
}{
"family": { "id": "...", "name": "..." },
"child": { "id": "...", "name": "Emma", "birth_date": "2019-03-15" },
"policy": { "id": "...", "status": "active" },
"rules": [ ... ], // ~20-25 enabled rules
"age_group": "child",
"max_ratings": { "mpaa": "PG", "tv": "TV-Y7", "esrb": "E" },
"rule_summary": {
"screen_time_minutes": 90,
"bedtime_hour": 20,
"web_filter_level": "strict",
"content_rating": "PG",
"total_rules_enabled": 22
}
}Strictness levels: recommended uses age-appropriate defaults. strict reduces screen time by 30% and tightens timer intervals.relaxed increases screen time by 30% and extends timer intervals.
/setup/quickSingle-call onboarding that creates a family (if needed), registers a child, generates all 45 age-appropriate policy rules, and activates the policy. This is the recommended entry point for parent-facing applications.
family_idExisting family ID (optional — omit to create new family)
family_nameFamily name (used when creating new family)
child_nameChild display name
birth_dateChild date of birth (YYYY-MM-DD)
strictnessOne of: recommended (default), strict, relaxed
familyCreated or existing family
childCreated child profile with computed age
policyActive policy with rule count
rulesGenerated policy rules (~20-25 enabled)
age_groupComputed age group (toddler, child, tween, teen)
max_ratingsAge-appropriate content ratings across 5 systems
curl -X POST https://api.phosra.com/api/v1/setup/quick \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"child_name": "Emma",
"birth_date": "2019-03-15",
"strictness": "recommended"
}'{
"family": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "My Family"
},
"child": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "Emma",
"birth_date": "2019-03-15",
"age": 6
},
"policy": {
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"status": "active",
"rules_count": 22
},
"age_group": "child",
"max_ratings": {
"mpaa": "PG",
"tv": "TV-Y7",
"esrb": "E",
"pegi": "7",
"csm": "6+"
}
}The Phosra Enforcement Engine fans out policy rules to all verified platforms concurrently. Platforms MUST accept enforcement requests and report per-rule results. Enforcement jobs track status as: pending →running →completed / partial / failed.
Enforcement flow: Trigger enforcement → Job created → Fan out to platforms → Collect per-provider results → Retry failures
/children/{childID}/enforcePush the child's active policy rules to all verified compliance links (platform connections). Creates an enforcement job that fans out to each connected platform concurrently. Returns the job for status polling.
idSync job identifier
child_idTarget child identifier
policy_idPolicy being enforced
trigger_typeOne of: manual, auto, webhook
statusOne of: pending, running, completed, failed, partial
started_atJob start timestamp
completed_atJob completion timestamp
created_atJob creation timestamp
curl -X POST https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/enforce \
-H "Authorization: Bearer <access_token>"{
"id": "f6a7b8c9-d0e1-2345-f012-3456789abcde",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"trigger_type": "manual",
"status": "pending",
"created_at": "2025-01-10T10:30:00Z"
}/children/{childID}/enforcement/jobsList all enforcement jobs for a child, ordered by creation time (newest first). Useful for viewing enforcement history and identifying failures.
[]Array of enforcement job objects
curl https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/enforcement/jobs \
-H "Authorization: Bearer <access_token>"[
{
"id": "f6a7b8c9-d0e1-2345-f012-3456789abcde",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"trigger_type": "manual",
"status": "completed",
"started_at": "2025-01-10T10:30:01Z",
"completed_at": "2025-01-10T10:30:05Z",
"created_at": "2025-01-10T10:30:00Z"
}
]/children/{childID}/syncTrigger enforcement sync for a child across all connected providers. Pushes the active policy's rules to each provider. Returns a sync job that can be polled for status.
idSync job identifier
child_idTarget child identifier
policy_idPolicy being enforced
trigger_typeOne of: manual, auto, webhook
statusOne of: pending, running, completed, failed, partial
started_atJob start timestamp
completed_atJob completion timestamp
created_atJob creation timestamp
curl -X POST https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/sync \
-H "Authorization: Bearer <access_token>"{
"id": "f6a7b8c9-d0e1-2345-f012-3456789abcde",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"policy_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"trigger_type": "manual",
"status": "pending",
"started_at": null,
"completed_at": null,
"created_at": "2025-01-10T10:30:00Z"
}/sync/jobs/{jobID}Check the status of a sync job. Poll this endpoint until status is completed, failed, or partial.
idSync job identifier
child_idTarget child identifier
policy_idPolicy being enforced
trigger_typeOne of: manual, auto, webhook
statusOne of: pending, running, completed, failed, partial
started_atJob start timestamp
completed_atJob completion timestamp
created_atJob creation timestamp
curl https://api.phosra.com/api/v1/sync/jobs/f6a7b8c9-d0e1-2345-f012-3456789abcde \
-H "Authorization: Bearer <access_token>"{
"id": "f6a7b8c9-d0e1-2345-f012-3456789abcde",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"policy_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"trigger_type": "manual",
"status": "completed",
"started_at": "2025-01-10T10:30:01Z",
"completed_at": "2025-01-10T10:30:05Z",
"created_at": "2025-01-10T10:30:00Z"
}/sync/jobs/{jobID}/resultsGet per-provider results for a completed sync job. Each result shows how many rules were applied, skipped, or failed for that provider.
[]Per-provider result breakdown
curl https://api.phosra.com/api/v1/sync/jobs/f6a7b8c9-d0e1-2345-f012-3456789abcde/results \
-H "Authorization: Bearer <access_token>"[
{
"id": "a7b8c9d0-e1f2-3456-0123-456789abcdef",
"sync_job_id": "f6a7b8c9-d0e1-2345-f012-3456789abcde",
"provider_id": "nextdns",
"status": "completed",
"rules_applied": 8,
"rules_skipped": 2,
"rules_failed": 0,
"error_message": null,
"details": {
"profile_id": "abc123"
}
}
]/enforcement/jobs/{jobID}/retryRetry a failed or partial enforcement job. Only failed providers are retried — providers that previously succeeded are skipped. Requires the original job to be in failed or partial status.
curl -X POST https://api.phosra.com/api/v1/enforcement/jobs/f6a7b8c9-d0e1-2345-f012-3456789abcde/retry \
-H "Authorization: Bearer <access_token>"{
"id": "a1b2c3d4-new-retry-job-id",
"parent_job_id": "f6a7b8c9-d0e1-2345-f012-3456789abcde",
"status": "pending",
"retry_count": 1,
"providers_retrying": [
"nextdns"
],
"created_at": "2025-01-10T10:35:00Z"
}PCSS defines a unified content rating framework spanning 5 international rating systems. Platforms MUST map their internal content ratings to the nearest PCSS equivalent. Cross-system equivalences SHALL be computed with a confidence score (0-1).
/ratings/systemsList all supported content rating systems (MPAA, TV Parental Guidelines, ESRB, PEGI, Common Sense Media). This endpoint is public.
[]Array of rating system objects
curl https://api.phosra.com/api/v1/ratings/systems[
{
"id": "mpaa",
"name": "MPAA",
"country": "US",
"media_type": "film"
},
{
"id": "tv",
"name": "TV Parental Guidelines",
"country": "US",
"media_type": "tv"
},
{
"id": "esrb",
"name": "ESRB",
"country": "US/CA",
"media_type": "game"
},
{
"id": "pegi",
"name": "PEGI",
"country": "EU",
"media_type": "game"
},
{
"id": "csm",
"name": "Common Sense Media",
"country": "US",
"media_type": "general"
}
]/ratings/by-ageLook up the maximum appropriate content rating for a given age across all rating systems. This endpoint is public and useful for previewing age mappings without creating a child profile.
ageAge in years (query parameter: ?age=10)
ageQueried age
ratingsMap of rating system ID to maximum allowed rating
curl "https://api.phosra.com/api/v1/ratings/by-age?age=10"{
"age": 10,
"ratings": {
"mpaa": {
"code": "PG",
"name": "Parental Guidance Suggested",
"min_age": 8
},
"tv": {
"code": "TV-PG",
"name": "Parental Guidance Suggested",
"min_age": 8
},
"esrb": {
"code": "E10+",
"name": "Everyone 10+",
"min_age": 10
},
"pegi": {
"code": "PEGI 12",
"name": "PEGI 12",
"min_age": 12
},
"csm": {
"code": "10+",
"name": "Age 10+",
"min_age": 10
}
}
}Platforms SHOULD register webhook endpoints to receive real-time enforcement notifications. All webhook payloads MUST be signed using HMAC-SHA256 with the webhook secret. Platforms MUST verify the X-Phosra-Signature header before processing.
# Signature verification signature = HMAC-SHA256(webhook_secret, request_body) # Compare with X-Phosra-Signature header (hex-encoded)
Supported events: enforcement.completed enforcement.failed policy.updated policy.activated compliance.verified compliance.failed
/webhooksRegister a webhook endpoint to receive real-time notifications for enforcement, policy, and compliance events. All payloads are signed with HMAC-SHA256 using the provided secret.
urlHTTPS endpoint URL for delivery
eventsEvent types to subscribe to
secretHMAC-SHA256 signing secret
idWebhook identifier
family_idOwning family identifier
urlDelivery endpoint URL
eventsSubscribed event types
statusOne of: active, paused, failed
created_atWebhook creation timestamp
curl -X POST https://api.phosra.com/api/v1/webhooks \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/webhooks/phosra",
"events": ["enforcement.completed", "enforcement.failed", "policy.updated"],
"secret": "whsec_your_secret_key"
}'{
"id": "wh_abc123",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://api.example.com/webhooks/phosra",
"events": [
"enforcement.completed",
"enforcement.failed",
"policy.updated"
],
"status": "active",
"created_at": "2025-01-10T10:00:00Z"
}/webhooks/{webhookID}Retrieve details of a specific webhook including its event subscriptions and delivery statistics.
idWebhook identifier
family_idOwning family identifier
urlDelivery endpoint URL
eventsSubscribed event types
statusOne of: active, paused, failed
created_atWebhook creation timestamp
curl https://api.phosra.com/api/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer <access_token>"{
"id": "wh_abc123",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://api.example.com/webhooks/phosra",
"events": [
"enforcement.completed",
"enforcement.failed",
"policy.updated"
],
"status": "active",
"created_at": "2025-01-10T10:00:00Z"
}/webhooks/{webhookID}Update a webhook's URL, event subscriptions, or secret. Changes take effect immediately for the next delivery.
urlHTTPS endpoint URL for delivery
eventsEvent types to subscribe to
secretHMAC-SHA256 signing secret
curl -X PUT https://api.phosra.com/api/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"events": ["enforcement.completed", "enforcement.failed", "policy.updated", "compliance.verified"]
}'// 200 OK/webhooks/{webhookID}Permanently delete a webhook. No further events will be delivered to this endpoint. Pending deliveries are cancelled.
curl -X DELETE https://api.phosra.com/api/v1/webhooks/wh_abc123 \
-H "Authorization: Bearer <access_token>"// 204 No Content/webhooks/{webhookID}/testSend a test ping event to the webhook endpoint. Returns delivery status, response code, and latency. Use this to verify your endpoint is correctly configured and can handle HMAC signature verification.
curl -X POST https://api.phosra.com/api/v1/webhooks/wh_abc123/test \
-H "Authorization: Bearer <access_token>"{
"delivery_id": "del_test01",
"event": "test.ping",
"status": "delivered",
"response_code": 200,
"response_time_ms": 145
}/webhooks/{webhookID}/deliveriesList recent webhook deliveries with status, response codes, and timestamps. Failed deliveries are retried with exponential backoff (1min, 5min, 30min). Delivery history is retained for 30 days.
curl https://api.phosra.com/api/v1/webhooks/wh_abc123/deliveries \
-H "Authorization: Bearer <access_token>"[
{
"id": "del_001",
"event": "enforcement.completed",
"status": "delivered",
"response_code": 200,
"timestamp": "2025-01-12T18:05:00Z"
},
{
"id": "del_002",
"event": "policy.updated",
"status": "delivered",
"response_code": 200,
"timestamp": "2025-01-12T17:30:00Z"
}
]Each platform is classified into one of three compliance levels. Platforms MUST progress toward full compliance. Regression from Compliant to a lower level SHALL trigger regulatory review.
The following timeline governs the transition to mandatory PCSS compliance for all regulated platforms.
Platforms MAY register and begin compliance integration. Early adopters receive Compliant certification.
Platforms serving minors SHOULD register with the PCSS platform registry to track compliance status.
All platforms MUST achieve at least Provisional compliance. Platforms at Pending SHALL face regulatory review and potential enforcement action.
All PCSS API endpoints are served under:
https://phosra-api.fly.dev/api/v1
Platforms MUST use HTTPS in production environments. HTTP MAY be used only in development.
Phosra provides a guided Quick Setup flow that enables parents to protect their children across all regulated platforms in under one minute. The three-step wizard handles family creation, age-based policy generation, and platform verification.
Enter name, birth date, and choose a protection level (Recommended, Strict, or Relaxed).
See plain-language summary cards for screen time, content ratings, web filtering, social controls, privacy, and algorithm safety.
Verify compliance on platforms with a progress indicator. Enforce with one click after connecting.
Phosra supports community standards (also called movements) — curated rule sets based on expert guidance, research, and advocacy organizations. Parents MAY adopt one or more standards for each child to automatically generate matching policy rules.
Standards provide a "one-click" way to align with community guidelines like the Four Norms from Jonathan Haidt's Anxious Generation, Wait Until 8th, or Common Sense Media age ratings. When adopted, the standard's rules are merged into the child's active policy.
Research-backed rule sets from child development experts and psychologists.
Grassroots movements like Wait Until 8th and Smartphone Free Childhood.
Recommendations from AAP, Common Sense Media, and other organizations.
Browse all available standards at /standards. The Phosra API currently includes 31 community standards spanning expert guidance, parenting pledges, and organizational recommendations.
/standardsList all available community standards (movements). Each standard defines a set of recommended rules based on expert guidance — e.g. Wait Until 8th, Four Norms (Anxious Generation), Common Sense Media guidelines. This endpoint is public.
[]Array of community standard objects
curl https://api.phosra.com/api/v1/standards[
{
"id": "four-norms",
"slug": "four-norms",
"name": "Four Norms (Anxious Generation)",
"description": "Jonathan Haidt's four foundational norms for childhood in the smartphone age.",
"rules_count": 6,
"category": "expert"
},
{
"id": "wait-until-8th",
"slug": "wait-until-8th",
"name": "Wait Until 8th",
"description": "The pledge to wait until at least 8th grade before giving children a smartphone.",
"rules_count": 4,
"category": "pledge"
}
]/standards/{slug}Get full details of a community standard including all recommended rules, age thresholds, and supporting research. This endpoint is public.
idStandard identifier
slugURL-friendly slug
nameStandard display name
descriptionSummary of the standard's purpose
rulesRecommended rules with categories and values
rules_countNumber of rules in the standard
categoryStandard category (expert, pledge, organization)
curl https://api.phosra.com/api/v1/standards/four-norms{
"id": "four-norms",
"slug": "four-norms",
"name": "Four Norms (Anxious Generation)",
"description": "Jonathan Haidt's four foundational norms for childhood in the smartphone age.",
"rules": [
{
"category": "social_media_min_age",
"value": "16",
"label": "No social media before 16"
},
{
"category": "time_daily_limit",
"value": "120",
"label": "Phone-free schools"
},
{
"category": "time_bedtime",
"value": "enabled",
"label": "Device-free bedrooms"
}
],
"rules_count": 6,
"category": "expert"
}/children/{childID}/standardsList all community standards adopted for a specific child. Adopted standards automatically generate corresponding policy rules.
curl https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/standards \
-H "Authorization: Bearer <access_token>"[
{
"standard_id": "four-norms",
"name": "Four Norms (Anxious Generation)",
"adopted_at": "2025-01-15T10:00:00Z",
"rules_applied": 6
}
]/children/{childID}/standardsAdopt a community standard for a child. This generates policy rules matching the standard's recommendations and adds them to the child's active policy. If rules for the same categories already exist, they are updated to match the standard.
standard_idSlug of the community standard to adopt
curl -X POST https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/standards \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "standard_id": "four-norms" }'{
"standard_id": "four-norms",
"name": "Four Norms (Anxious Generation)",
"adopted_at": "2025-01-15T10:00:00Z",
"rules_applied": 6,
"rules_created": 3,
"rules_updated": 3
}/children/{childID}/standards/{standardID}Remove a community standard from a child. The associated policy rules are not automatically deleted — they remain as manually-configured rules. To remove the rules as well, delete them individually or regenerate the policy from age.
curl -X DELETE https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/standards/four-norms \
-H "Authorization: Bearer <access_token>"// 204 No ContentPhosra maintains a registry of 21 parental control applications and services that can be connected as sources — apps parents already use to manage their children's devices. Unlike target platforms that Phosra pushes rules to, sources are apps that Phosra integrates with to push rules through.
Direct API integration. Phosra pushes rules automatically via documented REST endpoints.
Qustodio, Apple Screen Time (MDM), Google Family Link
Integration with platforms offering documented APIs. Phosra translates rules into each platform's native format.
Platforms with REST or MDM APIs
Guided setup mode. Phosra generates step-by-step instructions for manual configuration.
Net Nanny, Norton Family, Kaspersky, Circle
Identified integration points. Availability may vary.
Bark Phone
Each source is mapped to Phosra's 45 rule categories with full, partial, or none support per capability. Browse all sources with their capability matrices at /parental-controls.
POST /v1/sources — Connect a parental control app to a child
POST /v1/sources/{sourceID}/sync — Push all rules to source
POST /v1/sources/{sourceID}/rules — Push individual capability
GET /v1/sources/{sourceID}/guide/{category} — Get guided setup steps (no-API sources)
The reporting API provides family-level overviews of enforcement status, compliance health, and per-child statistics. Reports SHOULD be used by parent-facing applications to surface the current protection state at a glance.
/families/{familyID}/reports/overviewGet a comprehensive overview report for a family including per-child enforcement status, compliance link health, recent activity, and rule coverage statistics.
curl https://api.phosra.com/api/v1/families/a1b2c3d4-e5f6-7890-abcd-ef1234567890/reports/overview \
-H "Authorization: Bearer <access_token>"{
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"children": [
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "Emma",
"age": 6,
"active_policy": "School Days",
"rules_enabled": 22,
"platforms_connected": 2,
"last_enforcement": "2025-01-12T18:00:00Z",
"enforcement_status": "healthy"
}
],
"compliance_summary": {
"total_links": 2,
"verified": 2,
"failed": 0
},
"enforcement_summary": {
"total_jobs_7d": 5,
"success_rate": 1,
"avg_rules_pushed": 26
}
}Anonymous feedback endpoint for collecting user experience data. No authentication required.
/feedbackSubmit product feedback or a feature request. This endpoint is public and does not require authentication, allowing anonymous feedback from site visitors.
typeOne of: bug, feature, general
messageFeedback message (max 2000 characters)
emailOptional contact email for follow-up
curl -X POST https://api.phosra.com/api/v1/feedback \
-H "Content-Type: application/json" \
-d '{
"type": "feature",
"message": "Would love to see Roku integration",
"email": "user@example.com"
}'{
"id": "fb_abc123",
"type": "feature",
"message": "Would love to see Roku integration",
"status": "new",
"created_at": "2025-01-15T14:00:00Z"
}Native iOS integration endpoints for Apple Screen Time enforcement via FamilyControls, ManagedSettings, and DeviceActivity frameworks. Devices register with parent authorization, pull versioned policies with 304 Not Modified support, and report per-category enforcement results back to the API.
Parent-authenticated CRUD for managing child devices and capabilities
Versioned policy pull with APNs silent push notifications on changes
Per-category enforcement status reporting with framework context
When a policy is updated, Phosra sends a silent push notification to all active devices registered for that child. Your app MUST handle this in application(_:didReceiveRemoteNotification:fetchCompletionHandler:) and trigger a policy refresh via GET /device/policy.
{
"aps": {
"content-available": 1
},
"phosra": {
"event": "policy.updated",
"version": 3
}
}aps.content-availableAlways 1 — marks this as a silent/background push. No alert, sound, or badge.phosra.eventEvent type. Currently always "policy.updated".phosra.versionThe new policy version number. Compare with your cached version — if higher, call GET /device/policy.apns-push-typebackgroundapns-priority5 — required for silent push (priority 10 would require an alert)apns-topicYour app's bundle ID (e.g. com.downtime.downtime)func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler handler: @escaping (UIBackgroundFetchResult) -> Void
) {
guard let phosra = userInfo["phosra"] as? [String: Any],
let event = phosra["event"] as? String,
event == "policy.updated",
let version = phosra["version"] as? Int else {
handler(.noData)
return
}
// Only refresh if the pushed version is newer than our cached version
guard version > PolicyCache.shared.currentVersion else {
handler(.noData)
return
}
Task {
do {
let policy = try await PhosraAPI.fetchPolicy()
PolicyEnforcer.shared.apply(policy)
handler(.newData)
} catch {
handler(.failed)
}
}
}BGAppRefreshTask).PUT /devices/{deviceID} with the new apns_token./children/{childID}/devicesRegister an Apple device for on-device policy enforcement. Returns a one-time API key that the iOS app stores in Keychain. The API key is used for all subsequent device-auth requests (policy polling, reports, ack). The plaintext key is never stored server-side — only its SHA-256 hash.
device_nameHuman-readable name (e.g. 'Sofia\'s iPad')
device_modelDevice model (e.g. 'iPad Pro 11-inch')
os_versioniOS version (e.g. '18.2')
app_versionPhosra app version (e.g. '1.0.0')
apns_tokenApple Push Notification token (optional)
capabilitiesApple frameworks the device supports (e.g. ['FamilyControls', 'ManagedSettings', 'DeviceActivity'])
deviceThe registered device
api_keyOne-time device API key — store in Keychain immediately
curl -X POST https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/devices \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"device_name": "Sofia'\''s iPad",
"device_model": "iPad Pro 11-inch",
"os_version": "18.2",
"app_version": "1.0.0"
}'{
"device": {
"id": "d1e2f3a4-b5c6-7890-abcd-ef1234567890",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"platform_id": "apple",
"device_name": "Sofia's iPad",
"device_model": "iPad Pro 11-inch",
"os_version": "18.2",
"app_version": "1.0.0",
"apns_token": null,
"capabilities": [
"FamilyControls",
"ManagedSettings",
"DeviceActivity"
],
"enforcement_summary": {},
"last_seen_at": null,
"last_policy_version": 0,
"status": "active",
"created_at": "2026-02-17T10:00:00Z",
"updated_at": "2026-02-17T10:00:00Z"
},
"api_key": "a3f8b2c1d4e5f6789012345678abcdef0123456789abcdef0123456789abcdef"
}/children/{childID}/devicesList all registered Apple devices for a child. Shows each device's status, last seen time, and which policy version it last acknowledged. Useful for the parent dashboard to monitor device health.
[]Registered devices for this child
curl https://api.phosra.com/api/v1/children/b2c3d4e5-f6a7-8901-bcde-f12345678901/devices \
-H "Authorization: Bearer <access_token>"[
{
"id": "d1e2f3a4-b5c6-7890-abcd-ef1234567890",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"family_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"platform_id": "apple",
"device_name": "Sofia's iPad",
"device_model": "iPad Pro 11-inch",
"os_version": "18.2",
"app_version": "1.0.0",
"capabilities": [
"FamilyControls",
"ManagedSettings",
"DeviceActivity"
],
"enforcement_summary": {
"content_rating": {
"status": "enforced",
"framework": "ManagedSettings"
},
"time_daily_limit": {
"status": "enforced",
"framework": "DeviceActivity"
},
"web_safesearch": {
"status": "enforced",
"framework": "ManagedSettings"
}
},
"last_seen_at": "2026-02-17T14:30:00Z",
"last_policy_version": 3,
"status": "active",
"created_at": "2026-02-17T10:00:00Z",
"updated_at": "2026-02-17T14:30:00Z"
}
]/devices/{deviceID}Update device metadata such as APNs token, app version, or device name. All fields are optional — only provided fields are updated. Typically called when the iOS app updates or the APNs token rotates.
device_nameUpdated device name
apns_tokenUpdated Apple Push Notification token
app_versionUpdated app version after upgrade
os_versionUpdated iOS version after OS update
idDevice registration identifier
child_idAssociated child identifier
family_idParent family identifier
platform_idPlatform slug (always 'apple')
device_nameHuman-readable device name (e.g. 'Sofia\'s iPad')
device_modelDevice model identifier (e.g. 'iPad Pro 11-inch')
os_versioniOS version (e.g. '18.2')
app_versionPhosra iOS app version (e.g. '1.0.0')
apns_tokenApple Push Notification token (optional)
capabilitiesApple frameworks the device supports (e.g. FamilyControls, ManagedSettings, DeviceActivity, WebContentFilter)
enforcement_summaryPer-category enforcement results from the device's last enforcement_status report
last_seen_atLast time the device contacted the API
last_policy_versionLast policy version the device acknowledged
statusOne of: active, inactive, revoked
created_atRegistration timestamp
updated_atLast update timestamp
curl -X PUT https://api.phosra.com/api/v1/devices/d1e2f3a4-b5c6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"apns_token": "new_apns_token_abc123",
"app_version": "1.1.0"
}'{
"id": "d1e2f3a4-b5c6-7890-abcd-ef1234567890",
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"platform_id": "apple",
"device_name": "Sofia's iPad",
"device_model": "iPad Pro 11-inch",
"os_version": "18.2",
"app_version": "1.1.0",
"apns_token": "new_apns_token_abc123",
"last_policy_version": 3,
"status": "active",
"updated_at": "2026-02-17T15:00:00Z"
}/devices/{deviceID}Revoke a device's API key, preventing it from polling for policies or submitting reports. The device registration is kept for audit purposes but marked as 'revoked'. The iOS app will receive 401 on its next request.
curl -X DELETE https://api.phosra.com/api/v1/devices/d1e2f3a4-b5c6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer <access_token>"/device/policyFetch the compiled policy document for the authenticated device's child. Returns a structured JSON document the iOS app interprets to configure FamilyControls, ManagedSettings, and DeviceActivity. Supports conditional polling: pass ?since_version=N to get a 304 Not Modified if the policy hasn't changed. Auth: X-Device-Key header (not Bearer JWT).
since_versionReturn 304 if current version is <= this value (query parameter)
versionPolicy version (auto-increments on changes)
child_idChild this policy applies to
child_ageChild's current age in years
age_groupAge group label (e.g. 'Child', 'Teen')
policy_idSource policy identifier
statusPolicy status (active)
generated_atWhen the compiled document was generated
content_filterContent restriction settings
screen_timeScreen time limits
purchasesPurchase controls
privacyPrivacy settings
socialSocial interaction controls
notificationsNotification controls
web_filterWeb filtering settings
curl https://api.phosra.com/api/v1/device/policy?since_version=2 \
-H "X-Device-Key: <device_api_key>"{
"version": 3,
"child_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"child_age": 7,
"age_group": "Child",
"policy_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"status": "active",
"generated_at": "2026-02-17T15:00:00Z",
"content_filter": {
"age_rating": "4+",
"max_ratings": {
"mpaa": "PG",
"tvpg": "TV-Y7",
"esrb": "E",
"pegi": "7",
"csm": "7+",
"apple": "4+"
},
"blocked_apps": [
"com.epic.fortnite"
],
"allowed_apps": [],
"allowlist_mode": false
},
"screen_time": {
"daily_limit_minutes": 120,
"per_app_limits": [
{
"bundle_id": "com.google.youtube",
"daily_minutes": 30
}
],
"downtime_windows": [
{
"days_of_week": [
"mon",
"tue",
"wed",
"thu",
"fri"
],
"start_time": "20:00",
"end_time": "07:00"
}
],
"always_allowed_apps": [
"com.apple.mobilephone",
"com.apple.MobileSMS",
"com.apple.Maps"
],
"schedule": {
"weekday": {
"start": "07:00",
"end": "20:00"
},
"weekend": {
"start": "08:00",
"end": "21:00"
}
}
},
"purchases": {
"require_approval": true,
"block_iap": true,
"spending_cap_usd": 0
},
"privacy": {
"location_sharing_enabled": true,
"profile_visibility": "private",
"account_creation_approval": true,
"data_sharing_restricted": true
},
"social": {
"chat_mode": "contacts_only",
"dm_restriction": "disabled",
"multiplayer_mode": "friends_only"
},
"notifications": {
"curfew_start": "20:00",
"curfew_end": "07:00",
"usage_timer_minutes": 30
},
"web_filter": {
"level": "strict",
"safe_search": true,
"blocked_domains": [
"reddit.com",
"4chan.org"
],
"allowed_domains": [],
"blocked_categories": [
"gambling",
"dating",
"adult"
]
}
}/device/reportSubmit an activity report from the iOS app. Reports are stored in device_reports and fanned out to the activity_logs table for unified analytics. Report types: screen_time (daily usage), app_usage (per-app breakdown), web_activity (browsing history), blocked_attempt (enforcement events), enforcement_status (per-category enforcement results — also updates the device's enforcement_summary for the parent dashboard). Auth: X-Device-Key header.
report_typeOne of: screen_time, app_usage, web_activity, blocked_attempt, enforcement_status
payloadReport data (varies by report_type). For enforcement_status: { policy_version, results: [{ category, status, framework, detail }] }
reported_atWhen the activity occurred on-device
curl -X POST https://api.phosra.com/api/v1/device/report \
-H "X-Device-Key: <device_api_key>" \
-H "Content-Type: application/json" \
-d '{
"report_type": "screen_time",
"payload": {
"total_minutes": 95,
"by_category": { "games": 40, "education": 30, "social": 25 },
"top_apps": [
{ "bundle_id": "com.mojang.minecraftpe", "minutes": 35 },
{ "bundle_id": "com.duolingo", "minutes": 30 }
]
},
"reported_at": "2026-02-17T20:00:00Z"
}'{
"status": "accepted"
}/device/ackConfirm that the iOS app has successfully applied a specific policy version. Updates the device's last_policy_version so the parent dashboard can verify enforcement is current. Auth: X-Device-Key header.
versionThe policy version that was successfully applied
curl -X POST https://api.phosra.com/api/v1/device/ack \
-H "X-Device-Key: <device_api_key>" \
-H "Content-Type: application/json" \
-d '{ "version": 3 }'{
"acknowledged_version": 3
}/platform-mappings/{platformID}Get platform-specific identifier mappings. Currently supports 'apple' — returns Apple age ratings, App Store category bundle IDs, system app bundle IDs, default always-allowed apps, and a category-to-framework mapping that tells the iOS app which Apple framework (ManagedSettings, DeviceActivity, FamilyControls) to use for each Phosra rule category. This endpoint is public and does not require authentication.
age_ratingsMPAA/TVPG rating to Apple age rating mapping
app_categoriesCategory → bundle IDs and App Store categories
system_appsSystem app name → bundle ID (e.g. phone → com.apple.mobilephone)
always_allowedDefault always-allowed bundle IDs (Phone, Messages, etc.)
category_frameworksPhosra rule category → Apple framework mapping for on-device enforcement
curl https://api.phosra.com/api/v1/platform-mappings/apple{
"age_ratings": {
"G": "4+",
"PG": "9+",
"PG-13": "12+",
"R": "17+",
"NC-17": "17+",
"TV-Y": "4+",
"TV-Y7": "4+",
"TV-PG": "9+",
"TV-14": "12+",
"TV-MA": "17+",
"E": "4+",
"E10+": "9+",
"T": "12+",
"M": "17+",
"AO": "17+"
},
"app_categories": {
"social-media": {
"bundle_ids": [
"com.burbn.instagram",
"com.atebits.Tweetie2",
"com.toyopagroup.picaboo"
],
"app_store_category": "Social Networking"
},
"gaming": {
"bundle_ids": [
"com.supercell.laser",
"com.epic.fortnite",
"com.mojang.minecraftpe"
],
"app_store_category": "Games"
}
},
"system_apps": {
"phone": "com.apple.mobilephone",
"messages": "com.apple.MobileSMS",
"facetime": "com.apple.facetime",
"maps": "com.apple.Maps",
"camera": "com.apple.camera"
},
"always_allowed": [
"com.apple.mobilephone",
"com.apple.MobileSMS",
"com.apple.facetime",
"com.apple.Maps"
],
"category_frameworks": {
"content_rating": {
"framework": "ManagedSettings",
"api_class": "ManagedSettingsStore.application",
"min_os": "16.0"
},
"time_daily_limit": {
"framework": "DeviceActivity",
"api_class": "DeviceActivitySchedule",
"min_os": "16.0"
},
"web_safesearch": {
"framework": "ManagedSettings",
"api_class": "ManagedSettingsStore.webContent.autoFilter",
"min_os": "16.0"
},
"purchase_block_iap": {
"framework": "ManagedSettings",
"api_class": "ManagedSettingsStore.appStore.denyInAppPurchases",
"min_os": "16.0"
},
"social_contacts": {
"framework": "FamilyControls",
"api_class": "AuthorizationCenter",
"min_os": "16.0"
},
"algo_feed_control": {
"framework": "none",
"api_class": "",
"min_os": "",
"notes": "Platform-level — no Apple API; enforce by blocking/limiting social apps"
}
}
}