SG-Verify API (2.0.2)

Download OpenAPI specification:Download

API Specifications for implementing Callback for SG-Verify service and retrieving Person data from SG-Verify REST APIs.

Note - this specification is subject to changes based on evolution of the APIs.

Release Notes

  • 2.0.2 (3 Nov 2022)

    • Data Items
      • Updated:
        • Description of 'Nationality' updated to 'Nationality/Citizenship'
        • Description of Country updated to 'Country/Place'
    • Operation
      • Updated:
        • Downtime
  • 2.0.1 (09 Dec 2020)

    • Update of Certificate Authority list
      • Comodo to Comodo/Sectigo
      • New CA: Netrust
    • Updated TLS version to only 1.2
    • Updated recommended cipher suites
    • Updated the SG-Verify QR URL to app.singpass.gov.sg
  • 2.0.0 (04 Nov 2019)

    • SG-Verify will send authorisation code to partner's callback url.
    • Added Token & Person API
  • 1.0.1 (02 Sept 2019)

    • Deprecated homeno & mailadd attribute
  • 1.0.0 (01 July 2019)

    • initial draft

Releases and Compatibility

The RESTful API adopts Semantic Versioning 2.0.0 for releases, and every new release of the API increments the version numbers in the following format:

{MAJOR}.{MINOR}.{PATCH}
  1. {MAJOR} number introduces incompatible API changes with previous {MAJOR} number also resets {MINOR} to 0,
  2. {MINOR} number introduces new functionalities or information that are backward compatible also resets {PATCH} to 0, and
  3. {PATCH} number introduces bug fixes and remains backward compatible.

Pre-release or draft versions, when provided, are denoted by appended hypen - with a series of separate identifiers {LABEL}-{VERSION} following the {PATCH} number. Such releases are unstable and may not provide the intended compatibility with the specification in draft status.

Serving as notice, the RESTful API in version 2.X.X are incompatible with version 1.X.X releases.

Despite backward compatibility in {MINOR} or {PATCH} releases, API consumers are best to evaluate and determine their implementation does not disrupt use-case requirements.

Overview

SG-Verify is a service provided by SingPass Mobile that allows easy sharing of customer basic personal information to an organization.

How Does SG-Verify Work?

The diagram below shows a logical overview of the architecture:

Overview

  1. The user scans QR code at digital service's kiosk using SingPass mobile app.
  2. The user provides consents to share personal information with digital service's kiosk.
  3. SingPass mobile send authorisation code to digital service's callback URL.
  4. Exchange data between SG Verify and digital service using authorisation code.
  5. Digital service updates kiosk to display the name of the user.

NOTE: As shown above, your application needs to implement your callback URL according to the specification to integrate successfully with SG-Verify.

Environments

The RESTful APIs are provided in both testing and live environments, and are accessible over the Internet via HTTPS.

Consumers are to ensure firewall clearance on their edge network nodes for connecting to the APIs.

The convention used by API endpoints' URLs is in the following format:

https://{ENV_DOMAIN_NAME}/{CONTEXT}/{VERSION}/{RESOURCE}
  • {ENV_DOMAIN_NAME} indicates SG-Verify's API domain names - respectively:

    • sandbox.api.myinfo.gov.sg, or
    • test.api.myinfo.gov.sg, or
    • api.myinfo.gov.sg, following
  • /{CONTEXT}, indicates the context of the API call = /sgverify

  • /{VERSION} indicates the endpoint's release {MAJOR} version number path - for this release = /v2

  • /{RESOURCE} indicates the API resource path name. Any additional query string parameters are appended as needed.

Available Environments

1. Sandbox Environment

The sandbox environment is used for your testing when developing your prototype. The Person API will return test data described in https://api.singpass.gov.sg/library/verify/developers/resources-personas.

Note:

  • Domain Name: sandbox.api.myinfo.gov.sg
  • PKI digital signature is not required for all APIs.
  • Authorization Bearer access token is required in Person API.

2. Test Environment

The test enviroment is used for testing your application with the full security measures required in production. The Person API will return test data described in https://api.singpass.gov.sg/library/verify/developers/resources-personas.

Note:

  • Domain Name: test.api.myinfo.gov.sg
  • PKI digital signature is required for Token and Person APIs.
    Refer to Security > Request Signing for the steps to sign your request.
  • Authorization Bearer access token is required in Person API.

