Verify a Signed JWT Token

This API validates a given JWT (authentication or refresh token) against the app’s signing key while considering:

  1. Expiration (exp) – Ensures the token is still valid.
  2. Revoked Signing Keys – Checks if the signing key has been revoked.
  3. Not Before (nbf) – Ensures the token is not used before its valid start time.
If the token passes all checks, the API returns true; otherwise, it returns false.

Endpoint

POST /app/{app_id}/verify

Headers

Name Type Required Description
Authorization string Yes The app-key of the project.

Example Request

curl --request POST \
--url http://{{your-endpoint}}:{{your-port}}/app/{{app-id}}/verify \
--header 'Authorization: {{app-key}}' \
--header 'content-type: application/json' \
--data '{
"token":"eyJhbGciOiJFUzI1NiIsImtpZCI6IjAxSk1WMjhGSlZCS0YwSkcwWVNHNjU1RUhZIiwidHlwIjoiSldUIn0.eyJhdWQiOiJ3ZWItYXBwIiwiZXhwIjoxNzQwNDI2ODg5LCJpYXQiOjE3NDA0MjMyODksImlwIjoiMS4xLjEuMSIsImlzcyI6ImFwcF8yIiwiamlkIjoiMDFKTVdNWlBFWFpLOEtLQkUxSllCQUdCOVYiLCJuYmYiOjE3NDA0MjMyODksInBlcnNvbmFsIjp7Im5hbWUiOiJ0ZXN0LXVzZXIifSwic3ViIjoidGVzdEB0ZXN0LmNvbSIsInVzZXJhZ2VudCI6Im15LXVzZXItYWdlbnQifQ.OY8tCesz-VlIg0kUeCEmKmpWVQ_bxfUEIMa0dZEfNM7x_6z139E8Of4hrffyRCmR3icsuIW5ICvj5QI2aD0I2g"
}'
const request = require('request');

const options = {
    method: 'POST',
    url: 'http://{{your-endpoint}}:{{your-port}}/app/{{app-id}}/verify',
    headers: {Authorization: '{{app-key}}', 'content-type': 'application/json'},
    body: {
    token: 'eyJhbGciOiJFUzI1NiIsImtpZCI6IjAxSk1WMjhGSlZCS0YwSkcwWVNHNjU1RUhZIiwidHlwIjoiSldUIn0.eyJhdWQiOiJ3ZWItYXBwIiwiZXhwIjoxNzQwNDI2ODg5LCJpYXQiOjE3NDA0MjMyODksImlwIjoiMS4xLjEuMSIsImlzcyI6ImFwcF8yIiwiamlkIjoiMDFKTVdNWlBFWFpLOEtLQkUxSllCQUdCOVYiLCJuYmYiOjE3NDA0MjMyODksInBlcnNvbmFsIjp7Im5hbWUiOiJ0ZXN0LXVzZXIifSwic3ViIjoidGVzdEB0ZXN0LmNvbSIsInVzZXJhZ2VudCI6Im15LXVzZXItYWdlbnQifQ.OY8tCesz-VlIg0kUeCEmKmpWVQ_bxfUEIMa0dZEfNM7x_6z139E8Of4hrffyRCmR3icsuIW5ICvj5QI2aD0I2g'
    },
    json: true
};

request(options, function (error, response, body) {
    if (error) throw new Error(error);

    console.log(body);
});
import requests

url = "http://{{your-endpoint}}:{{your-port}}/app/{{app-id}}/verify"

payload = { "token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IjAxSk1WMjhGSlZCS0YwSkcwWVNHNjU1RUhZIiwidHlwIjoiSldUIn0.eyJhdWQiOiJ3ZWItYXBwIiwiZXhwIjoxNzQwNDI2ODg5LCJpYXQiOjE3NDA0MjMyODksImlwIjoiMS4xLjEuMSIsImlzcyI6ImFwcF8yIiwiamlkIjoiMDFKTVdNWlBFWFpLOEtLQkUxSllCQUdCOVYiLCJuYmYiOjE3NDA0MjMyODksInBlcnNvbmFsIjp7Im5hbWUiOiJ0ZXN0LXVzZXIifSwic3ViIjoidGVzdEB0ZXN0LmNvbSIsInVzZXJhZ2VudCI6Im15LXVzZXItYWdlbnQifQ.OY8tCesz-VlIg0kUeCEmKmpWVQ_bxfUEIMa0dZEfNM7x_6z139E8Of4hrffyRCmR3icsuIW5ICvj5QI2aD0I2g" }
headers = {
    "Authorization": "{{app-key}}",
    "content-type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
<?php
$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'http://{{your-endpoint}}:{{your-port}}/app/{{app-id}}/verify', [
    'body' => '{
    "token":"eyJhbGciOiJFUzI1NiIsImtpZCI6IjAxSk1WMjhGSlZCS0YwSkcwWVNHNjU1RUhZIiwidHlwIjoiSldUIn0.eyJhdWQiOiJ3ZWItYXBwIiwiZXhwIjoxNzQwNDI2ODg5LCJpYXQiOjE3NDA0MjMyODksImlwIjoiMS4xLjEuMSIsImlzcyI6ImFwcF8yIiwiamlkIjoiMDFKTVdNWlBFWFpLOEtLQkUxSllCQUdCOVYiLCJuYmYiOjE3NDA0MjMyODksInBlcnNvbmFsIjp7Im5hbWUiOiJ0ZXN0LXVzZXIifSwic3ViIjoidGVzdEB0ZXN0LmNvbSIsInVzZXJhZ2VudCI6Im15LXVzZXItYWdlbnQifQ.OY8tCesz-VlIg0kUeCEmKmpWVQ_bxfUEIMa0dZEfNM7x_6z139E8Of4hrffyRCmR3icsuIW5ICvj5QI2aD0I2g"
}',
    'headers' => [
    'Authorization' => '{{app-key}}',
    'content-type' => 'application/json',
    ],
]);

