City (PII) Protection Endpoint


METHOD: POST
ENDPOINT: https://dev.qupass.in/api/city

Description

The City endpoint enables the protection and unprotection of geographic identifiers such as city and town names across all supported languages.

The returned token preserves the original character set across all supported languages, ensuring Unicode integrity and data stores’ locale compatibility.

Maintaining the same encoding space or range of symbols from which the original data was derived — for example, ensuring that a tokenized city name in Hindi continues to use characters from the Devanagari Unicode block (U+0900–U+097F), while a city name in English remains within the Latin-1 or Basic Latin Unicode blocks (U+0000–U+007F).

Examples

  • Input: New York (Latin)
    • QuFold_Token: slRQxkU tMPavfy
      • ✅ Character set preserved (Latin block)
      • ✅ Encoding compatibility is maintained
    • FPE_Token: Koi rVSx
      • ✅ Length and Character set preserved (Latin block)
      • ✅ Encoding compatibility is maintained
  • Input: న్యూయార్క్ (Telugu)
    • QuFold_Token: ౬మఢఖ౭ఈఫఙ౨ట్యఁరిొఝఌగ
      • ✅ Character set preserved (Telugu block)
      • ✅ Encoding compatibility is maintained
  • Input: न्यूयॉर्क (Devanagari)
    • QuFold_Token: ऎणघवज॰ञओुऩॳङरॻॎिउजॲ
      • ✅ Character set preserved (Devanagari block)
      • ✅ Encoding compatibility is maintained

It is not length-preserving — token length may vary intentionally to introduce structural entropy and strengthen protection against pattern correlation and reverse inference.



Request Payload


  • HEADER PARAMETERS
    • x-api-key (required) Provides access to one or more functions in the API Playground.
    • Authorization (required) The JWT token issued upon successful authentication.
    • qu-token (required) QU token that you revceive at the time of login.

  • PAYLOAD DETAILS
    • id (required) Integer identifier for the request.
    • operation (required) Specifies the protection operation. Available: [protect | unprotect].
    • data (required) Array of values to be transformed.
    • options:
      • method - Transformation method; Available: [tokenise | fpe | mask | redact | passthrough].
        • Defaults to tokenise
      • scope - User-defined context string; differentiates tokens across applications or datasets. (e.g., app1, azure+app1).
        • Defaults to no-scope
      • lang - Language domain of the input. Supports most of the International and Indic languages. Look for supported languages
        • International: [en | de | fr | es | it | ru | ar | si | th | hi | ja | ko | zh]
        • Indic: [hi | te | kn | ta | bn | pa | gu | or | ml ]
        • Defaults to en
      • noise - Adds controlled randomness.
        • Defaults to 0, ensures deterministic tokenization within scope
        • Non-zero values produce possible distinct tokens for the repeated inputs