3. Production Environment

The production enviroment is the actual live environment with full security measures and live data.

Note:

  • Domain Name: api.myinfo.gov.sg
  • PKI digital signature is required for Token and Person APIs.
    Refer to Security > Request Signing for the steps to sign your request.
  • Authorization Bearer access token is required in Person API.

Scheduled Downtimes

The following are the scheduled downtimes for the various environments:

Production Environment

  • CPFB data

    • Everyday 5:00am to 5:30am
    • Every 1st Sun of the month from 12:00am to 8:00am
    • Every last Sn of the month from 12:00am to 8:00am
  • IRAS data

    • Every Wed, 2:00am to 6:00am
    • Every Sun, 2:00am to 8:30am
  • MOM data

    • Every 4th Sun of the month from 12:00am to 6:00am

Test Environment

  • none

Sandbox Environment

  • none

Security

HTTPS Interface

SG-Verify's API gateway supports accessing of APIs via the following interfaces:

  • HTTP version 1.1 connection over TLS (Transport Layer Security) version 1.2 standards, and cipher suites:

    • using AES (Advanced Encryption Standard) and SHA (Secure Hash Algorithm),
    • on either GCM (Galois/Counter Mode) or CBC (Cipher Block Chaining) mode.
  • Below is the list of recommended cipher suites that you may use:

    • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

IMPORTANT: ensure your server supports TLS 1.2 and supports a cipher suite in the list above.

OAuth2.0

SG-Verify APIs use OAuth2.0 authorisation code flow to perform authentication & authorisation.

The sequence diagram below illustrates the steps involved in integrating your application with our APIs:

OAuth

The flow consists of 3 APIs:

  1. Authorise

    • After the authentication, SPM will trigger the Authorise API and load the consent. Once user gives consent, your application will receive the authorisation code via your callback url.
  2. Token

    • Call this server-to-server API with a valid authorisation code to get the access token.
  3. Protected Resource (Person)

    • Call this server-to-server API with a valid access token to get the person data.

Application Authentication

Access to all server-to-server APIs will be authenticated by SG-Verify's API gateway.

Prior to implementing your callback or calling the APIs, respective consumers are required to have:

  • approval of access, onboarding process for the required API resources will be provisioned, and
  • authentication credentials are then supplied and exchanged.

Authentication methods provided by SG-Verify's API gateway on internet:

  • OAuth 2.0 using RS256 digital signature (see "Request Signing" section below)
  • Digital signature should be produced using a RSA private key with corresponding public certificate issued by one of the following compatible CAs:
    • Comodo/Sectigo
    • digiCert
    • Entrust
    • GeoTrust
    • GlobalSign
    • Netrust
    • Thawte
    • VeriSign

Request Signing

NOTE: Test and Production Environments only

All server-to-server API requests are to be digitally signed, by including the following parameters and values in the Authorization header:

PKI_SIGN app_id="{app_id}",
nonce="{random_nonce}",
signature_method="RS256",
signature="{base64_url_percent_encoded_signature}",
timestamp="{unix_epoch_in_milliseconds}"

Note: Above sample is separated by lines for ease-of-reading, and new-line denotations are to be omitted in the actual request.

  • {app_id} is the APP ID credential supplied upon onboarding,

  • {random_nonce} is an unique randomly generated text used for replay prevention,

  • {signature_method} is the signature algorithm of the authenticating gateway.

    • Value of signature_method = RS256
  • {base64_url_percent_encoded_signature} is the binary of the generated signature encoded in Base64 URL-safe format,

  • {unix_epoch_in_milliseconds} is the UNIX epoch time in milliseconds

Sample header with authorization parameters

Below is an example of an Authorization header for the sample application. Make sure you list the parameters in the sequence shown below.

  Authorization: PKI_SIGN
  app_id="STG2-SGVERIFY-SELF-TEST",
  nonce="150590021034800",
  signature_method="RS256",
  signature="EEm+HEcNQajb5FkVd82zjojk+daYZXxSGPCOR2GHZeoyjZY1PK+aFMzHfWu7eJZYMa5WaEwWxdOdq5hjNbl8kHD7bMaOks7FgEPdjE++TNomfv7SMktDnIvZmPYAxhjb/C9POU2KT6tSlZT/Si/qMgD1cryaPwSeMoM59UZa1GzYmqlkveba7rma58uGwb3wZFH0n57UnouR6LYXDOOLkqi8uMZBuvRUvSJRXETAj2N0hT+4QJiN96Ct6IEQh/woZh0o74K5Ol9PpDSM08qC7Lj6N/k694J+hbBQVVviGn7/6mDkfbwdMDuoKs4t7NpqmAnwT+xaQSIZcexfrAVQYA==",
  timestamp="1505900210349"

