OpenSPP Documentation v2.0

⌘ K
  • Products
    • OpenSPP SP-MIS
      • Modules included
      • Relevant user guides
      • Relevant configuration guides
      • Demo module
    • OpenSPP Social Registry
      • Modules included
      • Relevant user guides
      • Relevant configuration guides
    • OpenSPP Farmer Registry
      • Modules included
      • Relevant user guides
      • Relevant configuration guides
    • OpenSPP DRIMS
      • Modules included
      • Relevant user guides
      • Relevant configuration guides
    • OpenSPP Disability Registry
      • Modules included
      • Relevant user guides
      • Relevant configuration guides
    • Custom module combinations
    • Features in OpenSPP
      • Unified registry
      • GIS & land management
      • Program management
      • Eligibility & targeting
      • Payment & disbursement
      • In-Kind benefits
      • Data integration & APIs
      • Change management
      • Grievance redress
  • Learn
    • Registry
    • Programs
    • Cycles
    • Eligibility
    • Compliance
    • Entitlements
    • Payments
    • Deduplication
    • Change requests
  • Get started
    • Installing OpenSPP
      • Docker installation
    • Module installation
      • General module installation
      • SP-MIS installation
      • Social Registry installation
      • Farmer Registry installation
      • DRIMS installation
      • Disability Registry installation
    • Try our products
      • Try OpenSPP SP-MIS
        • Install SP-MIS demo data
        • SP-MIS Stories
        • SP-MIS Demo scenarios
    • Choosing your configuration
    • Configuration vs customization
    • From Proof of Concept to Pilot
  • User guide
    • Getting started
      • Navigating the OpenSPP interface
      • Administrating role-based access
    • Registry
      • Register an individual
      • Register a group
      • Search and filter registrants
      • Import registrant data
      • Export registrant data
      • Manage farm data
    • Change Requests
      • Submit a change request
      • Review a change request
      • Change request types
    • Case management
      • Core case management workflow
    • Programs
      • Create programs
      • Manage in-kind products
      • Work with program cycles
      • Enroll beneficiaries
      • Allocate funds to programs
      • Manage entitlements
    • Payments
      • View Service Points
    • Approvals
      • Review and Approve Requests
    • DRIMS User Guide
      • Understand the Dashboard
      • Receive a Donation
      • Manage Inventory
      • Submit a Relief Request
      • Process a Dispatch
      • Handle Returns
    • Grievance Redress Mechanism (GRM)
      • Manage grievances
    • Geographic Information System (GIS)
      • View maps and generate reports
    • Reference
      • Geographic Areas
      • Vocabularies (Code Lists)
  • Configuration guide
    • Alerts
      • Alerts overview
    • Approval workflows
      • Approval workflows overview
      • Approval tiers
      • Batch approvals and freeze periods
    • Area management
      • Area management overview
      • HDX COD integration
    • Audit configuration
      • Audit configuration overview
      • Audit backends
    • Banking
      • Banking overview
    • Case management
      • Case management overview
      • Case stages
      • Case teams
    • CEL expressions
      • CEL quick start
      • CEL syntax reference
      • Variables
      • CEL cookbook
      • CEL troubleshooting
    • Change request types
      • Overview
      • Creating change request types
      • Field mappings
      • Conflict and duplicate detection
      • Common configuration patterns
      • Custom detail models
      • Troubleshooting
    • Consent configuration
      • Consent management overview
      • Configuring privacy notices
      • Recording consent
      • API consent filtering
    • Custom fields
      • Custom fields overview
    • DRIMS Configuration Guide
      • Configuring Warehouses
      • Configuring Approval Workflows
      • Configuring Alerts and Thresholds
      • Configuring Vocabularies
    • Eligibility rules
      • CEL expressions for eligibility
      • Geographic targeting
      • Expression templates
      • Testing eligibility rules
      • Advanced eligibility configuration
    • Entitlement formulas
      • Cash calculations
      • In-kind entitlements
      • Formula library
      • Dynamic entitlements
      • Conditional logic
    • Event Data
      • Event Data Overview
      • Configuring Event Types
      • Defining Event Fields
    • Farmer registry
      • Farmer registry overview
      • Farm details, seasons, and activities
    • GIS configuration
      • GIS configuration overview
      • GIS reports and indicator layers
    • Grievance redress
      • Grievance redress overview
      • SLA rules
      • GRM teams and tags
    • Hazard management
      • Hazard management overview
      • Linking programs to hazard incidents
    • Import matching
      • Import matching overview
    • OpenSPP Studio
      • Studio Overview
      • Custom Fields (Registry Field Builder)
      • Event Type Designer
    • Role configuration
      • Access control overview
      • Assigning roles to users
      • Predefined roles
      • Creating custom roles
      • Troubleshooting
    • Scoring & Assessment
      • Scoring Framework Overview
      • Proxy Means Test (PMT) Configuration
      • Vulnerability Scoring Configuration
      • Social Welfare Development Index (SWDI)
      • Creating Custom Scoring Formulas
    • Service points
      • Service points overview
      • Service point lifecycle
    • Session tracking
      • Session tracking overview
    • Simulation
      • Simulation overview
    • Storage backend
      • Storage backend overview
    • Variables
      • Variables Overview
      • Creating Variables
      • Variable Types
      • Using Variables in CEL
    • Vocabulary System
      • Vocabulary Overview
      • Standard Vocabularies
      • Vocabulary Profiles
      • Custom Vocabularies
  • Developer guide
    • Development setup
    • Architecture
      • Module organization
      • Data model
    • Custom modules
      • Module scaffold
      • Models
      • Security
      • Views and menus
      • Mixins
      • Testing
      • Example: custom registry fields
    • Custom program managers
      • Manager pattern
      • Building a custom manager
      • Tutorial: build CCT program managers
    • Custom change request types
      • Detail models
      • Apply strategies
      • Approval hooks
      • Tutorial: build a transfer member CR type
    • API V2
      • API V2 Overview
      • Authentication
      • External Identifiers
      • Consent Management
      • API Resources
      • Search and Filtering
      • Batch Operations
      • Error Handling
      • Tutorial: build a Python API client
      • Studio API Integration
      • Entitlements and Cycles
      • Products and Service Points
    • DCI Integration
      • DCI Overview
      • OpenSPP as DCI Server
      • OpenSPP as DCI Client
      • DCI Protocol Details
    • Security and Encryption
    • CEL (Common Expression Language)
      • CEL Internals
    • Studio
    • Audit and Versioning
    • Contributing
  • Operations guide
    • Deployment
      • Production Hardening
    • Security
      • Access Control
      • Data Classification
      • PII Encryption
      • Key Management
      • Audit Logging
      • Security Scanning
    • Storage
    • Backup & Recovery
    • Monitoring & Alerts
  • Reference
    • Modules Reference
      • Alerts
      • Analytics
      • API V2
        • Change Request
        • Cycles
        • Data
        • Entitlements
        • GIS API
        • Products
        • Service Points
        • Simulation API
        • Vocabulary
      • Approval Workflows
      • Area Management
      • HDX COD Integration
      • Attachment Antivirus Scan
      • Audit
      • Banking / Bank Details
      • Base (Common)
      • Base Settings
      • Branding Kit
      • Case Management Base
        • CEL Rules
        • Demo Data
        • Entitlements Integration
        • Graduation Integration
        • Programs Integration
        • Registry Integration
        • Session Integration
      • CEL Domain Query Builder
        • Event Data Integration
        • Registry Search
        • Vocabulary Integration
        • Expression Widget
      • Registry Search
      • Expression Widget
      • Change Request V2
        • Advanced Types
        • Base Types
      • QR Credentials (Claim 169)
      • Consent
      • Custom Fields
      • DCI Core
        • Client
        • Client - CRVS
        • Client - Disability
        • Client - IBR
        • Demo
        • Server
      • Demo
      • Disability Registry
      • Document Management System
      • DRIMS - Disaster Response Inventory Management
        • Sri Lanka Configuration
        • Sri Lanka Demo
      • Encryption: Base
      • Event Data
      • Farmer Registry
        • Change Request Types
        • Dashboard
        • Demo
        • Vocabularies
      • GIS
        • Indicators
        • Reports
        • Reports - Programs
        • Registrant GIS
      • Graduation Management
      • Grievance Redress Mechanism
        • Case Link
        • CEL Rules
        • Demo Data
        • Programs Integration
        • Registry Integration
      • Hazard & Emergency Management
        • Programs Integration
      • Programs Integration
      • Hide Menus Base
      • HXL Integration
        • Area Integration
      • Import Match
      • Indicator
      • Indicator Studio
      • Irrigation
      • Key Management
      • Land Record
      • Metric
      • Metric Service
      • MIS Demo V2
      • API: Oauth
      • Programs
      • Registrant GIS
      • Registry
      • Registry Group Hierarchy
      • Registry Search Portal
      • Scoring
        • Programs Bridge
      • Security
      • Service Points
      • Session Tracking
      • Targeting Simulation
      • Source Tracking
      • Starter: Farmer Registry
      • Starter: Social Registry
      • Starter: SP-MIS
      • Storage Backend
      • Studio
        • API v2 Integration
        • Change Requests
        • Events
      • User Roles
      • Versioning
      • Vocabulary
      • Theme
    • Vocabulary Reference
    • Humanitarian Terms Glossary
    • OpenSPP Glossary
    • What's new in OpenSPP v2
  • Community and support
    • Contributing
    • Internationalization and Localization
    • Modules Maturity Levels and Development Status Policy
    • Module Lifecycle - Maintainer Role Policy
    • Contributor Covenant Code of Conduct
    • OpenSPP Vulnerability Disclosure Policy
    • Why OpenSPP is built on Odoo
    • Licensing

