OpenCRVS
v1.5
v1.5
  • 👋Welcome!
  • CRVS Systems
    • Understanding CRVS
    • Effective digital CRVS systems
    • OpenCRVS within a government systems architecture
    • OpenCRVS Value Proposition
  • Product Specifications
    • Functional Architecture
    • Workflow management
    • Status Flow Diagram
    • Users
      • Examples
    • Core functions
      • 1. Notify event
      • 2. Declare event
      • 3. Validate event
      • 4. Register event
      • 5. Print certificate
      • 6. Issue certificate
      • 7. Search for a record
      • 8. View record
      • 9. Correct record
      • 10. Verify record
      • 11. Archive record
      • 12. Vital statistics export
    • Support functions
      • 13. Login
      • 14. Audit
      • 15. Deduplication
      • 16. Performance management
      • 17. Payment
      • 18. Learning
      • 19. User support
      • 20. User onboarding
    • Admin functions
      • 21. User management
      • 22. Comms management
      • 23. Content management
      • 24. Config management
    • Data functions
      • 25. Legacy data import
      • 26. Legacy paper import
  • Technology
    • Architecture
      • Performance tests
    • Standards
      • FHIR Documents
        • Event Composition
        • Person
        • Registration Task
        • Event Observations
        • Locations
    • Security
    • Interoperability
      • Create a client
      • Authenticate a client
      • Event Notification clients
      • Record Search clients
      • Webhook clients
      • National ID client
      • FHIR Location REST API
      • Other ways to interoperate
  • Default configuration
    • Intro to Farajaland
    • Civil registration in Farajaland
    • OpenCRVS configuration in Farajaland
      • Application settings
      • User / role mapping
      • Declaration forms
      • Certificate templates
    • Business process flows in Farajaland
  • Setup
    • 1. Planning an OpenCRVS Implementation
    • 2. Establish project and team
    • 3. Gather requirements
      • 3.1 Mapping business processes
      • 3.2 Mapping offices and user types
      • 3.3 Define your application settings
      • 3.4 Designing event declaration forms
      • 3.5 Designing a certificate template
    • 4. Installation
      • 4.1 Set-up a local development environment
        • 4.1.1 Install the required dependencies
        • 4.1.2 Install OpenCRVS locally
        • 4.1.3 Starting and stopping OpenCRVS
        • 4.1.4 Log in to OpenCRVS locally
        • 4.1.5 Tooling
          • 4.1.5.1 WSL Support
      • 4.2 Set-up your own, local, country configuration
        • 4.2.1 Fork your own country configuration repository
        • 4.2.2 Set up administrative address divisions
          • 4.2.2.1 Prepare source file for administrative structure
          • 4.2.2.2 Prepare source file for statistics
        • 4.2.3 Set up CR offices and Health facilities
          • 4.2.3.1 Prepare source file for CRVS Office facilities
          • 4.2.3.2 Prepare source file for health facilities
        • 4.2.4 Set up employees & roles for testing or production
          • 4.2.3.1 Prepare source file for employees
          • 4.2.3.2 Configure role titles
        • 4.2.5 Set up application settings
          • 4.2.5.1 Managing language content
            • 4.2.5.1.1 Informant and staff notifications
          • 4.2.5.2 Configuring Metabase Dashboards
        • 4.2.6 Configure certificate templates
        • 4.2.7 Configure declaration forms
          • 4.2.7.1 Configuring an event form
        • 4.2.8 Seeding & clearing your local databases
        • 4.2.9 Countryconfig API endpoints explained
      • 4.3 Set-up a server-hosted environment
        • 4.3.1 Verify servers & create a "provision" user
        • 4.3.2 TLS / SSL & DNS
          • 4.3.2.1 LetsEncrypt https challenge in development environments
          • 4.3.2.2 LetsEncrypt DNS challenge in production
          • 4.3.2.3 Static TLS certificates
        • 4.3.3 Configure inventory files
        • 4.3.4 Create a Github environment
          • 4.3.4.1 Environment secrets and variables explained
          • 4.3.4.2 VPN Recipes
        • 4.3.5 Provisioning servers
          • 4.3.5.1 SSH access
          • 4.3.5.2 Building, pushing & releasing your countryconfig code
          • 4.3.5.3 Ansible tasks when provisioning
        • 4.3.6 Deploy
          • 4.3.6.1 Running a deployment
          • 4.3.6.2 Seeding a server environment
          • 4.3.6.3 Login to an OpenCRVS server
          • 4.3.6.5 Resetting a server environment
        • 4.3.7 Backup & Restore
          • 4.3.7.1 Restoring a backup
          • 4.3.7.2 Off-boarding from OpenCRVS
    • 5. Functional configuration
      • 5.1 Configure application settings
      • 5.2 Configure registration periods and fees
      • 5.3 Managing system users
    • 6. Quality assurance testing
    • 7. Go-live
      • 7.1 Pre-Deployment Checklist
    • 8. Operational Support
    • 9. Monitoring
      • 9.1 Application logs
      • 9.2 Infrastructure health
      • 9.3 Routine monitoring checklist
      • 9.4 Setting up alerts
      • 9.5 Managing a Docker Swarm
  • General
    • Community
    • Contributing
    • Releases
      • v1.5.1: Release notes
      • v1.5.0: Release notes
      • v1.4.1: Release notes
      • v1.4.0 to v1.4.1 Migration notes
      • v1.4.0 Release notes
      • v1.3.* to v1.4.* Migration notes
      • v1.3.5: Release notes
      • v1.3.4: Release notes
      • v1.3.3: Release notes
      • v1.3.1: Release notes
      • v1.3.0: Release notes
      • v1.2.1: Release notes
      • Patch: Elasticsearch 7.10.2
      • v1.2.0: Release notes
      • v.1.1.2: Release notes
      • v.1.1.1: Release notes
      • v1.1.0: Release notes
    • Roadmap