Sample Code in NodeJS

  // generates the security headers for calling API gateway
  function generateAuthorizationHeader(url, params, method, strContentType, authType, appId, keyCertContent, passphrase) {

    if (authType == "L2") {
      return generateRS256Header(url, params, method, strContentType, appId, keyCertContent, passphrase);
    } else {
      return "";
    }
  };

  // Signing Your Requests
  function generateRS256Header(url, params, method, strContentType, appId, keyCertContent, keyCertPassphrase) {
    var nonceValue = nonce();
    var timestamp = (new Date).getTime();

    // A) Construct the Authorisation Token Parameters
    var defaultAuthHeaders = {
      "app_id": appId, // App ID assigned to your application
      "nonce": nonceValue, // secure random number
      "signature_method": "RS256",
      "timestamp": timestamp // Unix epoch time
    };

    // B) Forming the Base String
    // Base String is a representation of the entire request (ensures message integrity)

    // i) Normalize request parameters
    var baseParams = sortJSON(_.merge(defaultAuthHeaders, params));

    var baseParamsStr = qs.stringify(baseParams);
    baseParamsStr = qs.unescape(baseParamsStr); // url safe

    // ii) concatenate request elements (HTTP method + url + base string parameters)
    var baseString = method.toUpperCase() + "&" + url + "&" + baseParamsStr;

    // C) Signing Base String to get Digital Signature
    var signWith = {
      key: fs.readFileSync(keyCertContent, 'utf8')
    }; // Provides private key

    // Load pem file containing the x509 cert & private key & sign the base string with it to produce the Digital Signature
    var signature = crypto.createSign('RSA-SHA256')
      .update(baseString)
      .sign(signWith, 'base64');

    // D) Assembling the Authorization Header
    var strAuthHeader = "PKI_SIGN app_id=\"" + appId + // Defaults to 1st part of incoming request hostname
      "\",timestamp=\"" + timestamp +
      "\",nonce=\"" + nonceValue +
      "\",signature_method=\"RS256\"" +
      ",signature=\"" + signature +
      "\"";

    return strAuthHeader;
  };

Token Validation

NOTE: Person APIs only