openspp.org openspp.org

Consent Management – Developer guide
  • repository
  • open issue
  • suggest edit
  • .md
Contents
  • Prerequisites
  • Why Consent Matters
  • How Consent Works
  • Consent Response Headers
  • Response Filtering
    • Full Consent
    • Basic Consent (Limited Fields)
    • No Consent
    • Consent Expired
  • Consent Scopes
    • Extension Fields
  • Legal Basis (No Consent Required)
  • Checking Consent Programmatically
    • Example: Python
    • Example: JavaScript
  • Consent API Endpoints
    • Available Operations
    • Get Consent Status
    • Revoke Consent
  • Consent Collection Methods
  • Purpose Limitation
  • Security Design
    • Consent Matching
    • Enumeration Prevention
  • Handling Consent Errors
    • 403 Forbidden: Insufficient Consent
    • Consent Scope Mismatch
  • Best Practices
    • 1. Always Check Consent Headers
    • 2. Request Only What You Need
    • 3. Handle Partial Data Gracefully
    • 4. Handle Expired Consent
    • 5. Document Your Purpose
  • Complete Example
  • Common mistakes
  • What's next
  • See also

Consent Management

Contents

  • Prerequisites
  • Why Consent Matters
  • How Consent Works
  • Consent Response Headers
  • Response Filtering
    • Full Consent
    • Basic Consent (Limited Fields)
    • No Consent
    • Consent Expired
  • Consent Scopes
    • Extension Fields
  • Legal Basis (No Consent Required)
  • Checking Consent Programmatically
    • Example: Python
    • Example: JavaScript
  • Consent API Endpoints
    • Available Operations
    • Get Consent Status
    • Revoke Consent
  • Consent Collection Methods
  • Purpose Limitation
  • Security Design
    • Consent Matching
    • Enumeration Prevention
  • Handling Consent Errors
    • 403 Forbidden: Insufficient Consent
    • Consent Scope Mismatch
  • Best Practices
    • 1. Always Check Consent Headers
    • 2. Request Only What You Need
    • 3. Handle Partial Data Gracefully
    • 4. Handle Expired Consent
    • 5. Document Your Purpose
  • Complete Example
  • Common mistakes
  • What's next
  • See also

