Initiate and retrieve a One-Time Password (OTP) for a specific pending transaction to complete user verification and transaction authorization.
Generate OTP for Pending Transaction
Flow: Retrieve pending tokens → Generate OTP for selected token
GET — /gateway/safetoken/v1/tokens/validations
Retrieve pending token transactions filtered by mobile number, email, date range, status or pagination
SECURE
Headers
Content-Type: application/jsonApiKey: <requestor-key>Authorization: Bearer <access_token>- generated via OAuth2 login
Query Parameters (optional)
mobileNo (string) — e.g. +2348076000000
email (string)
startDate (ISO 8601)
endDate (ISO 8601)
pageNum (int)
pageSize (int)
status — INITIATED / FAILED / UNAUTHENTICATED / AUTHENTICATED
curl --location '{{BASE_URL}}/gateway/safetoken/v1/tokens/validations' \
--header 'Content-Type: application/json' \
--header 'ApiKey: {{requestor-key}}'
// Node (axios)
const axios = require('axios');
axios.get('{{BASE_URL}}/gateway/safetoken/v1/tokens/validations', {
params: { mobileNo: '{{mobile-no}}' },
headers: {
'Content-Type': 'application/json',
'ApiKey': '{{requestor-key}}'
}
}).then(r => console.log(r.data)).catch(e => console.error(e.response?.data || e));
# Python (requests)
import requests
url = '{{BASE_URL}}/gateway/safetoken/v1/tokens/validations'
headers = {'Content-Type': 'application/json', 'ApiKey': '{{requestor-key}}'}
params = {'mobileNo': '{{mobile-no}}'}
resp = requests.get(url, headers=headers, params=params)
print(resp.json())
// React (fetch)
fetch('{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}', {
headers: {
'Content-Type': 'application/json',
'ApiKey': '{{requestor-key}}'
}
}).then(r => r.json()).then(console.log).catch(console.error);
// JavaScript (fetch)
fetch('{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}', {
headers: {
'Content-Type': 'application/json',
'ApiKey': '{{requestor-key}}'
}
}).then(r => r.json()).then(console.log).catch(console.error);
// Java (OkHttp)
OkHttpClient client = new OkHttpClient();
Request req = new Request.Builder()
.url("{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}")
.addHeader("Content-Type", "application/json")
.addHeader("ApiKey", "{{requestor-key}}")
.build();
Response res = client.newCall(req).execute();
System.out.println(res.body().string());
// Spring Boot (RestTemplate)
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
headers.set("ApiKey", "{{requestor-key}}");
HttpEntity entity = new HttpEntity<>(headers);
ResponseEntity response = restTemplate.exchange(
"{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}",
HttpMethod.GET,
entity,
String.class
);
System.out.println(response.getBody());
// C# (HttpClient)
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Content-Type", "application/json");
client.DefaultRequestHeaders.Add("ApiKey", "{{requestor-key}}");
var res = await client.GetAsync("{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}");
Console.WriteLine(await res.Content.ReadAsStringAsync());
// Go (net/http)
req, _ := http.NewRequest("GET", "{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}", nil)
req.Header.Add("Content-Type", "application/json")
req.Header.Add("ApiKey", "{{requestor-key}}")
resp, _ := http.DefaultClient.Do(req)
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
// Kotlin (OkHttp)
val request = Request.Builder()
.url("{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}")
.addHeader("Content-Type", "application/json")
.addHeader("ApiKey", "{{requestor-key}}")
.build()
val resp = client.newCall(request).execute()
println(resp.body?.string())
// PHP (cURL)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json", "ApiKey: {{requestor-key}}"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);
curl_close($ch);
# Ruby (Net::HTTP)
require 'net/http'
uri = URI('{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}')
req = Net::HTTP::Get.new(uri)
req['Content-Type'] = 'application/json'
req['ApiKey'] = '{{requestor-key}}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.body
// Swift (URLSession)
let url = URL(string: "{{BASE_URL}}/gateway/safetoken/v1/tokens/validations?mobileNo={{mobile-no}}")!
var req = URLRequest(url: url)
req.setValue("application/json", forHTTPHeaderField: "Content-Type")
req.setValue("{{requestor-key}}", forHTTPHeaderField: "ApiKey")
URLSession.shared.dataTask(with: req) { data, res, err in
print(String(decoding: data!, as: UTF8.self))
}.resume()
Success Response (200)
{
"count": 7735,
"content": [
{
"correlationId": "a74c2319-4fef-4979-a4e1-6ea94d1d3b90",
"tokenIdMasked": "506100********0039",
"mobileNo": "+2348129175777",
"amount": 5000,
"currency": "566",
"siteName": "DSTV",
"status": "INITIATED"
},
{
"correlationId": "80fa61ff-d568-44cd-a53b-a7d920e19c36",
"tokenIdMasked": "506105*********7864",
"mobileNo": "+2348025279025",
"amount": 2000,
"currency": "566",
"siteName": "Interswitch Energy Platform_SANDBOX",
"status": "INITIATED"
},
{
"correlationId": "dd4d4d30-9071-459a-b562-69d737c6e959",
"tokenIdMasked": "506100********0039",
"mobileNo": "+2348129175777",
"amount": 5000,
"currency": "566",
"siteName": "DSTV",
"status": "INITIATED"
}
],
"code": "00",
"description": "Successful",
"errors": null
}
404 — Pending Transactions (Non-Existent Requestor ApiKey)
{
"code": "10404",
"description": "API Key does not exist",
"errors": null
}
403 — Pending Transactions (Unauthorized User)
{
"code": "10403",
"description": "Token Aggregator does not have access to perform this action",
"errors": null
}
400 — Pending Transactions (No ApiKey)
{
"code": "10400",
"description": "Bad request",
"errors": [
{
"fieldName": "header",
"message": "Required request header 'ApiKey' for method parameter type String is not present"
}
]
}
400 — Pending Transactions (Status as TRUE)
{
"code": "10400",
"description": "Bad request",
"errors": [
{
"fieldName": "status",
"message": "invalid"
}
]
}
200 — Invalid Email and Phone No (Empty List)
{
"count": 0,
"content": [],
"code": "00",
"description": "Successful",
"errors": null
}
400 — Pending Transactions (End Date behind Start Date)
{
"code": "10400",
"description": "Bad request",
"errors": [
{
"fieldName": "endDate",
"message": "invalid"
},
{
"fieldName": "startDate",
"message": "invalid"
}
]
}
POST — /gateway/safetoken/v1/soft-token/generate
Generate a one-time password (OTP) for a selected pending token transaction.
SECURE
Headers
Content-Type: application/jsonApiKey: <requestor-key>Authorization: Bearer <access_token>- generated via OAuth2 login
Request Body (Re-generate with correlationId)
{
"correlationId": "{{generated-correlation-id}}"
}
curl --location '{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate' \
--header 'Content-Type: application/json' \
--header 'ApiKey: {{requestor-key}}' \
--data '{
"correlationId": "{{generated-correlation-id}}"
}'
// Node (axios)
const axios = require('axios');
axios.post('{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate',
{ correlationId: '{{generated-correlation-id}}' },
{ headers: { 'Content-Type': 'application/json', 'ApiKey': '{{requestor-key}}' } }
).then(r => console.log(r.data)).catch(e => console.error(e.response?.data || e));
# Python (requests)
import requests
url = '{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate'
headers = {'Content-Type': 'application/json', 'ApiKey': '{{requestor-key}}'}
payload = {'correlationId': '{{generated-correlation-id}}'}
resp = requests.post(url, headers=headers, json=payload)
print(resp.json())
// React (fetch)
fetch('{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'ApiKey': '{{requestor-key}}'
},
body: JSON.stringify({ correlationId: '{{generated-correlation-id}}' })
}).then(r => r.json()).then(console.log).catch(console.error);
// JavaScript (fetch)
fetch('{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'ApiKey': '{{requestor-key}}'
},
body: JSON.stringify({ correlationId: '{{generated-correlation-id}}' })
}).then(r => r.json()).then(console.log).catch(console.error);
// Spring Boot (RestTemplate)
RestTemplate rt = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
headers.set("ApiKey", "{{requestor-key}}");
String body = "{\"correlationId\": \"{{generated-correlation-id}}\"}";
HttpEntity e = new HttpEntity<>(body, headers);
ResponseEntity resp = rt.postForEntity("{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate", e, String.class);
System.out.println(resp.getBody());
// Java (OkHttp)
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
String jsonBody = "{\"correlationId\": \"{{generated-correlation-id}}\"}";
RequestBody body = RequestBody.create(jsonBody, JSON);
Request request = new Request.Builder()
.url("{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate")
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("ApiKey", "{{requestor-key}}")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
// C# (HttpClient)
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Content-Type", "application/json");
client.DefaultRequestHeaders.Add("ApiKey", "{{requestor-key}}");
var payload = new StringContent(System.Text.Json.JsonSerializer.Serialize(new { correlationId = "{{generated-correlation-id}}"}), System.Text.Encoding.UTF8, "application/json");
var res = await client.PostAsync("{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate", payload);
Console.WriteLine(await res.Content.ReadAsStringAsync());
// Go (net/http)
jsonStr := `{"correlationId":"{{generated-correlation-id}}"}`
req, _ := http.NewRequest("POST", "{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate", strings.NewReader(jsonStr))
req.Header.Add("Content-Type", "application/json")
req.Header.Add("ApiKey", "{{requestor-key}}")
resp, _ := http.DefaultClient.Do(req)
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
// Kotlin (OkHttp)
val json = "{\"correlationId\": \"{{generated-correlation-id}}\"}"
val body = json.toRequestBody("application/json; charset=utf-8".toMediaType())
val req = Request.Builder()
.url("{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate")
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("ApiKey", "{{requestor-key}}")
.build()
val res = client.newCall(req).execute()
println(res.body?.string())
// PHP (cURL)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json", "ApiKey: {{requestor-key}}"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([correlationId => "{{generated-correlation-id}}"]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);
curl_close($ch);
# Ruby (Net::HTTP)
require 'net/http'
uri = URI('{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req['ApiKey'] = '{{requestor-key}}'
req.body = { correlationId: '{{generated-correlation-id}}' }.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.body
// Swift (URLSession)
let url = URL(string: "{{BASE_URL}}/gateway/safetoken/v1/soft-token/generate")!
var req = URLRequest(url: url)
req.httpMethod = "POST"
req.setValue("application/json", forHTTPHeaderField: "Content-Type")
req.setValue("{{requestor-key}}", forHTTPHeaderField: "ApiKey")
let body = ["correlationId": "{{generated-correlation-id}}"]
req.httpBody = try! JSONSerialization.data(withJSONObject: body)
URLSession.shared.dataTask(with: req) { data, _, _ in
if let data = data { print(String(decoding: data, as: UTF8.self)) }
}.resume()
Success Response (200) — Generate with tokenId
{
"code": "00",
"description": "Successful",
"errors": null,
"correlationId": "d22e5ed4-b304-42b5-8e53-4ff094835b51",
"requestorReference": null,
"otp": "963189",
"expiry": "23-Oct-25 03:31 PM"
}
Error Responses
404 — Re-generate OTP (Apikey / tokenId mismatch)
{
"code": "10404",
"description": "Token Validation does not exist",
"errors": null
}
404 — Re-generate OTP (Unregistered Token Id)
{
"tokenId": "TestSoftTokenUnregistered"
}
400 — Re-generate OTP (No or Empty Api Key)
{
"code": "10400",
"description": "Bad request",
"errors": [
{
"fieldName": "header",
"message": "Required request header 'ApiKey' for method parameter type String is not present"
}
]
}
404 — Re-generate OTP (Invalid Api Key)
{
"code": "10404",
"description": "Token Requestor does not exist",
"errors": null
}
400 — Re-generate OTP (No Token Id)
{
"code": "10400",
"description": "Bad request",
"errors": [
{
"fieldName": "tokenId",
"message": "required"
}
]
}