Access Tokens are in JWT format. This JWT complies to the standard 'JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants' (https://tools.ietf.org/html/rfc7523). You will need to verify the token with our public cert (provided during application onboarding).

Sample Code in NodeJS

  // Sample Code for Verifying & Decoding JWS or JWT
  function verifyJWS(jws, publicCert) {
    // verify token
    // ignore notbefore check because it gives errors sometimes if the call is too fast.
    try {
      var jwspayload = jwt.verify(jws, fs.readFileSync(publicCert, 'utf8'), {
        algorithms: ['RS256'],
        ignoreNotBefore: true
      });
      return jwspayload;
    }
    catch(error) {
      throw("Error with verifying and decoding JWS");
    }
  }

Payload Signing and Encryption (Person)

NOTE: Person APIs in Test and Production environments only

The response payload for the Person API (for test and production environments) is first signed, then encrypted:

Encryption protects the data at rest while a signed payload means, if necessary, you will be able to pass this signed payload to a 3rd party where they can verify the payload's integrity with our public certificate.

In order to read the payload, you have to perform the following steps in order:

  1. Decrypt the payload with your application's private key.
  2. Validate the decrypted payload signature with our public key.

After doing the above steps, your application will be able to extract the payload in JSON format.

STEP 1: Decryption

  • Encryption is done using your application's public key that you provided during onboarding. Decryption of the payload should be using the private key of that key-pair.
  • Current encryption algorithms used:
    • RSA-OAEP (for content key wrapping)
    • AES256GCM (for content encrytion)

Sample Code in NodeJS

  // Sample Code for decrypting JWE
  // Decrypt JWE using private key
  function decryptJWE(header, encryptedKey, iv, cipherText, tag, privateKey) {

    return new Promise((resolve, reject) => {

      var keystore = jose.JWK.createKeyStore();

      var data = {
        "type": "compact",
        "ciphertext": cipherText,
        "protected": header,
        "encrypted_key": encryptedKey,
        "tag": tag,
        "iv": iv,
        "header": JSON.parse(jose.util.base64url.decode(header).toString())
      };
      keystore.add(fs.readFileSync(privateKey, 'utf8'), "pem")
        .then(function(jweKey) {
          // {result} is a jose.JWK.Key
          jose.JWE.createDecrypt(jweKey)
            .decrypt(data)
            .then(function(result) {
              resolve(JSON.parse(result.payload.toString()));
            })
            .catch(function(error) {
              reject(error);
            });
        });

    })
    .catch (error => {
      throw "Error with decrypting JWE";
    })
  }

STEP 2: Verification of Signature

The decrypted payload is signed according to JWS (JSON Web Signature) format, similar to the access token.

  • signature algorithm used is RS256.

Sample Code in NodeJS

  // Sample Code for Verifying & Decoding JWS or JWT
  function verifyJWS(jws, publicCert) {
    // verify payload
    // ignore notbefore check because it gives errors sometimes if the call is too fast.
    try {
      var jwspayload = jwt.verify(jws, fs.readFileSync(publicCert, 'utf8'), {
        algorithms: ['RS256'],
        ignoreNotBefore: true
      });
      return jwspayload;
    }
    catch(error) {
      throw("Error with verifying and decoding JWS");
    }
  }

Understanding the Data Structure

SG-Verify Person data follows a specific structure that you need to understand to traverse the data effectively. This section will explain the structure in detail.

The diagram below illustrates how the data is represented logically:
SG-Verify Person Data Structure

Data Items (Top-Level)

Each top-level data item can either be a data item object or an array of data item objects. Each data item object will consist of the following properties:

  • classification (Data classification of data field. Default 'C' - Confidential)
  • source (see below)
  • lastupdated (Last updated date of data field. See "full-date" here)
  • unavailable (in certain situations - see below)
  • additional data properties containing data values or arrays

Data Source

The source property indicates the source of data. Possible values are:

  • '1' - Government-verified
  • '2' - User provided
  • '3' - Field is Not Applicable to Person
  • '4' - Verified by SingPass

Note: All Government-verified fields must be non-editable on your digital service form (some exceptions apply - see individual field descriptions).

Data Properties

In each data item, there can be multiple data properties or arrays of data properties.

Each data property will contain either:

  • a value property, or
  • a pair of code and desc properties, or
  • an array of data properties, or
  • other data properties

Note:

  • value property can be strings, numbers, or dates.
  • code and desc pairs will contain the code and its matching description.
  • value is mutually exclusive from (code + desc); i.e. if there is a value, there will not be any code or desc.
  • Where there is code, there will always be a desc - no value will be present.

Exceptions: For these cases, the values will be directly in the property and not in a value, code or desc subproperty:

  • for data item metadata properties; e.g. classification, source, lastupdated, and unavailable
  • for discriminator properties; e.g. type in address formats

Data Not Applicable

Sometimes, a requested data item is not applicable to the person. Examples include:

  • a foreigner will never have a regadd data item.
  • a singapore citizen or permanent resident will never have passtype data item.

For a full list, refer to the "Data Catalog" section of SG-Verify API Data in our portal.

Note: When a requested data item is not applicable to the person, the source property will be 3. In such cases, please ignore the data item completely.

Data Item Not Applicable

When a requested data item is not applicable to the entity:

  • for data item objects, the source property will be 3
  • for data item arrays, an empty array will be returned

In such cases, please ignore the data item completely.

Data Property Not Applicable

  • When a data property is not applicable to the person, it will not appear in the schema of that particular entity type.
  • Please check the Person schema to identify which data properties are not applicable to the person type.

Data Unavailable

In other situations, a requested data item might not have any data for that data item from the data source; i.e. data is unavailable. Examples include:

  • when a person does not have any vehicles registered under them

Note: When a requested data item is unavailable:

  • for data item objects, the data item will have the property unavailable with value true.
    In such cases, no additional properties (other than classification, source, and lastupdated) will be provided for the data item.
  • for arrays of data items, an empty array will be returned.

Please display as "Not Available" in your form.

Data Item Unavailable

  • for data item objects, the data item will have the property unavailable with value true.
    In such cases, no additional properties (other than classification, source, lastupdated) will be provided for the data item.
  • for data item arrays, an empty array will be returned.

Please display as "Not Available" in your form.

Data Property Unavailable

  • for data property objects, the value or code/desc will be empty value ("") or NaN.
  • for arrays of data properties, an empty array will be returned.

Error Handling

The RESTful APIs used HTTP specification standard status codes to indicate the success or failure of each request. Except gateway errors, the response content will be in the following JSON format:

{
    "code": "integer (int32)",
    "message": "string"
}

Refer to the individual API definitions for the error codes you might encounter for each API.

Support

Please refer to the NDI {api} Portal for the following supporting materials where relevant:

For technical queries, contact support@myinfo.gov.sg.

For business queries, contact partner@myinfo.gov.sg.

Sample header with authorization parameters

Below is an example of an Authorization header for the sample application. Make sure you list the parameters in the sequence shown below.

  Authorization: PKI_SIGN
  app_id="STG2-MYINFO-SELF-TEST",
  nonce="150590021034800",
  signature_method="RS256",
  signature="EEm+HEcNQajb5FkVd82zjojk+daYZXxSGPCOR2GHZeoyjZY1PK+aFMzHfWu7eJZYMa5WaEwWxdOdq5hjNbl8kHD7bMaOks7FgEPdjE++TNomfv7SMktDnIvZmPYAxhjb/C9POU2KT6tSlZT/Si/qMgD1cryaPwSeMoM59UZa1GzYmqlkveba7rma58uGwb3wZFH0n57UnouR6LYXDOOLkqi8uMZBuvRUvSJRXETAj2N0hT+4QJiN96Ct6IEQh/woZh0o74K5Ol9PpDSM08qC7Lj6N/k694J+hbBQVVviGn7/6mDkfbwdMDuoKs4t7NpqmAnwT+xaQSIZcexfrAVQYA==",
  timestamp="1505900210349"

Authentication

PKISign

PKI digital signature for server to server calls. See Request Signing for more details.

Security Scheme Type HTTP
HTTP Authorization Scheme Mutual authentication via PKI digital signature in Authorization header

OAuth2

The following are the available OAuth2 scopes for SG-Verify APIs

Security Scheme Type OAuth2
authorizationCode OAuth Flow
Authorization URL:
Token URL: /sgverify/v3/token
Scopes:
  • uinfin -

    NRIC/FIN

  • partialuinfin -

    Partial NRIC/FIN

  • uuid -

    UUID

  • name -

    Principal Name

  • aliasname -

    Alias Name

  • hanyupinyinname -

    Hanyu Pinyin Name

  • hanyupinyinaliasname -

    Hanyu Pinyin Alias Name

  • marriedname -

    Married Name

  • sex -

    Sex

  • race -

    Race

  • secondaryrace -

    Secondary Race

  • dob -

    Date of Birth

  • residentialstatus -

    Residential Status

  • nationality -

    Nationality/Citizenship

  • birthcountry -

    Country/Place of Birth

  • passportnumber -

    Passport Number

  • passportexpirydate -

    Passport Expiry Date

  • passtype -

    Pass Type

  • passstatus -

    Pass Status

  • passexpirydate -

    Pass Expiry Date

  • mobileno -

    Mobile Number

  • email -

    Email Address

  • regadd -

    Registered Address

  • employment -

    Name of Employer

  • drivinglicence.qdl.validity -

    Driving Licence - Qualified Driving Licence Validity

  • drivinglicence.qdl.expirydate -

    Driving Licence - Qualified Driving Licence Expiry Date

  • drivinglicence.qdl.classes -

    Driving Licence - Qualified Driving Licence Class

Generating QR Code

Partner will need to generate the SG-Verify QR code by following the parameters and values in the URL.

Your QR code

1) Forming the SG-Verify URL with the query parameters