Consent Management#

For: developers

How API V2 applies consent rules to every response — response headers, field filtering, and consent-aware client patterns.

Prerequisites#

  • A working API client and OAuth token (see Authentication)

  • Awareness that responses may be filtered — your client should never assume full data is returned

Why Consent Matters#

OpenSPP API V2 implements privacy-by-design with consent-based access control. This ensures:

  • Data sovereignty: Registrants control who accesses their data

  • Compliance: GDPR, national data protection laws

  • Trust: Transparent data sharing builds community trust

  • Field-level control: Share only what's needed for each purpose

How Consent Works#

┌────────────┐     ┌──────────────┐     ┌───────────────┐
│  API Call  │────►│ Check Consent│────►│ Filter Fields │
│            │     │              │     │   Based on    │
│            │     │ - Registrant │     │   Consent     │
│            │     │ - API Client │     │   Scope       │
│            │     │ - Resource   │     │               │
└────────────┘     └──────────────┘     └───────────────┘
                           │
                           │ No Consent?
                           ▼
                   ┌──────────────┐
                   │Return Minimal│
                   │  (ID only)   │
                   └──────────────┘

When you request a registrant's data:

  1. API checks for active consent from the registrant to your organization

  2. If consent exists, API checks the consent scope (which fields allowed)

  3. API filters the response to only include consented fields

  4. If no consent exists, API returns minimal data (identifiers only)