echo $response->getBody();
package main

import (
    "fmt"
    "strings"
    "net/http"
    "io"
)

func main() {

    url := "http://{{your-endpoint}}:{{your-port}}/app/{{app-id}}/verify"

    payload := strings.NewReader("{\n  \"token\":\"eyJhbGciOiJFUzI1NiIsImtpZCI6IjAxSk1WMjhGSlZCS0YwSkcwWVNHNjU1RUhZIiwidHlwIjoiSldUIn0.eyJhdWQiOiJ3ZWItYXBwIiwiZXhwIjoxNzQwNDI2ODg5LCJpYXQiOjE3NDA0MjMyODksImlwIjoiMS4xLjEuMSIsImlzcyI6ImFwcF8yIiwiamlkIjoiMDFKTVdNWlBFWFpLOEtLQkUxSllCQUdCOVYiLCJuYmYiOjE3NDA0MjMyODksInBlcnNvbmFsIjp7Im5hbWUiOiJ0ZXN0LXVzZXIifSwic3ViIjoidGVzdEB0ZXN0LmNvbSIsInVzZXJhZ2VudCI6Im15LXVzZXItYWdlbnQifQ.OY8tCesz-VlIg0kUeCEmKmpWVQ_bxfUEIMa0dZEfNM7x_6z139E8Of4hrffyRCmR3icsuIW5ICvj5QI2aD0I2g\"\n}")

    req, _ := http.NewRequest("POST", url, payload)

    req.Header.Add("Authorization", "{{app-key}}")
    req.Header.Add("content-type", "application/json")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := io.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
AsyncHttpClient client = new DefaultAsyncHttpClient();
client.prepare("POST", "http://{{your-endpoint}}:{{your-port}}/app/{{app-id}}/verify")
    .setHeader("Authorization", "{{app-key}}")
    .setHeader("content-type", "application/json")
    .setBody("{\n  \"token\":\"eyJhbGciOiJFUzI1NiIsImtpZCI6IjAxSk1WMjhGSlZCS0YwSkcwWVNHNjU1RUhZIiwidHlwIjoiSldUIn0.eyJhdWQiOiJ3ZWItYXBwIiwiZXhwIjoxNzQwNDI2ODg5LCJpYXQiOjE3NDA0MjMyODksImlwIjoiMS4xLjEuMSIsImlzcyI6ImFwcF8yIiwiamlkIjoiMDFKTVdNWlBFWFpLOEtLQkUxSllCQUdCOVYiLCJuYmYiOjE3NDA0MjMyODksInBlcnNvbmFsIjp7Im5hbWUiOiJ0ZXN0LXVzZXIifSwic3ViIjoidGVzdEB0ZXN0LmNvbSIsInVzZXJhZ2VudCI6Im15LXVzZXItYWdlbnQifQ.OY8tCesz-VlIg0kUeCEmKmpWVQ_bxfUEIMa0dZEfNM7x_6z139E8Of4hrffyRCmR3icsuIW5ICvj5QI2aD0I2g\"\n}")
    .execute()
    .toCompletableFuture()
    .thenAccept(System.out::println)
    .join();

client.close();

Request Fields

Field Type Required Description
token string Yes The JWT (auth or refresh) token to be verified.

Example Success Response

{
"verified": true
}

Response Fields

Field Type Description
verified boolean Returns true if the token is valid, otherwise false.

Additional Notes:

  1. A true response means the token is valid, not expired, and signed with an active key.
  2. A false response means the token is expired, revoked, or not yet active.
  3. This API does not decode or return token claims - only verify its authenticity.

Responses

Status Code Description
200 Ok Success
400 Bad Request Mostly when the form validation fails. The error will be returned as a response.
403 Access Denied When the provided app key in Authorization header is invalid.
500 Internal Server Error Mostly because of the database error. Check the log for root cause details.