Powered by GitBook
On this page
  • Creating a subscriber endpoint
  • Subscription process
  1. Technology
  2. Interoperability

Webhook clients

Business functionality and API endpoints available to a "Webhook" client.

PreviousRecord Search clientsNextNational ID client

OpenCRVS publishes the following civil registration events as webhooks that clients can subscribe to. This is particularly useful for e-Gov systems if you wish to initiate business functionality for a citizen at the moment a Birth or Death is officially registered.

  • Birth registration

  • Death registration

Included in these webhooks is a FHIR Resource type and unique ID to the OpenCRVS resource associated and customisable demographics, attachments and links to biometric data for the registration in a SHA signed and encrypted payload.

Subscribing to an OpenCRVS webhook requires you to develop a service that exposes the standardised and required webhook endpoints associated with the pattern.

Any service that subscribes to an OpenCRVS webhook must:

  1. Expose endpoints on a secure server that can process HTTPS requests and respond to a webhook following the pattern.

  2. Authenticate and query OpenCRVS to find a list of available event webhooks.

  3. Authenticate and subscribe to the webhook of choice.

  4. Respond to the webhook event as you wish internally, and request further details from OpenCRVS via a if you need to.

You can use our to test webhook API functionality. is a tool you can download to test API access before building your integrations.

As an example 3rd party webhook client service, we have written that subscribes to a birth registration webhook and retrieves the data required by to register a national ID in MOSIP at the moment a Birth is registered. This medator only works for a National ID client explained later, but you can refer to the code to replicate the sequence diagrams below regarding subscribing and handling webhooks.

Creating a subscriber endpoint

Your mediator must be able to process two types of HTTPS requests:

  • Verification Requests

  • Webhook Events.

Since both requests use HTTPs your server must have a valid TLS or SSL certificate correctly configured and installed.

The following sections explain what will be in each type of request to these endpoints and how to respond to them.

Verification Requests

Anytime you try to subscribe to a webhook, OpenCRVS will send a GET request to this endpoint URL to confirm that your mediator is prepared to receive webhook events.

Sample:

  GET https://www.your-clever-domain-name.com/webhooks?
  mode=subscribe&
  challenge=&
  topic=BIRTH_REGISTERED
Parameter
Sample value
Description

mode

subscribe

This value will always be set to subscribe

challenge

1158201444

A random cryptographic string that you must pass back to OpenCRVS

topic

BIRTH_REGISTERED

A supported OpenCRVS event type string that will trigger this webhook

Note: The supported events and associated topic strings are explained later in this document when studying the subscription process.

Validating Verification Requests

Whenever your endpoint receives a verification request, it must:

Verify that the topic value matches the event you're trying to subscribe to. Respond with the following object:

{
    "challenge": "1158201444"
}

Webhook Events

Whenever there's a a new event created, we will send your endpoint a POST request with a JSON payload. When you create or edit a webhook client, you select the data you wish to be contained in the payload using the checkboxes.

For example, if you subscribed to the birth registration event, we would send you a POST request to the same URL as the Verification request URL that would look something like this depending on what content you configured in the screen above:

POST / HTTPS/1.1
Content-Type: application/json
X-Hub-Signature: sha1={super-long-SHA1-signature}

