---
updatedAt: 2026-06-02T21:19:38.000Z
agentTools:
  projectIndex: https://docs.vouched.id/llms.txt
---

# TIN Verification

TIN Verification job.

Requires the `tinValidationEnabled` account feature; without it the request is rejected with a 403 `AccountConfigErrorType`.

Test mode is **not supported** for this endpoint. Unlike `POST /api/ssn`, the `x-test-request` header is read but unimplemented here, and sending `x-test-request: true` fails with a 500 `UnknownSystemError`. Do not send it.

When the result cannot be determined synchronously the response comes back with `status: pending` and `result.status: PENDING`; the final result arrives at your `callbackURL` and is also readable from `GET /api/tin/jobs/{id}` once `status` is `complete`.

<Callout icon="📘" theme="info">
  Accented and diacritic characters are supported. 

  Vouched automatically normalizes name fields before verification. Note that the TIN endpoint accepts only letters, digits, spaces, hyphens, and &; other punctuation (such as apostrophes in A'rreion) is replaced with a space before matching.
</Callout>

# OpenAPI definition

```json
{
  "openapi": "3.1.0",
  "info": {
    "version": "0.13.13",
    "title": "Vouched API",
    "description": "Official Vouched REST API.\n\n## Environments\n\nThe `servers` list below has two production hosts: `verify.vouched.id` (US) and\n`verify.eu.vouched.id` (EU). A separate **sandbox** deployment runs the same service with\n`SANDBOX_MODE` enabled, where only the identity-verification job endpoints are mounted —\n`GET`/`POST /api/jobs`, `GET`/`DELETE /api/jobs/{id}`, `GET /api/jobs/{id}/download` and\n`POST /api/jobs/session`. Every other endpoint **under `/api`** in this document returns **404**\nin sandbox, including AML, SSN, TIN, DOB, invites and CrossCheck.\n\nThe provider webhook receivers are the exception: `/api/tin/webhook`,\n`/api/dlv/webhook/license-validation`, `/v1/sendgrid/email/send` and `/v1/twilio/sms/send` are\nregistered outside the sandbox gate and remain available.\n",
    "x-logo": {
      "url": "https://i.pinimg.com/originals/88/29/2f/88292f8ffd6231d0c41634f2e707c34a.png",
      "altText": "Vouched logo"
    },
    "license": {
      "name": "Apache 2.0",
      "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
    }
  },
  "servers": [
    {
      "url": "https://verify.vouched.id",
      "description": "US (default)"
    },
    {
      "url": "https://verify.eu.vouched.id",
      "description": "EU"
    }
  ],
  "tags": [
    {
      "name": "tin",
      "description": "This is the section for TIN related jobs."
    }
  ],
  "paths": {
    "/api/tin/verify": {
      "post": {
        "description": "TIN Verification job.\n\nRequires the `tinValidationEnabled` account feature; without it the request is rejected with a 403 `AccountConfigErrorType`.\n\nTest mode is **not supported** for this endpoint. Unlike `POST /api/ssn`, the `x-test-request` header is read but unimplemented here, and sending `x-test-request: true` fails with a 500 `UnknownSystemError`. Do not send it.\n\nWhen the result cannot be determined synchronously the response comes back with `status: pending` and `result.status: PENDING`; the final result arrives at your `callbackURL` and is also readable from `GET /api/tin/jobs/{id}` once `status` is `complete`.",
        "summary": "TIN Verification",
        "operationId": "tinVerify",
        "security": [
          {
            "X-API-Key": []
          }
        ],
        "tags": [
          "tin"
        ],
        "parameters": [
          {
            "name": "content-type",
            "in": "header",
            "schema": {
              "type": "string",
              "default": "application/json"
            }
          },
          {
            "name": "accept",
            "in": "header",
            "schema": {
              "type": "string",
              "default": "application/json"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/tin_request"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/tin_response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "500": {
            "$ref": "#/components/responses/500"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "X-API-Key": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "The authentication private key"
      }
    },
    "schemas": {
      "error": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "\nError type code.\n- InvalidRequestError - The request is invalid.\n\n  - Parameters sent in the request are invalid.\n\n\n- FaceMatchError - The face match score was lower than the threshold.\n\n  - Category: faceMatch\n\n  - Faces obtained from the ID and Selfie images do not match.\n\n\n- NameMatchError - The name match score was lower than the threshold.\n\n  - The name provided by the user and the name extracted from the ID do not match.\n\n  - Eg: User Provided Name - Dave Smith, Extracted Name - David Smith\n\n\n- BarcodeMatchError - The barcode match score was lower than the threshold.\n\n  - The data provided by the user and the data extracted from the barcode do not match. \n\n  - Eg: User Provided Name - Dave Smith, Extracted Name - David Smith\n\n\n- BirthDateMatchError - The birth date match score was lower than the threshold.\n\n  - The birth date provided by the user and the data extracted from the ID do not match.\n\n  - Eg: User Provided DOB - 01/09/1992, Extracted DOB - 09/01/1992\n\n  - Eg: User Provided DOB - 11/09/1992, Extracted DOB - 12/09/1992\n\n\n- ExpiredIdError - The ID’s expiration date has passed.\n\n  - The expiration date extracted from the ID indicates that it has expired.\n\n- InvalidIdPhotoError - The ID is invalid.\n\n  - Category: id\n\n  - The image submitted does not qualify as an ID. The ID image may be of lower quality, have blur, glare or it may be too dark, and hence the data could not be extracted.\n\n- InvalidUserPhotoError - The user photo (selfie) is invalid.\n\n  - Category: selfie\n\n  - The image submitted does not qualify as a selfie.\n\n- BarcodeDetectError - The barcode could not be detected on the ID.\n- AuthenticationError - The request could not be authenticated.\n\n  - The key could not be verified.\n\n- NotFoundError - The requested resource does not exist, or is not visible to this account.\n- AccountConfigErrorType - The feature is not enabled for this account.\n- SSNAccountConfigErrorType - SSN verification is not enabled for this account. Returned by the SSN endpoints in place of `AccountConfigErrorType`.\n- SSNUnprocessableEntityErrorType - The eCBSV request contains incorrectly formatted or missing data.\n- UnknownSystemError - A unknown system error occurred.\n- LivenessSkippedError - Selfie liveness was skipped.\n- LivenessScoreError - The selfie liveness score was below the threshold.\n- LivenessCompletionError - The selfie liveness check did not complete.\n- DarkWebError - The dark web check result was below the threshold.\n- ipAddressError - The IP address check result was below the threshold.\n- AMLError - The AML screening result was below the threshold.\n- MissingIdentityErrorType - No identity document was supplied.\n- RestrictedIdDocumentError - The identity document did not meet the account's configured constraints.\n- CrosscheckIdentityError - The CrossCheck identity score was below the threshold.\n- StableSelfiePatternError - An unstable selfie pattern was detected.\n- StableIdPatternError - An unstable ID pattern was detected.\n- DocumentVoidedError - The document has been voided.\n- DlvError - The ID did not pass Driver's License Verification.",
            "enum": [
              "InvalidRequestError",
              "FaceMatchError",
              "NameMatchError",
              "BarcodeMatchError",
              "BarcodeDetectError",
              "BirthDateMatchError",
              "ExpiredIdError",
              "InvalidIdPhotoError",
              "InvalidUserPhotoError",
              "AuthenticationError",
              "NotFoundError",
              "AccountConfigErrorType",
              "SSNAccountConfigErrorType",
              "SSNUnprocessableEntityErrorType",
              "UnknownSystemError",
              "LivenessSkippedError",
              "LivenessScoreError",
              "LivenessCompletionError",
              "DarkWebError",
              "ipAddressError",
              "AMLError",
              "MissingIdentityErrorType",
              "RestrictedIdDocumentError",
              "CrosscheckIdentityError",
              "StableSelfiePatternError",
              "StableIdPatternError",
              "DocumentVoidedError",
              "DlvError"
            ]
          },
          "message": {
            "type": "string",
            "description": "Details on the occurring error."
          },
          "warning": {
            "type": "boolean",
            "description": "Is this a warning?"
          },
          "suggestion": {
            "example": "John Smith",
            "description": "A suggestion for matching name.",
            "type": "string"
          }
        }
      },
      "errors": {
        "type": "object",
        "description": "One or more errors describing why the request failed.",
        "required": [
          "errors"
        ],
        "properties": {
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/error"
            }
          }
        }
      },
      "token_error_response": {
        "type": "object",
        "description": "Returned by the JWT middleware, which runs ahead of all routers and so can answer any path. Note this is a single `error` string, not the `errors` array used by the rest of the API.",
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "Token expired",
              "Token malformed"
            ]
          }
        }
      },
      "verification_property": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Name of the property"
          },
          "value": {
            "type": "string",
            "maxLength": 1024,
            "description": "Value of the property"
          }
        },
        "required": [
          "name",
          "value"
        ]
      },
      "verification_properties": {
        "type": "array",
        "description": "Optional list of arbitrary customer supplied properties, echoed back on the job response and omitted from it when none were sent. Intended for attributing the result in your own system — send an identifier you can look up rather than the record itself. At most 5 entries. The same values are also returned for this job by `GET /api/jobs` under `request.properties`, where they are `null` rather than omitted when none were sent.",
        "maxItems": 5,
        "items": {
          "$ref": "#/components/schemas/verification_property"
        }
      },
      "tin_request": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "description": "First name linked to the TIN number in the request. The first 40 characters of the combined first and last names are used in the matching process. Must only contain letters, spaces, hyphens, and ampersands.",
            "minLength": 1
          },
          "lastName": {
            "type": "string",
            "description": "Last name linked to the TIN number in the request. The first 40 characters of the combined first and last names are used in the matching process. Must only contain letters, spaces, hyphens, and ampersands.",
            "minLength": 1
          },
          "tinType": {
            "type": "string",
            "description": "ITIN",
            "enum": [
              "ITIN"
            ]
          },
          "tin": {
            "type": "string",
            "description": "The full 9 digits of the TIN in the request. Do not include dashes or spaces."
          },
          "callbackURL": {
            "type": "string",
            "description": "Upon completion of a pending job, Vouched will POST the job results to the defined webhook."
          },
          "phone": {
            "type": "string",
            "description": "The phone number of the individual for this request. Formatted in E.164 formatting for international numbers including the leading plus sign. For example +12065551111"
          },
          "properties": {
            "$ref": "#/components/schemas/verification_properties"
          }
        },
        "additionalProperties": false,
        "required": [
          "firstName",
          "lastName",
          "tinType",
          "tin",
          "callbackURL",
          "phone"
        ]
      },
      "tin_response": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Job identifier. Pass this as `{id}` to `GET /api/tin/jobs/{id}`."
          },
          "status": {
            "type": "string",
            "description": "Job execution status. `pending` means the Compliancely result has not arrived yet — poll `GET /api/tin/jobs/{id}` (or wait for the `callbackURL` webhook) until this becomes `complete`.",
            "enum": [
              "pending",
              "complete"
            ]
          },
          "completed": {
            "type": "boolean"
          },
          "submitted": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "request": {
            "type": "object",
            "properties": {
              "firstName": {
                "type": "string"
              },
              "lastName": {
                "type": "string"
              },
              "tinType": {
                "type": "string"
              },
              "callbackURL": {
                "type": "string"
              },
              "phone": {
                "type": "string"
              },
              "properties": {
                "$ref": "#/components/schemas/verification_properties"
              }
            }
          },
          "result": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "description": "MATCH | NO_MATCH | PENDING",
                "enum": [
                  "MATCH",
                  "NO_MATCH",
                  "PENDING"
                ]
              },
              "tinType": {
                "type": "string",
                "description": "ITIN"
              }
            }
          }
        }
      }
    },
    "responses": {
      "400": {
        "description": "InvalidRequestError - The request is invalid. An aborted or oversized request is answered with this status and an empty body instead of the envelope below.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/errors"
            },
            "example": {
              "errors": [
                {
                  "type": "InvalidRequestError",
                  "message": "Invalid request"
                }
              ]
            }
          }
        }
      },
      "401": {
        "description": "The request could not be authenticated. Credential rejection returns an `AuthenticationError` envelope; a malformed or expired bearer token is rejected earlier by the JWT middleware and returns `{ \"error\": \"Token expired\" }` or `{ \"error\": \"Token malformed\" }` instead.",
        "content": {
          "application/json": {
            "schema": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/errors"
                },
                {
                  "$ref": "#/components/schemas/token_error_response"
                }
              ]
            },
            "example": {
              "errors": [
                {
                  "type": "AuthenticationError",
                  "message": "Unauthorized access"
                }
              ]
            }
          }
        }
      },
      "403": {
        "description": "AccountConfigErrorType - The feature is not enabled for this account. SSN operations return `SSNAccountConfigErrorType` instead and document their own 403.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/errors"
            },
            "example": {
              "errors": [
                {
                  "type": "AccountConfigErrorType",
                  "message": "<Feature> has not been enabled for this account"
                }
              ]
            }
          }
        }
      },
      "500": {
        "description": "UnknownSystemError - A unknown system error occurred.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/errors"
            },
            "example": {
              "errors": [
                {
                  "type": "UnknownSystemError",
                  "message": "Oops, we encountered a problem"
                }
              ]
            }
          }
        }
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "APIs",
      "tags": [
        "jobs",
        "invites",
        "crosscheck",
        "aml",
        "ssn",
        "tin",
        "dob",
        "documents"
      ]
    },
    {
      "name": "Internal",
      "tags": [
        "client",
        "digital-id",
        "admin",
        "webhooks"
      ]
    }
  ]
}
```