Record Search clients

Perform an advanced search of civil registration records from a trusted, external e-Gov service

The Record Search client can perform an advanced search of civil registration records. Use this to help support social protection systems, check the existence of civil registration records or check citizen demographics.

To stop abuse of such a powerful API, all results returned are audited as having been downloaded by the client. System Administrators should be careful to ensure that citizen data is not exposed to untrustworthy individuals by using this API.

All client behaviour is audited and is ultimately the personal responsibility of the National System Administrator of OpenCRVS that created the client. Protect citizen data and do not expose it unnecessarily as you may be in breach of local laws.

A daily limit of 2000 Record Search requests per client, per day is hardcoded into OpenCRVS Core. Any subsequent requests will fail.

You can use our Postman collections to test Record Search API functionality. Postman is a tool you can download to test API access before building your integrations.

Submitting a Record Search

To submit an Record Search, your client must first request an authorization token using your client_id and client_secret.

Record Search Requests

With the token as an authorization header, the following example request will submit a record search in GraphQL. GraphQL is the chosen protocol as this API re-uses the same Advanced Search GraphQL queries that are used buy the OpenCRVS GUI.

You can browse to the GraphQL Playground using an authorization header to view the full documentation for the searchEvents GraphQL query.

https://gateway.your_domain/graphql

The GraphQL parameters are explained below. A full list of available Advanced Search GraphQL variables is also explained below.

POST https://gateway.<your_domain>/graphql
Content-Type: application/json
Authorization: Bearer {{token}}

{
  "operationName": "searchEvents",
  "query": "query searchEvents($advancedSearchParameters: AdvancedSearchParametersInput!, $sort: String, $count: Int, $skip: Int) {\nsearchEvents(\n  advancedSearchParameters: $advancedSearchParameters\n  sort: $sort\n  count: $count\n  skip: $skip\n) {\n  totalItems\n  results {\n    id\n    type\n    registration {\n      status\n      contactNumber\n      trackingId\n      registrationNumber\n      registeredLocationId\n      duplicates\n      assignment {\n        userId\n        firstName\n        lastName\n        officeName\n        __typename\n      }\n      createdAt\n      modifiedAt\n      __typename\n    }\n    operationHistories {\n      operationType\n      operatedOn\n      operatorRole\n      operatorName {\n        firstNames\n        familyName\n        use\n        __typename\n      }\n      operatorOfficeName\n      operatorOfficeAlias\n      notificationFacilityName\n      notificationFacilityAlias\n      rejectReason\n      rejectComment\n      __typename\n    }\n    ... on BirthEventSearchSet {\n      dateOfBirth\n      childName {\n        firstNames\n        familyName\n        use\n        __typename\n      }\n      __typename\n    }\n    ... on DeathEventSearchSet {\n      dateOfDeath\n      deceasedName {\n        firstNames\n        familyName\n        use\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n  __typename\n}}",  
  "variables": {"advancedSearchParameters": {
      "event": "birth",
      "registrationStatuses": ["REGISTERED"],
      "childGender": "male",
      "dateOfRegistrationEnd": "2022-12-31T23:59:59.999Z",
      "dateOfRegistrationStart": "2021-11-01T00:00:00.000Z",
      "declarationJurisdictionId": "576uyegf7 .... ", // A FHIR Location ID for an admin level
      "eventLocationId": "aaabuifr87h ...", // A FHIR Location ID for a health facility where the birth or death took place
      "fatherFirstNames": "Dad",
      "motherFirstNames": "Mom"
    },
    "count": 10,
    "skip": 0
  }
}

GraphQL Parameters

GraphQL variables.advancedSearchParameters object

We recommend that you use the Advanced Search feature in the OpenCRVS application and monitor the GraphQL payload that is sent to the Gateway using the Chrome Developer Tools "Network" tab, in order to understand how these parameters are formatted. The table below lists all possible parameters with a description and example where we feel further explanation is helpful.

Record Search Response

The response from a record search is not FHIR, but an Elasticsearch response. The audit experience is explained below the example payload.

{
  "data": {
    "searchEvents": {
      "totalItems": 3,
      "results": [
        {
          "id": "cb813494-9339-48dd-85a1-156278436f30",
          "type": "Birth",
          "registration": {
            "status": "CERTIFIED",
            "contactNumber": "+260760001907",
            "trackingId": "BHKTHM7",
            "registrationNumber": "2023BHKTHM7",
            "registeredLocationId": "712502d2-5ea2-49d9-86df-a7d61f3f351f",
            "duplicates": null,
            "assignment": null,
            "createdAt": "1673047650433",
            "modifiedAt": null,
            "__typename": "RegistrationSearchSet"
          },
          "operationHistories": [ ... ],
          "dateOfBirth": "2022-10-26",
          "childName": [
            {
              "firstNames": "Santiago",
              "familyName": "Schmeler",
              "use": "en",
              "__typename": "HumanName"
            },
            {
              "firstNames": "",
              "familyName": null,
              "use": "fr",
              "__typename": "HumanName"
            }
          ],
          "__typename": "BirthEventSearchSet"
        },
        {
          "id": "b2fd5270-49c1-4227-8625-d874b6eef25d",
          "type": "Birth",
          "registration": {
            "status": "CERTIFIED",
            "contactNumber": "+260754288799",
            "trackingId": "BBPX0DM",
            "registrationNumber": "2023BBPX0DM",
            "registeredLocationId": "712502d2-5ea2-49d9-86df-a7d61f3f351f",
            "duplicates": null,
            "assignment": null,
            "createdAt": "1673048958068",
            "modifiedAt": null,
            "__typename": "RegistrationSearchSet"
          },
          "operationHistories": [ ... ],
          "dateOfBirth": "2022-08-31",
          "childName": [
            {
              "firstNames": "Price",
              "familyName": "Lind",
              "use": "en",
              "__typename": "HumanName"
            },
            {
              "firstNames": "",
              "familyName": null,
              "use": "fr",
              "__typename": "HumanName"
            }
          ],
          "__typename": "BirthEventSearchSet"
        },
        {
          "id": "a7c641cb-9671-4715-a1a4-ecee08def9b0",
          "type": "Birth",
          "registration": {
            "status": "CERTIFIED",
            "contactNumber": "+260751978586",
            "trackingId": "BXZJNML",
            "registrationNumber": "2023BXZJNML",
            "registeredLocationId": "712502d2-5ea2-49d9-86df-a7d61f3f351f",
            "duplicates": null,
            "assignment": null,
            "createdAt": "1673062235276",
            "modifiedAt": null,
            "__typename": "RegistrationSearchSet"
          },
          "operationHistories": [ ... ],
          "dateOfBirth": "2021-12-11",
          "childName": [
            {
              "firstNames": "Nash",
              "familyName": "Cruickshank",
              "use": "en",
              "__typename": "HumanName"
            },
            {
              "firstNames": "",
              "familyName": null,
              "use": "fr",
              "__typename": "HumanName"
            }
          ],
          "__typename": "BirthEventSearchSet"
        }
      ],
      "__typename": "EventSearchResultSet"
    }
  }
}

After a search has completed and if you search for any record returned, you will see that in Record Audit, an entry shows that this client has accessed the personally identifiable citizen data on the record.