2) Sign the SG-Verify URL on Step (1) with your private key

3) Assembling the signature into SG-Verify URL

Example:

https://app.singpass.gov.sg/sgverify?callback=https%3A%2F%2Ftest.yourcallbackurl%2Fcallback&client_id=STG2-SGVERIFY-SELF-TEST&nonce=158624668049200&qr_type=dynamic&signature_method=RS256&state=kiosk4&timestamp_expiry=1586247280492&timestamp_start=1586246680492&v=2&signature=B8NV5QoAbmuEjy0Ie5NpSMxMhoqwvV+ZyYJ4VOOQoJyfqLLoxlFJiKTUfb4LA4RVsrSnLiBl4hY3WOFCm4d8Q5cNlsuNO4c24pzTPOAx/HzpHvZYLQjJVxuL9BObaZbKrzO4yKVXDg2xNgqcNzEQQZzByxhv56uuTn/Y2dVAGSMZzmpte5/Vv3GR9okrymrrmjszXMMv3HJk30Xui+gwKpD6sgtcYdh63+qpJpe55QqUTOMLID2+v7EP5IVTcbhbT3G6w72aIs0UpqLOrfPom+mo8a0SfpHPkkvl9+sPMijbQMd/9XKQnKxTY8ovgHHuU2OEuuO1wYbZdKadiYqpgA==

