FASTag Annual Pass API
FASTag & Annual Pass
Introduction
The FASTag & Annual Pass API returns the electronic toll collection footprint of an Indian vehicle against its registration number. For a single vehicle number you receive every FASTag issued against that vehicle — including tags that are no longer in use — together with the vehicle's toll category and, where one exists, the details of its Annual Pass.
A vehicle can hold more than one tag over its lifetime. Tags issued by a previous owner or a previous issuer bank are not removed from the record; they are returned alongside the current tag with their own status. You are required to read tagStatus on each entry rather than assuming the first tag in the array is the live one. totalValidTags reports how many tag records were returned in the tags array, not how many of them are active.
An Annual Pass is a separate product from the tag itself. It is bound to a specific tagId and carries its own validity window, trip limit and status. Not every vehicle has one, so annualPassDetails is polymorphic: when a pass exists it is an object of pass fields, and when none exists it is an object containing only a message of "Annual pass not found". You are required to branch on the presence of passId before reading any other pass field.
Two date formats appear in the response and they are not interchangeable. Tag issueDate is returned as YYYY-MM-DD. Annual Pass passStartDate and passEndDate are returned as DD-MM-YYYY. Numeric pass values such as tripLimit and averageTripsTakenPerMonth are returned as strings, not numbers. The API is a stateless lookup — there is no request id to retain, no idempotency key, and no expiry window on anything returned to you.
How to call the API
You are required to authenticate every request by passing your API key in the Authorization header. The key is passed as a bare token, with no Bearer prefix. The request body is JSON, so Content-Type: application/json is also required.
The endpoint accepts POST only. Any other HTTP method against this path returns 404 with no Route matched with those values.
A successful call returns HTTP 200 with the payload wrapped in a top-level result object.
{
"result": { }
}Application errors are wrapped in a top-level error object carrying a machine-readable reason you can switch on and a human-readable message you can surface or log. status and statusCode both repeat the HTTP status code.
{
"error": {
"name": "error",
"message": "Vehicle number provided in the input payload is missing or invalid.",
"status": 400,
"reason": "VALIDATION_ERROR",
"type": "Bad Request",
"statusCode": 400
}
}Authentication failures are rejected before the request reaches the endpoint and therefore do not use the error envelope. They return HTTP 401 with a flat object containing only a message. You are required to handle this shape separately from the error envelope.
{
"message": "Invalid authentication credentials"
}API Input Guidelines
- vehicleNumber is the only input field and it is required. There are no optional fields and no mutually exclusive fields.
- vehicleNumber must be a JSON string. A number, null, an empty string, or a missing key all fail with VALIDATION_ERROR.
- Casing is tolerated. hr03y2887 and HR03Y2887 return the same record. The registration number is normalised to upper case in the response.
- Whitespace and separators are not tolerated. HR 03 Y 2887 and HR03-Y2887 are rejected with VALIDATION_ERROR. Strip spaces, hyphens and dots before sending.
- Send the registration number in its compact form — state code, RTO code, series and number run together with no delimiters, for example PB10DF0109.
- A well-formed registration number for which no tag and no pass exists returns 404 with reason No record found. This is a distinct outcome from a malformed input and you are required to treat the two differently.
- The Annual Pass lookup is always performed. There is no flag to include or exclude it, and no cache-bypass or force-refresh parameter.
- One vehicle number per request. The endpoint does not accept an array or a batch payload.
- Malformed JSON in the request body is rejected at the gateway with 400 and Unexpected end of JSON input, in a different envelope from application errors.
Sample Curl
Preproduction
curl --location 'https://api-preproduction.signzy.app/api/v3/fastag/annual-pass' \
--header 'Content-Type: application/json' \
--header 'Authorization: <Auth Token>' \
--data '{
"vehicleNumber": "HR03Y2887"
}'Production
curl --location 'https://api.signzy.app/api/v3/fastag/annual-pass' \
--header 'Content-Type: application/json' \
--header 'Authorization: <Auth Token>' \
--data '{
"vehicleNumber": "HR03Y2887"
}'Input Parameters
Parameter | Description | Required |
|---|---|---|
Authorization | Your API key, passed as a bare token with no Bearer prefix. | Yes |
Content-Type | Must be application/json. | Yes |
vehicleNumber | Vehicle registration number in compact form, without spaces or separators. Case-insensitive. Example: HR03Y2887. | Yes |
Sample Response
Vehicle with one active tag and an Annual Pass.
{
"result": {
"message": "Vehicle Found",
"totalValidTags": 1,
"tags": [
{
"tagId": "34161FA8203289DA08FBF280",
"regNumber": "HR03Y2887",
"tid": "E2801105200074CDB5A80A9B",
"vehicleClass": "CAR/JEEP/VAN",
"tagStatus": "A",
"issueDate": "2021-09-04",
"excCode": "07",
"bankId": "607469",
"comVehicle": "F",
"npciRegNumber": "HR03Y2887",
"bankName": "KOTAK BANK"
}
],
"vahanCategory": "NON-COMMERCIAL",
"annualPassDetails": {
"passId": "RJMY1766689348498Y5",
"passType": "ANNUAL",
"tagId": "34161FA8203289DA08FBF280",
"vehicleClass": "VC4",
"tripLimit": "155",
"averageTripsTakenPerMonth": "6",
"passStartDate": "26-12-2025",
"passEndDate": "25-12-2026",
"passStatus": "ACTIVE",
"vehNumberEnc": "qWtNLBucagvcwDHMIQywUGEkWySkji+sxutvOb3tUC6FVs4wxyvdmezjPFFm8WQYTrao3ih2AV3TtyjQIYJ36uynAPS/k/hImFbwd6bbGKOpEqLTFUrIPFj9EI2CRycc0EKb03Jp57fhzMQ5ctctuUhYNwlYq+DIjSTnILhrxcQ=",
"vehNumberDec": "HR03Y2887"
}
}
}Vehicle with multiple tags and no Annual Pass. Note that annualPassDetails collapses to a single message field.
{
"result": {
"message": "Vehicle Found",
"totalValidTags": 3,
"tags": [
{
"tagId": "34161FA8203286141639A0A0",
"regNumber": "PB10DF0109",
"tid": "E28011052000785A61D30ADF",
"vehicleClass": "CAR/JEEP/VAN",
"tagStatus": "A",
"issueDate": "2024-03-30",
"excCode": "00",
"bankId": "606986",
"comVehicle": "F",
"npciRegNumber": "PB10DF0109",
"bankName": "STATE BANK OF INDIA"
},
{
"tagId": "34161FA820328E401652EC00",
"regNumber": "PB10DF0109",
"tid": "E280110520007946F35F0A36",
"vehicleClass": "CAR/JEEP/VAN",
"tagStatus": "I",
"issueDate": "2020-03-13",
"excCode": "06",
"bankId": "608032",
"comVehicle": "F",
"npciRegNumber": "PB10DF0109",
"bankName": "PAYTM PAYMENTS BANK"
},
{
"tagId": "34161FA820328E400FA2D3A0",
"regNumber": "PB10DF0109",
"tid": "E2003412012A1B000157662D",
"vehicleClass": "CAR/JEEP/VAN",
"tagStatus": "I",
"issueDate": "2020-02-25",
"excCode": "06",
"bankId": "608032",
"comVehicle": "F",
"npciRegNumber": "PB10DF0109",
"bankName": "PAYTM PAYMENTS BANK"
}
],
"vahanCategory": "NON-COMMERCIAL",
"annualPassDetails": {
"message": "Annual pass not found"
}
}
}Response Parameters
PARAMETER NAME | REQUIRED/OPTIONAL | DATA TYPE | DESCRIPTION |
|---|---|---|---|
result | Required | Object | Wrapper for the successful response payload. |
result.message | Required | String | Outcome of the lookup. Returned as Vehicle Found on success. |
result.totalValidTags | Required | Number | Count of tag records returned in tags. This is the size of the array, not a count of active tags. |
result.tags | Required | Array of Objects | All FASTags on record against the vehicle, including tags that are no longer in use. |
result.tags[].tagId | Required | String | Unique identifier of the FASTag. Uppercase hexadecimal. Use this to match a tag against annualPassDetails.tagId. |
result.tags[].regNumber | Required | String | Vehicle registration number the tag is issued against, normalised to upper case. |
result.tags[].tid | Required | String | Hardware identifier of the tag inlay. Uppercase hexadecimal. Distinct from tagId. |
result.tags[].vehicleClass | Required | String | Toll vehicle class in descriptive form, for example CAR/JEEP/VAN. This is a different representation from annualPassDetails.vehicleClass. |
result.tags[].tagStatus | Required | String | Current status of the tag. Observed values: A (active) and I (inactive). Treat any other single-character value as not active. |
result.tags[].issueDate | Required | String | Date the tag was issued, in YYYY-MM-DD format. |
result.tags[].excCode | Required | String | Two-digit exception code recorded against the tag. 00 indicates no exception. Observed values include 00, 06 and 07. |
result.tags[].bankId | Required | String | Numeric identifier of the issuer bank. |
result.tags[].bankName | Required | String | Name of the issuer bank, for example KOTAK BANK. |
result.tags[].comVehicle | Required | String | Commercial vehicle flag. T for commercial, F for non-commercial. |
result.tags[].npciRegNumber | Required | String | Registration number as held in the national toll registry. Normally identical to regNumber; compare the two if you need to detect a mismatch. |
result.vahanCategory | Required | String | Vehicle category from the national vehicle registry. Observed value: NON-COMMERCIAL. |
result.annualPassDetails | Required | Object | Annual Pass details. Contains the pass fields below when a pass exists, and only message when it does not. |
result.annualPassDetails.message | Optional | String | Present only when no pass exists. Returned as Annual pass not found. Absent when a pass is found. |
result.annualPassDetails.passId | Optional | String | Unique identifier of the Annual Pass. Present only when a pass exists — use this field to test whether a pass was found. |
result.annualPassDetails.passType | Optional | String | Type of pass. Observed value: ANNUAL. |
result.annualPassDetails.tagId | Optional | String | Identifier of the tag the pass is bound to. Matches one of the tagId values in tags. |
result.annualPassDetails.vehicleClass | Optional | String | Toll vehicle class of the pass in coded form, for example VC4. Not the same representation as tags[].vehicleClass. |
result.annualPassDetails.tripLimit | Optional | String | Total number of trips the pass permits, returned as a numeric string. |
result.annualPassDetails.averageTripsTakenPerMonth | Optional | String | Average trips consumed per month under the pass, returned as a numeric string. |
result.annualPassDetails.passStartDate | Optional | String | First day of pass validity, in DD-MM-YYYY format. |
result.annualPassDetails.passEndDate | Optional | String | Last day of pass validity, in DD-MM-YYYY format. |
result.annualPassDetails.passStatus | Optional | String | Current status of the pass. Observed value: ACTIVE. |
result.annualPassDetails.vehNumberDec | Optional | String | Registration number the pass is issued against, in plain text. |
Status Codes
CODE | REASON | MESSAGE |
|---|---|---|
200 | — | Vehicle Found |
400 | VALIDATION_ERROR | Vehicle number provided in the input payload is missing or invalid. |
400 | Bad Request | Unexpected end of JSON input |
401 | — | No API key found in request |
401 | — | Invalid authentication credentials |
404 | No record found | No FASTag or Annual Pass record found for the given vehicle number. |
404 | — | no Route matched with those values |
Rows with a — reason are returned by the gateway rather than the endpoint and therefore carry only a message, without the error envelope or a reason field.
Getting help
Please feel free to contact us if you have any questions, require clarification, or have ideas for how to make the documents or any of our services better. You can reach out to us at [email protected].