Consent Response Headers#

API responses include consent status headers:

X-Consent-Status: active
X-Consent-Scope: individual

Header

Description

X-Consent-Status

active, no_consent, expired, legal_basis, scope_mismatch

X-Consent-Scope

Resource type the consent applies to (e.g., individual, group)

Response Filtering#

Full Consent#

When consent is active and covers the requested data:

GET /api/v2/spp/Individual/urn:gov:ph:psa:national-id|PH-123456789
Authorization: Bearer TOKEN

Response:

HTTP/1.1 200 OK
X-Consent-Status: active
X-Consent-Scope: individual

{
  "type": "Individual",
  "identifier": [...],
  "name": {"given": "Maria", "family": "Santos"},
  "birthDate": "1985-03-15",
  "gender": {...},
  "telecom": [...],
  "address": [...]
}

Basic Consent (Limited Fields)#

When consent allows only basic information:

HTTP/1.1 200 OK
X-Consent-Status: active
X-Consent-Scope: individual

{
  "type": "Individual",
  "identifier": [...],
  "name": {"given": "Maria", "family": "Santos"},
  "active": true
}

Note: Only identifier, name, and active fields returned.

No Consent#

When no consent exists:

HTTP/1.1 200 OK
X-Consent-Status: no_consent

{
  "type": "Individual",
  "identifier": [
    {
      "system": "urn:gov:ph:psa:national-id",
      "value": "PH-123456789"
    }
  ],
  "_consent": {
    "status": "no_consent",
    "message": "No active consent for this data access"
  }
}

Note: Only identifiers returned. This allows you to know the record exists without exposing personal data.

Consent Expired#

HTTP/1.1 200 OK
X-Consent-Status: expired

{
  "type": "Individual",
  "identifier": [...],
  "_consent": {
    "status": "expired",
    "message": "Consent has expired"
  }
}

Consent Scopes#

Consent is granted at different levels:

Scope

Fields Included

individual:basic

identifier, name, active

individual:demographic

basic + birthDate, gender

individual:contact

demographic + telecom, address

individual:full

All fields

individual:custom

Administrator-defined field list

Extension Fields#

Module extensions require explicit consent:

GET /api/v2/spp/Individual/...?_extensions=farmer

If consent doesn't include the farmer extension:

{
  "type": "Individual",
  "identifier": [...],
  "name": {...},
  "_consent": {
    "status": "active",
    "message": "Extension 'farmer' not included in consent scope",
    "allowedExtensions": []
  }
}

Legal Basis (No Consent Required)#

Some API clients operate under legal basis that doesn't require individual consent:

Legal Basis

Example

Consent Required

consent

Mobile app for beneficiaries

Yes

legal_obligation

Tax authority audit

No

vital_interest

Emergency health services

No

public_interest

Public health monitoring

No

public_task

Government statistical office

No

contract

Payment processor

No

legitimate_interest

Fraud detection

No

These align with GDPR Article 6 lawful bases. API clients with a legal basis bypass individual consent checks but still respect scope and field-level restrictions.

Checking Consent Programmatically#

Example: Python#

import requests

def check_consent_status(identifier, token, base_url):
    """Check consent status from API response headers."""
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(
        f"{base_url}/Individual/{identifier}",
        headers=headers
    )

    consent_status = response.headers.get("X-Consent-Status")
    consent_scope = response.headers.get("X-Consent-Scope")

    return {
        "status": consent_status,
        "scope": consent_scope,
        "data": response.json()
    }

# Usage
result = check_consent_status(
    identifier="urn:gov:ph:psa:national-id|PH-123456789",
    token=token,
    base_url="https://{your-domain}/api/v2/spp"
)

if result["status"] == "active":
    print(f"Consent active, scope: {result['scope']}")
    print(f"Data: {result['data']}")
elif result["status"] == "no_consent":
    print("No consent on file. Request consent from registrant.")
else:
    print(f"Consent status: {result['status']}")

Example: JavaScript#

async function checkConsentStatus(identifier, token, baseUrl) {
  const response = await fetch(`${baseUrl}/Individual/${identifier}`, {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  });

  const consentStatus = response.headers.get("X-Consent-Status");
  const consentScope = response.headers.get("X-Consent-Scope");

  const data = await response.json();

  return {
    status: consentStatus,
    scope: consentScope,
    data: data,
  };
}