Note: Make sure you list the parameters in the sequence shown below.

query Parameters
callback
required
string
Example: callback=https%3A%2F%2Ftest.yourcallbackurl%2Fcallback

Your callback URL (with URL encoded) for SG-Verify to return with the authorisation code.

client_id
required
string
Example: client_id=STG2-SGVERIFY-SELF-TEST

Unique ID for your application.

nonce
string
Example: nonce=4110833

Unique randomly generated text used for replay prevention

Note: Mandatory only if qr_type is dynamic

qr_type
required
string
Enum: "static" "dynamic"
Example: qr_type=dynamic

Type of QR

signature_method
required
string
Default: "RS256"

Signature algorithm of the authenticating gateway.

state
required
string
Example: state=kiosk001

Identifier that represents the user's session/transaction with the client for reconciling query and response. The same value will be sent back via the callback URL. Use a unique system generated number for each user/transaction.

timestamp_expiry
required
string
Example: timestamp_expiry=1602324610000

QR code expiry timestamp (UNIX epoch time in milliseconds)

timestamp_start
required
string
Example: timestamp_start=1570702210000

QR code start timestamp (UNIX epoch time in milliseconds)

v
required
string
Default: 2

Version of SG-Verify API.

signature
required
string
Example: signature=afzktYsdEcs...

Binary of the generated signature encoded in Base64 URL-safe format.

Request samples

// 1) Forming the SG - Verify URL with the query parameters:
function formSgVerifyURl() {
    var baseUrl = "https://app.singpass.gov.sg/sgverify";
    
    /** static QR
    var sgverifyURl = baseUrl +
        "?callback=" + "https%3A%2F%2Ftest.yourcallbackurl%2Fcallback" +
        "&client_id=" + "STG2-SGVERIFY-SELF-TEST" +
        "&qr_type=" + "static" +
        "&signature_method=" + "RS256"+
        "&state=" + "kiosk001" +
        "&timestamp_expiry=" + "1602324610000" + // Saturday, 10 October 2020 10:10:10
        "&timestamp_start=" + "1570702210000" + // Thursday, 10 October 2019 10:10:10
        "&v=" + "2" ;
    **/

    // dynamic QR
    var sgverifyURl = baseUrl +
        "?callback=" + "https%3A%2F%2Ftest.yourcallbackurl%2Fcallback" +
        "&client_id=" + "STG2-SGVERIFY-SELF-TEST" +
        "&nonce=" + "4110833" +
        "&qr_type=" + "dynamic" +
        "&signature_method=" + "RS256"+
        "&state=" + "kiosk001" +
        "&timestamp_expiry=" + "1602324610000" + // Saturday, 10 October 2020 10:10:10
        "&timestamp_start=" + "1570702210000" + // Thursday, 10 October 2019 10:10:10
        "&v=" + "2" ;

    return sgverifyURl;
}