{
  "payload": {
    "id": "531e9275-40e4-4ab5-a12c-6fa74d7b5b61",
    "timestamp": "2019-12-12T10:53:43-08:00",
    "event": {
      "hub": {
        "topic": "BIRTH_REGISTERED"
      },
      "context": [
        {
          "resourceType": "Bundle",
          "entry": [
            {
              "resource": {
                "resourceType": "Task",
                "status": "requested",
                "code": {
                  "coding": [
                    {
                      "system": "http://opencrvs.org/specs/types",
                      "code": "BIRTH"
                    }
                  ]
                },
                "focus": {
                  "reference": "Composition/e9e2ff8d-1eac-412b-8bbc-408e90276a3f"
                },
                "identifier": [
                  {
                    "system": "http://opencrvs.org/specs/id/draft-id",
                    "value": "53fe6974-6140-4e50-afc7-998a9018709b"
                  },
                  {
                    "system": "http://opencrvs.org/specs/id/birth-tracking-id",
                    "value": "B6E6YJB"
                  },
                  {
                    "system": "http://opencrvs.org/specs/id/birth-registration-number",
                    "value": "2020B6E6YJB"
                  }
                ],
                "extension": [
                  {
                    "url": "http://opencrvs.org/specs/extension/contact-person",
                    "valueString": "MOTHER"
                  },
                  {
                    "url": "http://opencrvs.org/specs/extension/contact-relationship",
                    "valueString": ""
                  },
                  {
                    "url": "http://opencrvs.org/specs/extension/contact-person-phone-number",
                    "valueString": "+260965656563"
                  },
                  {
                    "url": "http://opencrvs.org/specs/extension/timeLoggedMS",
                    "valueInteger": 52942
                  },
                  {
                    "url": "http://opencrvs.org/specs/extension/regLastUser",
                    "valueReference": {
                      "reference": "Practitioner/c3355b48-7790-43c7-b8f0-10c7316f9bed"
                    }
                  },
                  {
                    "url": "http://opencrvs.org/specs/extension/regLastLocation",
                    "valueReference": {
                      "reference": "Location/1b4092e0-d391-45cd-89d4-162a81f0f63f"
                    }
                  },
                  {
                    "url": "http://opencrvs.org/specs/extension/regLastOffice",
                    "valueReference": {
                      "reference": "Location/4ec9c980-0b2f-436a-b49e-203e1e601620"
                    }
                  }
                ],
                "lastModified": "2020-09-27T09:15:20.015Z",
                "businessStatus": {
                  "coding": [
                    {
                      "system": "http://opencrvs.org/specs/reg-status",
                      "code": "REGISTERED"
                    }
                  ]
                },
                "meta": {
                  "lastUpdated": "2020-09-27T09:15:20.040+00:00",
                  "versionId": "cfbefeac-bda0-4339-9745-9d54e7816c7d"
                },
                "id": "60ec435c-1370-4314-ab0b-f44507f0db24"
              }
            },
            {
              "resource": {
                "resourceType": "Patient",
                "active": true,
                "name": [
                  { "use": "en", "given": ["esrgstg"], "family": ["srthsrt"] }
                ],
                "gender": "male",
                "birthDate": "2019-12-23",
                "multipleBirthInteger": 1,
                "meta": {
                  "lastUpdated": "2020-09-27T09:15:20.166+00:00",
                  "versionId": "9f5f1a5e-7059-4f5b-bf2f-8aa4f641b37c"
                },
                "id": "1e9ca16b-7c9a-469d-8101-ddd0db229077",
                "identifier": [
                  {
                    "type": "BIRTH_REGISTRATION_NUMBER",
                    "value": "2020B6E6YJB"
                  }
                ]
              }
            },
            {
              "resource": {
                "resourceType": "DocumentReference",
                "masterIdentifier": {
                  "system": "urn:ietf:rfc:3986",
                  "value": "d3240515-3d90-4f1a-bbb6-6530477565bd"
                },
                "status": "current",
                "content": [
                  {
                    "attachment": {
                      "contentType": "image/png",
                      "data": "data:image/png;base64,iVBORw0KJLX..."
                    }
                  }
                ],
                "type": {
                  "coding": [
                    {
                      "system": "http://opencrvs.org/specs/supporting-doc-type",
                      "code": "NATIONAL_ID_FRONT"
                    }
                  ]
                },
                "subject": { "display": "MOTHER" },
                "meta": {
                  "lastUpdated": "2020-09-27T09:15:20.042+00:00",
                  "versionId": "0307d10f-f2c1-42be-a0d3-b09c268a38cf"
                },
                "id": "bf503f30-1d0a-40dc-908f-9c0d5e9cdf23"
              }
            }
          ]
        }
      ]
    }
  },
  "url": "",
  "hmac": "sha256=1d51fb6d-8636abe2-affb-4238-8bff-200ed3652d1et-dhrhd55"
}

Parameter
Sample value
Description

payload.id

531e9275-40e4-4ab5-a12c-6fa74d7b5b61

The unique id for this webhook. Helpful when debugging.

payload.timestamp

2019-12-12T10:53:43-08:00

A timestamp identifying the time that the webhook was created

payload.event.hub.topic