Sample Request


  	curl --location 'https://dev.qupass.in/api/city' \
  	--header 'x-api-key: <API_Key>' \
  	--header 'Authorization: <JWT_TOKEN>' \
  	--header 'qu-token: <QU_TOKEN>' \
  	--header 'Content-Type: application/json' \
  	--data '{
  		"id": 1,
  		"operation": "protect",
  		"data": [
  			"New York",
  			"Tokyo",
      		"Paris"
  		],
  		"options": {
  			"method": "tokenise",
  			"scope": "App1"
  		}
  	}'
    package main

    import ( 
      "io" 
      "fmt"
      "strings" 
      "net/http" 
      )
      
    func main() { 
      API_Key := "<API_Key>"
      JWT_Token := "<JWT_TOKEN>"
      QU_Token := "<QU_TOKEN>"
      
      url := "https://dev.qupass.in/api/city"
      data := strings.NewReader(`{ 
          "id":1,
          "operation": "protect", 
          "data": [
            "New York",
        	"Tokyo",
        	"Paris"
          ],
          "options": {
            "method": "tokenise",
            "scope": "App1"
          } 
      }`)

      req, err := http.NewRequest("POST", url, data)
      if err != nil {
        fmt.Println(err)
        return
      }

      req.Header.Set("x-api-key", API_Key)
      req.Header.Set("Authorization", JWT_Token)
      req.Header.Set("qu-token", QU_Token)
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
        fmt.Println(err)
        return
      }
      defer resp.Body.Close()

      body, err := io.ReadAll(resp.Body)
      if err != nil {
        fmt.Println(err)
        return
      }

      fmt.Println(string(body))
    }
    import java.net.HttpURLConnection;
    import java.net.URI;
    import java.net.URL;
    import java.io.OutputStream;
    import java.io.InputStreamReader;
    import java.io.BufferedReader;
    import java.nio.charset.StandardCharsets;

    public class APIRequest {
        public static void main(String[] args) {
            try {
                String API_Key = "<API_Key>";
                String JWT_Token = "<JWT_TOKEN>";
                String QU_Token = "<QU_TOKEN>";

                URI uri = new URI("https://dev.qupass.in/api/city");

                String data = "{"
                        + "\"id\": 1,"
                        + "\"operation\": \"protect\","
                        + "\"data\": ["
                        + "\"New York\","
                        + "\"Tokyo\","
                        + "\"Paris\""
                        + "],"
                        + "\"options\": {"
                        + "\"method\": \"tokenise\","
                        + "\"scope\": \"App1\""
                        + "}"
                        + "}";

                URL url = uri.toURL();
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();

                conn.setRequestMethod("POST");
                conn.setRequestProperty("x-api-key", API_Key);
                conn.setRequestProperty("Authorization", JWT_Token);
                conn.setRequestProperty("qu-token", QU_Token);
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setDoOutput(true);

                // Send request body
                try (OutputStream os = conn.getOutputStream()) {
                    byte[] input = data.getBytes(StandardCharsets.UTF_8);
                    os.write(input, 0, input.length);
                }

                int statusCode = conn.getResponseCode();

                BufferedReader br;
                if (statusCode >= 200 && statusCode < 300) {
                    br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
                } else {
                    br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
                }

                StringBuilder response = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    response.append(line.trim());
                }

                System.out.println(response.toString());

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    const API_Key = "<API_Key>";
    const JWT_Token = "<JWT_TOKEN>";
    const QU_Token = "<QU_TOKEN>";

    const url = "https://dev.qupass.in/api/city";

    const data = {
      id: 1,
      operation: "protect",
      data: [
        "New York",
        "Tokyo",
        "Paris"
      ],
      options: {
        method: "tokenise",
        scope: "App1"
      }
    };

    fetch(url, {
      method: "POST",
      headers: {
        "x-api-key": API_Key,
        "Authorization": JWT_Token,
        "qu-token": QU_Token,
        "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    })
      .then(async (response) => {
        const text = await response.text(); // raw response like Python's response.text
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${text}`);
        }
        console.log(text);
      })
      .catch((error) => {
        console.error("Error:", error.message);
      });
    <?php

    $API_Key = "<API_Key>";
    $JWT_Token = "<JWT_TOKEN>";
    $QU_Token = "<QU_TOKEN>";

    $url = "https://dev.qupass.in/api/city";

    $headers = [
        "x-api-key: $API_Key",
        "Authorization: $JWT_Token",
        "qu-token: $QU_Token",
        "Content-Type: application/json"
    ];

    $data = [
        "id" => 1,
        "operation" => "protect",
        "data" => [
            "New York",
        	"Tokyo",
        	"Paris"
        ],
        "options" => [
            "method" => "tokenise",
            "scope" => "App1"
        ]
    ];

    $ch = curl_init($url);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    } else {
        echo $response;
    }

    curl_close($ch);
    ?>
    import requests
    import json

    API_Key = "<API_Key>"
    JWT_Token = "<JWT_TOKEN>"
    QU_Token = "<QU_TOKEN>"

    url = 'https://dev.qupass.in/api/city'
    headers = {
      'x-api-key': API_Key,
      'Authorization': JWT_Token,
      'qu-token': QU_Token,
      'Content-Type': 'application/json'
    }

    data = {
      "id": 1,
      "operation": "protect",
      "data": [
        "New York",
        "Tokyo",
        "Paris"
      ],
      "options": {
        "method": "tokenise",
        "scope": "App1"
      }
    }

    response = requests.post(url, headers=headers, data=json.dumps(data))
    print(response.text)


Sample Data Payload and Output


PROTECTION SCENARIOS:

InputOutput
  {
    "operation": "protect",
    "data": [
        "New York",
        "New York",
        "Tokyo",
        "Paris"
    ],
    "method": "*" // [tokenise, fpe, .,]
  }
    {
      "operation": "protect",  
      "result": [
          "slRQxkU tMPavfy",
          "slRQxkU tMPavfy",
          "ruOacwiLeK",
          "huvmlCJWjU"
      ],
      "method": "tokenise"
    }
    {
      "operation": "protect",  
      "result": [
          "frNiRyAk HPIuhERI",
          "frNiRyAk HPIuhERI",
          "bTidguSryouNs",
          "QctUnUrMOZEXl"
      ],
      "method": "tokenise",
      "scope": "App1" //SCOPE
    }
    {
      "operation": "protect",  
      "result": [
          "NhKsPja GdAXADc",
          "frJYzXx jtmlSDK",
          "ATMgxlTMqps",
          "ETQDrUwRpys"
      ],
      "method": "tokenise",
      "noise": "2" //NOISE
    }
    {
      "operation": "protect",  
      "result": [
          "QOtCRxsY GnjonhEPs",
          "WCFXtFfR JAQapNmGm",
          "tstFCJXSlFXfoK",
          "XstvzGduxGQXrV"
      ],
      "method": "tokenise",
      "scope": "App1", //SCOPE
      "noise": "2" //NOISE
    }
    {
      "operation": "protect",  
      "result": [
          "Koi rVSx",
          "Koi rVSx",
          "aROzr",
          "DqfWw"
      ],
      "method": "fpe" // FPE
    }

UNPROTECTION SCENARIOS:

InputOutput
  {
    "operation": "unprotect",
    "data": [
        "slRQxkU tMPavfy",
        "slRQxkU tMPavfy",
        "ruOacwiLeK",
        "huvmlCJWjU"
    ],
    "method": "tokenise"
  }
    {
      "operation": "unprotect",  
      "result": [
          "New York",
          "New York",
          "Tokyo",
          "Paris"
      ]
    }
  {
    "operation": "unprotect",
    "data": [
        "slRQxkU tMPavfy",
        "slRQxU tMPavfy",
        "ruOacwiLeK",
        "huvmlCJWjU"
    ],
    "method": "tokenise"
  }
    {
      "operation": "unprotect",  
      "result": [
          "New York",
          "slRQxU tMPavfy", //INVALID
          "Tokyo",
          "Paris"
      ],
      "discrepancy": {
        "invalid_token": [ //INVALID
          1 // INDEX
        ]
      }
    }
  {
    "operation": "unprotect",
    "data": [
        "slRQxkU tMPavfy",
        "slRQxkU tMPavfy",
        "ruOacwiLeK",
        "huvmlCJWjU"
    ],
    "scope":"App2", //INVALID
    "method": "tokenise"
  }
    {
      "operation": "unprotect",  
      "result": [
          "slRQxkU tMPavfy",
          "slRQxkU tMPavfy",
          "ruOacwiLeK",
          "huvmlCJWjU"
      ],
      "discrepancy": {
        "invalid_scope": [ // INVALID
          0, // INDEX
          1,
          2,
          3
        ]
      }
    }
  {
    "operation": "unprotect",
    "data": [
        "Koi rVSx",
        "Koi rVSx",
        "aROzr",
        "DqfWw"
    ],
    "method": "fpe"
  }
    {
      "operation": "unprotect",  
      "result": [
          "New York",
          "New York",
          "Tokyo",
          "Paris"
      ]
    }