// 2) Sign the SG - Verify URL on Step(1) with your private key:
function signSgVerifyURL(sgverifyURl) {

    // Read your private key using FS (Recommended: read it from keystore)
    var keytoSign = {
        key: fs.readFileSync(keyCertContent, 'utf8')
    };

    var signedSgVerifyURl = crypto.createSign('RSA-SHA256')
        .update(sgverifyURl)
        .sign(keytoSign, 'base64');

    // signedSgVerifyURl= MEyCBY/XSBBBg8fDhRxbZNC+LQbz1eGhQLr3wnT+sLn1d3ms/SxJYBGjb4grIeG673P31jPwqyGgIt//+chYDK1ToBQ67tK25dnBRXECooWW12q+LYMZPpRCFPxZpowT2IaKsiFZm/RD5l3ZQNCb8HGsOGynyZPtEnXCNu8Ar5pWAVG/F00JtW2rX25gT7xOS3Yhpfkpsmz3grPTI0YHKrH379z8yHeK+PnmgH+8R8fbqEzek/++CQhgB0FAO0qYd7l6bTMeTQHa3G9CMeBt3OWM1oCHw/fpQJHbbLdmtN7/fXHUsYkidd4jgsYCNstbssdQmQ+3Zlb41Ov3m4pyrg==

    return signedSgVerifyURl;
}


// 3) Assembling the signature into SG-Verify URL
function assemblingSgVerifyUrlWithSignature(sgverifyURl,signedSgVerifyURl) {

    var sgverifyURlwithSignature= sgverifyURl +
    "&signature=" + signedSgVerifyURl;


    //sgverifyURlwithSignature = https://app.singpass.gov.sg/sgverify?callback=https%3A%2F%2Ftest.yourcallbackurl%2Fcallback&client_id=STG2-SGVERIFY-SELF-TEST&expiry_timestamp=1575540722000&nonce=4110833&qr_type=dynamic&state=kiosk001&v=2&signature_method=RS256&signature=hTMkaZzmcVLCkKF7cpAlcFZweTBeSs8A1yo5/ueAoJzvXt8KmTfjyUhxFXnpJGUdWXuDVsu7pHsQWor/t/50wSR7FBvjmWJEzin9g8erDarC14zKJspi1ENa11Rt9xa3K8jkmK8nazpjnwkAIWvRqeBAyfn8P1QrQSFIFJjxKUgWZ7kZexS3raZJ+DCSGRPFSx55f9xuAdWEsmME1JvZNTf3TjMo0ulZepyGKYbcTiry/1U6VQWhDOpXELLOCtMiWzOd/LNocbQ5F2mti8PmouXlDcWnxR+unOsk0jlC2/2db1xjTxf35EkZ31DOtGMb+fHNT042cUFo6yEzu6ROrQ==


    return sgverifyURlwithSignature;
}

Partner's Callback

SG-Verify will send the authorisation code to the partner once the user provides consent.

Your Callback

Note: Partner need to provide this callback URL to SG-Verify.

This callback allows SG-Verify to send authorisation code to the partner after the user provides consent.

Example:

https://{yourcallbackurl}/callback?code=OakxTQ8ecbuY1_0VBnCxdL0AsPQ&state=3D157196957062600

Responses

Verify APIs

Token

This API generates an access token when presented with a valid authcode obtained from the Authorise API. This token can then be used to request for the user's data that were consented.

Authorizations:
header Parameters
Authorization
required
string

Add authorization token constructed containing the RSA digital signature of the base string. Refer to https://api.singpass.gov.sg/library/verify/developers/tutorial2 on how this token should be generated.

Note: This header is not required when calling Sandbox API.

Request Body schema: application/x-www-form-urlencoded
code
required
string

The authcode given by the authorise API.

grant_type
string
Default: "authorization_code"

Grant type for getting token (default "authorization_code")

client_secret
required
string

Secret key given to your application during onboarding.

client_id
required
string

Unique ID for your application.

redirect_uri
required
string

Application's callback URL.

state
required
string

Identifier that represents the user's session with the client, provided earlier during the authorise API call.

Responses

Request samples