BIRTH_REGISTERED

A supported OpenCRVS event type string that triggered this webhook.

payload.event.context

[{ ... }]

url

https://www.your-clever-domain-name.com/webhooks

The URL that is notified by this webhook

hmac

sha256=d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f

The request signature that is created using your sha_secret explained below.

Validating Payloads

We encrypt the payload using your client's sha_secret in an SHA256 signature hash and include the hash in the request's hmac property, preceded with sha256=.

You must confirm that the data is genuinely received from OpenCRVS and not from a malicious man-in-the-middle by using the sha_secret in this way

To validate the payload in a similar way to our method:

Generate a SHA256 signature using the context array contents at position [0] as the rawBody . signingSecret is your OpenCRVS sha_secret, available to you as an environment variable and generated via the register step. requestSigningVersion is "sha256" Compare your signature to the hmac prop. If the signatures match, the payload is genuine.

Please note that we generate the signature using an escaped unicode version of the payload, with lowercase hex digits. If you just calculate against the decoded bytes, you will end up with a different signature. For example, the string äöå should be escaped to \u00e4\u00f6\u00e5.

Responding to Webhook Events

Your endpoint should respond to all events with 200 OK HTTPS.

Frequency: Be sure to adjust your servers to handle each Webhook individually and at any time.

Subscription process

Firstly, ensure that you have correctly configured your subscriber endpoint above to respond to Verification Requests and Webhook Events.

With the token you can now perform the following actions:

List webhook subscribers

This API returns all clients that are subscribed to receive webhook notifications.

URL

GET https://webhooks.<your_domain>/webhooks

Request headers

Content-Type: application/json
Authorization: Bearer <token>

Response payload

Example json

{
  "entries": [
    {
        "id": "531e9275-40e4-4ab5-a12c-6fa74d7b5b61",
        "callback": "https://www.your-clever-domain-name.com/webhooks",
        "createdAt": "2019-12-12T10:53:43-08:00",
        "createdBy": {
            "client_id": "8636abe2-affb-4238-8bff-200ed3652d1e",
            "type": "api",
            "username": "sys.admin",
            "name": "Jonathan Campbell"
        }
        "topic": "BIRTH_REGISTERED"
    }
  ]
}

Subscribe to a webhook

This API subscribes a client service to an OpenCRVS webhook using a supported OpenCRVS event type string as a trigger.

URL

POST https://webhooks.<your-open-crvs-host.com>/webhooks

Request headers

Content-Type: application/json
Authorization: Bearer <token>

Request payload

{
    "hub": {
        "callback": "https://www.your-clever-domain-name.com/webhooks",
        "mode": "subscribe",
        "topic": "BIRTH_REGISTERED",
        "secret": "d04aec67-1ef4-467a-a5a8-fa5c89ad71ce"
    }

}

Parameters contained within the hub object:

Parameter
Sample value
Description

callback

https://www.your-clever-domain-name.com/webhooks

The URL address that will be requested when the event occurs.

mode

subscribe

Always set to subscribe for this action.

topic

BIRTH_REGISTERED

A supported OpenCRVS event type string that will trigger this webhook.

secret

d04aec67-1ef4-467a-a5a8-fa5c89ad71ce

The supported events and associated topic string:

Webhook event
trigger

Birth registration

BIRTH_REGISTERED

Death registration

DEATH_REGISTERED

Response payload

The subscribe process will test the authenticity of the sha_secret and additionally make a test GET request to the Verification Request

Provided all is successfully completeed, your webhook will be subscribed and you will receive a 202 status code and empty response.

Unsubscribe to a webhook

This API unsubscribes a client service to an OpenCRVS webhook using the webhook id.

You may notice that as of OpenCRVS v1.2.*, webhook clients have the ability to unsubscribe themselves or other webhook clients to webhook events. In this version of OpenCRVS it is assumed that all webhooks created by the system administrator can be trusted not to interfere with each other's subscriptions.

URL

DELETE https://webhooks.<your-open-crvs-host.com>/webhooks/<your-webhook-id>

Request headers

Content-Type: application/json
Authorization: Bearer <token>

Response

204 status code and an empty response will be returned when the webhook has been successfully deleted.

The property context contains the FHIR bundles. Refer to our section to learn more about the FHIR specification.

The bundle associated with the target of this webhook.

This shows how we create the signature to help you understand how you might create a similar hash and compare them.

Unacknowledged responses are retried according to the capabilities of our library used .

To subscribe, your subscription service must request an using your client_id and client_secret.

Your OpenCRVS sha_secret, available to you via the mediator step.

W3C WebSub
WebSub
Record Search
Postman collections
Postman
this mediator
MOSIP - the Modular Open Source Identity Platform
standards
method
bullmq
authorization token
FHIR resources
register