// Usage
const result = await checkConsentStatus(
  "urn:gov:ph:psa:national-id|PH-123456789",
  token,
  "https://{your-domain}/api/v2/spp",
);

if (result.status === "active") {
  console.log(`Consent active, scope: ${result.scope}`);
} else if (result.status === "no_consent") {
  console.log("No consent on file");
}

Consent API Endpoints#

Note

Consent records are created and managed through the OpenSPP user interface, not via the API. The API provides read-only access to consent status and supports consent revocation.

Available Operations#

Operation

Endpoint

Description

Get Status

GET /Consent/{id}

Check consent status

Revoke

POST /Consent/{id}/$revoke

Revoke consent (GDPR Art 7.3)

Revoke (DELETE)

DELETE /Consent/{id}

Alternative revocation method

Receipt

GET /Consent/{id}/$receipt

Generate ISO 29184 receipt

History

GET /Consent/{id}/$history

View consent version history

Access Summary

GET /Consent/{id}/$access-summary

View data access logs

Get Consent Status#

GET /api/v2/spp/Consent/{consent-id}
Authorization: Bearer TOKEN

Response:

{
  "consent_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "given",
  "grantee": "Ministry of Agriculture",
  "effective_date": "2024-01-15",
  "expiry_date": "2025-06-30",
  "scopes": [
    {
      "resource_type": "individual",
      "field_access": "full",
      "purpose": "service_delivery",
      "include_extensions": true
    }
  ],
  "legal_basis": null
}

Revoke Consent#

POST /api/v2/spp/Consent/{consent-id}/$revoke
Authorization: Bearer TOKEN
Content-Type: application/json

{
  "reason": "Beneficiary requested revocation via support ticket #12345"
}

Response:

HTTP/1.1 200 OK

{
  "type": "Consent",
  "status": "revoked",
  "revokedDate": "2024-11-28T14:30:00Z",
  "revokedBy": {
    "reference": "User/admin",
    "display": "System Administrator"
  },
  "revocationReason": "Beneficiary requested revocation via support ticket #12345"
}

Consent Collection Methods#

When consent is created through the OpenSPP UI, the collection method is recorded:

Method

Description

written

Paper form with signature

verbal

Verbal consent (witnessed)

electronic

Digital signature, checkbox, etc.

implied

Implied by service request

Purpose Limitation#

Consent is purpose-specific. When created through the UI, administrators specify the purpose:

Purpose

Description

service_delivery

Delivering program benefits

eligibility_verification

Checking program eligibility

analytics

Anonymized statistics

research

Academic research

audit

Compliance audits

Security Design#

Consent Matching#

Consent can be granted in two ways:

  • Specific recipient: The registrant names your organization in the consent record

  • Category-based: The registrant consents to a category of organizations (e.g., "government health agencies"), and your API client's verified organization type matches

Enumeration Prevention#

The API applies random timing jitter (50-70ms) when returning consent-restricted responses. This prevents attackers from distinguishing between "resource not found" and "resource exists but no consent" based on response timing. Both cases return the same response structure with minimal data.

Handling Consent Errors#

403 Forbidden: Insufficient Consent#

HTTP/1.1 403 Forbidden

{
  "type": "urn:openspp:error:authorization",
  "title": "Forbidden",
  "status": 403,
  "detail": "No active consent for this data access"
}

Consent Scope Mismatch#

Requesting fields not covered by consent:

GET /api/v2/spp/Individual/...?_elements=identifier,name,telecom,address

With consent only for basic scope (identifier, name):

{
  "type": "Individual",
  "identifier": [...],
  "name": {...},
  "_consent": {
    "status": "active",
    "scope": "individual:basic",
    "message": "Requested fields 'telecom', 'address' not included in consent scope",
    "allowedFields": ["identifier", "name", "active"]
  }
}

Best Practices#

1. Always Check Consent Headers#

def fetch_with_consent_check(url, token):
    """Fetch data and handle consent status."""
    response = requests.get(url, headers={"Authorization": f"Bearer {token}"})
    response.raise_for_status()

    consent_status = response.headers.get("X-Consent-Status")

    if consent_status == "no_consent":
        print("Warning: No consent. Limited data returned.")
    elif consent_status == "expired":
        print("Warning: Consent expired. Limited data returned.")
    elif consent_status != "active":
        print(f"Warning: Consent status: {consent_status}")

    return response.json()

2. Request Only What You Need#

Don't request all fields if you only need basic info:

# ✅ Good - Request only needed fields
GET /api/v2/spp/Individual/...?_elements=identifier,name

# ❌ Bad - Request everything
GET /api/v2/spp/Individual/...

3. Handle Partial Data Gracefully#

Always check if expected fields are present:

individual = fetch_individual(identifier, token, base_url)

# ✅ Good - Check before accessing
if "telecom" in individual:
    phone = individual["telecom"][0]["value"]
else:
    phone = None  # Not consented

# ❌ Bad - Assume field exists
phone = individual["telecom"][0]["value"]  # May crash

4. Handle Expired Consent#

Check the X-Consent-Status header for expiration:

consent_status = response.headers.get("X-Consent-Status")

if consent_status == "expired":
    print("Warning: Consent has expired. Contact registrant for renewal.")
    # Limited data will be returned

5. Document Your Purpose#

Always specify why you're accessing data:

# In your application documentation
PURPOSE = "eligibility_verification"
PURPOSE_DESCRIPTION = "Checking eligibility for farmer subsidy program"

# Include in audit logs
logger.info(f"Accessing individual {identifier} for purpose: {PURPOSE}")

Complete Example#

import requests

class ConsentAwareClient:
    """API client with consent awareness."""

    def __init__(self, client_id, client_secret, base_url):
        self.base_url = base_url
        self.client_id = client_id
        self.token = None  # Implement token management

    def get_individual_with_consent(self, identifier):
        """Fetch individual with consent checking."""
        headers = {"Authorization": f"Bearer {self.token}"}
        response = requests.get(
            f"{self.base_url}/Individual/{identifier}",
            headers=headers
        )
        response.raise_for_status()

        # Check consent status from headers
        consent_status = response.headers.get("X-Consent-Status")
        consent_scope = response.headers.get("X-Consent-Scope")

        data = response.json()

        # Add consent metadata to response
        data["_consentInfo"] = {
            "status": consent_status,
            "scope": consent_scope,
        }

        # Warn if consent issues
        if consent_status == "no_consent":
            data["_consentInfo"]["warning"] = "No consent on file. Limited data returned."
        elif consent_status == "expired":
            data["_consentInfo"]["warning"] = "Consent has expired. Limited data returned."

        return data

    def revoke_consent(self, consent_id, reason=None):
        """Revoke a consent via API."""
        headers = {
            "Authorization": f"Bearer {self.token}",
            "Content-Type": "application/json"
        }

        payload = {"reason": reason} if reason else {}

        response = requests.post(
            f"{self.base_url}/Consent/{consent_id}/$revoke",
            headers=headers,
            json=payload
        )
        response.raise_for_status()
        return response.json()

# Usage
client = ConsentAwareClient(
    client_id="ministry-of-agriculture",
    client_secret="your-secret",
    base_url="https://{your-domain}/api/v2/spp"
)

# Fetch with consent checking
individual = client.get_individual_with_consent(
    "urn:gov:ph:psa:national-id|PH-123456789"
)

if individual["_consentInfo"]["status"] == "active":
    print(f"Full data available: {individual['name']['text']}")
elif individual["_consentInfo"]["status"] == "no_consent":
    print("Limited data. Consent must be obtained through OpenSPP UI.")

Common mistakes#

Getting only identifiers in responses?

This indicates no consent. Check the X-Consent-Status header. If no_consent, the registrant needs to provide consent through the OpenSPP user interface.

How do I know what fields are allowed?

Check the _consent.allowedFields array in responses with consent restrictions.

Can I bypass consent for emergencies?

If your API client has legal_basis: vital_interest, consent checks are relaxed. Contact your administrator to configure this.

Consent expired—what now?

The registrant must renew consent through the OpenSPP user interface. Contact your program administrator.

Can registrants revoke consent themselves?

Yes, through the beneficiary portal or mobile app. Your integration should handle revoked consent gracefully (you'll receive limited data).

What's next#

  • API Resources - Learn about available API resources

  • Search and Filtering - Advanced search capabilities

  • Error Handling - Error handling

  • Authentication - OAuth 2.0 setup

See also#

  • GDPR Principles - Data protection principles

  • G2P Connect: Consent - Consent in social protection

  • FHIR Consent Resource - FHIR consent model

previous

External Identifiers

next

API Resources

By The OpenSPP community
© Copyright OpenSPP.

The text and illustrations in this website are licensed by the OpenSPP Project under a Creative Commons Attribution 4.0 International license. All other trademarks are owned by their respective owners.