// function to prepare request for TOKEN API
function createTokenRequest(code) {
  var cacheCtl = "no-cache";
  var contentType = "application/x-www-form-urlencoded";
  var method = "POST";
  var request = null;

  // preparing the request with header and parameters
  // assemble params for Token API
  var strParams = "grant_type=authorization_code" +
    "&code=" + code +
    "&redirect_uri=" + _redirectUrl +
    "&client_id=" + _clientId +
    "&client_secret=" + _clientSecret;
  var params = querystring.parse(strParams);


  // assemble headers for Token API
  var strHeaders = "Content-Type=" + contentType + "&Cache-Control=" + cacheCtl;
  var headers = querystring.parse(strHeaders);

  // Sign request and add Authorization Headers
  var authHeaders = generateAuthorizationHeader(
    _tokenApiUrl,
    params,
    method,
    contentType,
    _authLevel,
    _clientId,
    _privateKeyContent,
    _clientSecret
  );

  if (!_.isEmpty(authHeaders)) {
    _.set(headers, "Authorization", authHeaders);
  }

  var request = restClient.post(_tokenApiUrl);

  // Set headers
  if (!_.isUndefined(headers) && !_.isEmpty(headers))
    request.set(headers);

  // Set Params
  if (!_.isUndefined(params) && !_.isEmpty(params))
    request.send(params);

  return request;
}

Response samples

Content type
application/json
{
  • "access_token": {
    },
  • "token_type": "Bearer",
  • "expires_in": 0,
  • "refresh_token": "string",
  • "scope": "string"
}

Person

This API returns user's data from SG-Verify when presented with a valid access token obtained from the Token API.

Note: Null value indicates that an attribute is unavailable.

Authorizations:
path Parameters
uuid
required
string
Example: d0fc2ef1-cc51-41ab-9796-b841f4772280

Universal Unique Identifier for NRIC/FIN.

Note: This value is getting from the JWTAccessToken -> sub

query Parameters
txnNo
string

Transaction ID from requesting digital services for cross referencing.

attributes
required
Array of strings
Example: attributes=partialuinfin,name

Comma separated list of attributes requested. Possible attributes are listed in the scopes of the OAuth2 Security Schema above.

client_id
required
string
Example: client_id=STG2-SGVERIFY-SELF-TEST

Unique ID for your application.

subentity
string
Example: subentity=180099736H

UEN of SaaS partner's client that will be receiving the person data.

header Parameters
Authorization
required
any

Add authorization token constructed containing the RSA digital signature of the base string. Refer to https://api.singpass.gov.sg/library/verify/developers/tutorial2 on how this token should be generated. Also include the access token (JWT) from /token API in your header prefixed with 'Bearer'.

Note: Only the Bearer token is required when calling Sandbox API.

Responses

Request samples

// function to prepare request for PERSON API
function createPersonRequest(uuid, validToken) {
  var url = _personApiUrl + "/" + uuid + "/";
  var cacheCtl = "no-cache";
  var method = "GET";
  var request = null;
  // assemble params for Person API
  var strParams = "client_id=" + _clientId +
    "&attributes=" + _attributes;
  var params = querystring.parse(strParams);

  // assemble headers for Person API
  var strHeaders = "Cache-Control=" + cacheCtl;
  var headers = querystring.parse(strHeaders);
  var authHeaders;

  // Sign request and add Authorization Headers
  authHeaders = generateAuthorizationHeader(
    url,
    params,
    method,
    "", // no content type needed for GET
    _authLevel,
    _clientId,
    _privateKeyContent,
    _clientSecret
  );

  if (!_.isEmpty(authHeaders)) {
    _.set(headers, "Authorization", authHeaders + ",Bearer " + validToken);
  }
  else {
    // NOTE: include access token in Authorization header as "Bearer " (with space behind)
      _.set(headers, "Authorization", "Bearer " + validToken);
  }

  // invoke token API
  var request = restClient.get(url);

  // Set headers
  if (!_.isUndefined(headers) && !_.isEmpty(headers))
    request.set(headers);

  // Set Params
  if (!_.isUndefined(params) && !_.isEmpty(params))
    request.query(params);

  return request;
}

Response samples

Content type
application/json
{
  • "partialuinfin": {
    },
  • "uuid": {
    },
  • "name": {
    },
  • "aliasname": {
    },
  • "hanyupinyinname": {
    },
  • "hanyupinyinaliasname": {
    },
  • "marriedname": {
    },
  • "sex": {
    },
  • "race": {
    },
  • "secondaryrace": {
    },
  • "dob": {
    },
  • "residentialstatus": {
    },
  • "nationality": {
    },
  • "birthcountry": {
    },
  • "passportnumber": {
    },
  • "passtype": {
    },
  • "passstatus": {
    },
  • "passexpirydate": {
    },
  • "mobileno": {
    },
  • "email": {
    },
  • "regadd": {
    },
  • "employment": {
    },
  • "drivinglicence": {
    }
}