REST API
Run a verification end-to-end with the SheerID REST API — start a verification, submit user data, and handle success, document upload, and pending outcomes. See our REST API reference for full endpoint details.
Basics
The SheerID API is organized around REST.
Base URL
The base URL for the SheerID REST API is https://services.sheerid.com/rest/v2/.
The current version is 2.0.0.
Authentication
Certain requests use a Bearer Token for authentication.
Static API tokens can be managed within MySheerID by clicking on your user icon and choosing Access Management:
We also support OAuth2 with dynamically generated tokens. For more information, see API Tokens
An API token is used by specifying it as a Bearer token in an Authorization header on an API request:
GET /rest/v2/info HTTP/1.1
Host: services.sheerid.com
Content-Type: application/json
Authorization: Bearer <YOUR_ACCESS_TOKEN>
What You’ll Build
In this tutorial you’ll run a verification from start to finish using the SheerID REST API: start a verification, submit a user’s information, and handle each possible outcome — instant success (with a reward code), document upload, and pending review. By the end you’ll understand the core request/response loop of a SheerID API integration.
Prerequisites
- A published verification program and its
programId(create one in MySheerID). - An API access token — see Authentication and API Tokens. New integrations should use dynamic OAuth tokens; static tokens are deprecated and stop working August 1, 2026.
- Test Mode enabled so you can simulate outcomes — see Test Your Program.
Terminology
Before you begin, get familiar with the attributes you’ll encounter in this process.
apiToken
A bearer token sent in the Authorization header to authenticate certain requests. See API Tokens to create and manage them.
programId: Retrieve your programId from your Program tab in MySheerID.
verificationId
Unique identifier for the ongoing verification.
submissionUrl
The URL where you will submit the required information for the the next step in the verification, e.g., docUpload.
currentStep
The current step in the verification.
errorIds
If applicable, an array of error IDs indicating a problem with the verification.
segment
The primary segment of the program, e.g., student, military. This value does not vary but is returned for convenience.
subSegment
The subsegment for the current verification, e.g., activeDuty is a possible subsegment in a military verification. This varies by the choice a user makes during a verification, but will always be one of the available subSegments configured for your program.
statusUrl
The URL to poll to determine the result of the document review.
For details on the endpoints and parameters in this tutorial, see our REST API Reference.
Retrieve Theme
If you would like to use the CSS and messaging that you configured at MySheerID, then you must first fetch the
program theme. To do this, make a GET request to the /program/{programId}/theme endpoint:
GET /rest/v2/program/<YOUR_PROGRAM_ID>/theme HTTP/1.1
Host: services.sheerid.com
Content-Type: application/json
See Program Theme for more information about what is contained in the program theme object, and Get Program Theme for the detailed API reference.
Start a Verification
Authorization: Bearer token on this request) and then hand the user to the hosted form. See Secure Verification Creation.
Now we need to begin a verification. This will retrieve what kind of segment you will be verifying against (Student, Active Military, Inactive Military, Teacher, etc.).
To retrieve the initial step for your flow, make the following POST request:
POST /rest/v2/verification HTTP/1.1
Host: services.sheerid.com
Content-Type: application/json
Authorization: Bearer <YOUR_ACCESS_TOKEN>
{
"programId": "<YOUR_PROGRAM_ID>"
}
Response:
{
"verificationId": "111111111111111111111111", // Verification ID that should be used for all future calls
"currentStep": "collectStudentPersonalInfo", // The step in the verification flow the current verification is on
"submissionUrl": "https://services.sheerid.com/rest/v2/verification/111111111111111111111111/step/collectStudentPersonalInfo", // The URL to use to complete the current step
"errorIds": [],
"segment": "student",
"subSegment": null
}
At this point a verification has begun and can be referenced with the verificationId, in the example case 111111111111111111111111. This ID will be used for all
future interactions with this verification ID.
Verify a User
Now that we have our step (in our demo case we are verifying a student, so our step is collectStudentPersonalInfo), we can submit a verification subject to verify.
We will be submitting a student for verification, so we will need to fill out this structure:
{
"firstName": "",
"lastName": "",
"birthDate": "YYYY-MM-DD",
"email": "",
"organization": {
"id": 0,
"name": ""
}
}
Schemas for all verification subjects can be found here.
organization.id is SheerID’s identifier for the school/organization — not a value you make up. Look it up first with the organization search endpoint; see Searching for Organizations.
Once all data has been collected, make a POST call to the URL collected in the previous step’s submissionUrl response with the data, e.g.
POST /verification, then submit to the returned submissionUrl. There is also a combined endpoint — POST /verification/program/{programId}/step/collectStudentPersonalInfo — that starts and submits in one call (used in Searching for Organizations). Either works; pick one and stay consistent.
{
"firstName": "Randy",
"lastName": "Random",
"birthDate": "2000-01-01",
"email": "[email protected]",
"organization": {
"id": 1,
"name": "Organization name"
}
}
In Test Mode, the outcome is driven by the input values, not by hitting real data sources. The example above returns an instant success; submitting REJECTED as the firstName instead routes the verification to the docUpload step. Other fields (notably birthDate) and other firstName keywords trigger the remaining outcomes.
For the full set of Test Mode trigger values, see the Testing guide (the single source of truth), or the Test Your Program knowledge base article.
Success
If the verification was successful, then you will receive a response like this:
{
"verificationId": "111111111111111111111111", // Verification ID that should be used for all future calls
"currentStep": "success", // The step in the verification flow the current verification is on
"rewardData": { "rewardCode": "REWARD" }, // Preferred: a map of all reward codes/values for this verification
"rewardCode": "REWARD", // Deprecated: the single reward code, kept for backward compatibility
"errorIds": [],
"segment": "student", // The current segment we are verifying
"subSegment": null // The current subsegment we are verifying if applicable
}
Read the reward from rewardData (preferred — it supports multiple codes/values per verification); the top-level rewardCode is deprecated and kept only for backward compatibility. See Offer Codes for the full reward model. After providing the code to your user, you’re done!
Document Upload & Review
If the verification was unsuccessful, then you will need to collect documentation to prove the user is part of the verification segment, and submit it to SheerID. In this situation, the document upload response will be returned after submitting the personal info of the user.
For example:
{
"verificationId": "111111111111111111111111", // Verification ID that should be used for all future calls
"currentStep": "docUpload", // The step in the verification flow that the current verification is on
"submissionUrl": "https://services.sheerid.com/rest/v2/verification/111111111111111111111111/step/docUpload", // The URL to use to complete the current step
"errorIds": [],
"segment": "student", // The audience segment targeted in your program
"subSegment": null // The audience subsegment, if applicable
}
docUpload step required including them in body of a multipart-form-data request, and included a doc upload token. That way of uploading documents is deprecated. Be sure to follow the steps described below when uploading documents to SheerID.
After collecting the documents to be uploaded, initiate the process by making a POST request to the submissionUrl provided in the doc upload response. The request should include a Content-Type header of application/json. The body of the request should be a JSON payload that includes the names, sizes, and MIME types of the files being uploaded. See the Doc Upload API documentation for details.
Uploads are validated on type, size, and count. Accepted documents are common image formats (e.g. image/jpeg, image/png) and application/pdf. A file that violates a limit comes back as a recoverable error — unsupportedDocMimeType, invalidFileSizeMax, invalidFileSizeEmpty, or invalidNumberOfFiles (see Errors) — so validate on your side before uploading. For the exact current size and count limits, see the Doc Upload API reference.
Example request:
POST /rest/v2/verification/<YOUR_VERIFICATION_ID>/step/docUpload HTTP/1.1
Host: services.sheerid.com
Content-Type: application/json
Content-Length: 207
{
"files": [
{
"fileName": "foo.jpg",
"mimeType": "image/jpeg",
"fileSize": 1111
},
{
"fileName": "bar.png",
"mimeType": "image/png",
"fileSize": 2222
}
]
}
The response will contain a documents array that includes an object for each document referenced in the request, in the same order. Each object in that array will include an upload URL for that document.
The response will also contain a submission URL, to be used after all files have been uploaded.
Example response:
{
"verificationId": "5c70719d2145e32d7d37af8e",
"currentStep": "docUpload",
"errorIds": [],
"segment": "student",
"subSegment": null,
"locale": "en-US",
"country": "US",
"documents": [
{
"documentId": "1234",
"status": "PENDING",
"mimeType": "image/jpeg",
"fileSize": 1111,
"uploadUrl": "https://upload.example.com/1111",
"errors": []
},
{
"documentId": "1234",
"status": "PENDING",
"mimeType": "image/png",
"fileSize": 2222,
"uploadUrl": "https://upload.example.com/2222",
"errors": []
}
],
"submissionUrl": "https://services.sheerid.com/rest/v2/verification/5c70719d2145e32d7d37af8e/step/completeDocUpload"
}
For each file to be uploaded, send a PUT request to the uploadUrl for that file, with the contents of the file itself as the request body.
Be sure to include a Content-Type header that matches the mimeType, and a Content-Length header that matches the fileSize.
Confirm that a 200 status is returned for each uploaded file.
Note: If you would like to simulate receiving different responses for document uploads using a testMode Program, please see the special files listed here.
Once all files have been uploaded and a 200 response has been returned for each, send a POST request to the submissionUrl found in the response described above, with an empty request body.
Pending
If documents have been successfully uploaded to SheerID for review, then you will receive a response that looks like this:
{
"verificationId": "62bf6bd5e61aee18c9783b10",
"currentStep": "pending",
"errorIds": [],
"segment": "teacher",
"subSegment": null,
"locale": "en-US",
"country": "US",
"statusUrl": "https://services.sheerid.com/rest/v2/verification/62bf6bd5e61aee18c9783b10",
"maxReviewTime": "20_MIN",
"estimatedReviewTime": "A_FEW_MINUTES",
"lastResponse": {
"documents": [],
"verificationId": "62bf6bd5e61aee18c9783b10",
"currentStep": "docUpload",
"errorIds": [],
"segment": "teacher",
"subSegment": null,
"locale": "en-US",
"country": "US",
"submissionUrl": "https://services.sheerid.com/rest/v2/verification/62bf6bd5e61aee18c9783b10/step/docUpload",
"rejectionReasons": [],
"maxReviewTime": "20_MIN",
"estimatedReviewTime": "A_FEW_MINUTES"
}
}
The statusUrl can be used to retrieve the current status of the verification. This endpoint can be polled to watch for changes to the verification state.
If the document review is still in progress, then you will continue to get the pending response.
If the document review is completed and marked successful (the document proved the user was associated with the segment), then you will receive the success response.
If the document review is completed and marked rejected (the document did not prove the user was associated with the segment), then you will receive the docUpload response, which indicates
that the user may attempt to verify by uploading additional documents (repeating the process above). There is a limited number of times that documents can be uploaded for a verification.
Getting Current Status
The current status of a verification can be retrieved at any time by making a GET request to https://services.sheerid.com/rest/v2/verification/{verificationId}. The
response from this endpoint will match the responses you get a various points through the flow (success, docUpload, pending, error, etc.). This endpoint can be
used to continue a verification that was halted at any point.
Get Verification Details
At any point you can fetch the full record of a verification — including the latest response and the submitted person info — with a GET to the details endpoint.
Request:
GET /rest/v2/verification/<YOUR_VERIFICATION_ID>/details HTTP/1.1
Host: services.sheerid.com
Authorization: Bearer <YOUR_ACCESS_TOKEN>
Response:
{
"programId": "5c0d45f251cc4d31b7a222ca",
"created": 1552444306323,
"updated": 1552444363224,
"lastResponse": {
"currentStep": "pending",
"verificationId": "5c886b92b107283f54d84854",
"statusUrl": "https://services.sheerid.com/rest/v2/verification/5c886b92b107283f54d84854",
"errorIds": [],
"segment": "student",
"subSegment": null
},
"personInfo": {
"firstName": "Jane",
"lastName": "Doe",
"email": "[email protected]",
"birthDate": "1990-01-01",
"metadata": null,
"organization": {
"id": 4597,
"name": "ALBANY LAW SCHOOL"
}
},
"docUploadRejectionCount": 0
}
See Get Verification Details for the full schema.
Complete Example
Putting it together, a typical end-to-end verification is:
- (Optional) Retrieve the theme —
GET /rest/v2/program/<programId>/themeto render your form with the program’s configured styling and messaging. - Start the verification —
POST /rest/v2/verificationwith{ "programId": "<programId>" }; keep the returnedverificationIdandsubmissionUrl. - Submit the user’s info —
POSTthe collected fields to thesubmissionUrl. - Handle the
currentStepin the response:success→ give the user therewardCode. Done.docUpload→ follow Document Upload & Review: initiate, PUT each file, thencompleteDocUpload.pending→ poll thestatusUrl(or use webhooks) until the verification resolves.
- (Anytime) Inspect a verification —
GET /rest/v2/verification/<verificationId>/details.
Rate limits, retries & environments
- Environment. There is no separate sandbox host — every call goes to
https://services.sheerid.com/rest/v2/. To simulate verification outcomes without consulting live data sources, enable Test Mode on your program (see Test Your Program). - Timeouts. Allow up to 11 seconds for a verification response. Our sources usually respond instantly, but this cushion absorbs occasional upstream latency.
- Rate limits &
429s. A429is overloaded: onlyapiRateLimitExceededis transient and safe to retry with exponential backoff — the per-person limits are not retryable. Drive retry logic off theerrorId, never the bare status. See Retry and backoff. - Idempotency.
POST /verificationis not idempotent — each call starts a new verification. Persist the returnedverificationIdand reuse it rather than re-creating.
Errors
Any response while interacting with the API could be an error response. There are two types of possible errors: recoverable and non-recoverable.
Recoverable Errors
A recoverable error will include the step the verification was on before the error occurred. So if you were attempting to submit a student subject for the collectStudentPersonalInfo step, you could receive this response:
{
"verificationId": "111111111111111111111111", // Verification ID that should be used for all future calls
"currentStep": "collectStudentPersonalInfo", // The step in the verification flow the current verification is on
"errorIds": [
// The errors that occurred when attempting the step
],
"segment": "student", // The current segment you are verifying
"subSegment": null, // The current subsegment you are verifying if applicable
"submissionUrl": "https://submission-url.com" // The URL to submit the person data to
}
The errorIds will indicate what went wrong, but since the currentStep is not error it means the issue could be corrected. These errors occur when bad data was
supplied, e.g. an invalid birth date, invalid email, invalid organization, etc.
Messages
Recoverable errors can be caused by invalid entries from the user, so the messaging that should be shown can be found in the program theme.
of the response that was returned. The messaging found in the errorId section of the messages should be appropriate to show users.
Example
When submitting a student subject for the collectStudentPersonalInfo if you sent this request:
{
"firstName": "First",
"lastName": "Last",
"birthDate": "1-1-1",
"email": "notValidEmail,com",
"organization": {
"id": 1,
"name": "Organization name"
}
}
You would receive the following errorIds:
{
"verificationId": "111111111111111111111111", // Verification ID that should be used for all future calls
"currentStep": "collectStudentPersonalInfo", // The step in the verification flow the current verification is on
"errorIds": [
"invalidBirthDate",
"invalidEmail"
],
"segment": "student",
"subSegment": null
}
This lets you know that you need to perform the collectStudentPersonalInfo step again, and you should find the invalidBirthDate and invalidEmail messages in the
program theme to find the message to display to the user.
Non Recoverable Errors
A non recoverable error will have error as the currentStep and will provide both a list of errorIds as well as a systemErrorMessage that can be used to determine
what caused the failure to assist with debugging. An example error response would look like this:
{
"verificationId": "111111111111111111111111", // Verification ID that should be used for all future calls
"currentStep": "error", // The step in the verification flow the current verification is on
"errorIds": [
// The errors that occurred when attempting the step
],
"systemErrorMessage": "Debugging message", // A description of the cause for the error to aid with debugging
"segment": "student", // The current segment we are verifying
"subSegment": null, // The current subsegment we are verifying if applicable
"submissionUrl": "https://submission-url.com" // The URL to submit the person data to
}
These errors occur when programs or verifications are not found, when internal SheerID errors occur, or when a step can not be completed for a non-user related reason.
Messages
The supplied errorIds can be used to look up the user facing messages in the program theme just like for recoverable errors, however
these can potentially be much more generic messages and difficult to understand. So to provide feedback for the integrator, the systemErrorMessage property can be used
to understand what went wrong. These messages are NOT intended to be displayed to users, they are only for the integrators benefit.
Example
When submitting a student subject for the collectStudentPersonalInfo step, if you sent this request:
{
"firstName": "First",
"lastName": "Last",
"birthDate": "1-1-1",
"email": "notValidEmail,com",
"invalidKey": "something"
}
You would receive the following error response:
{
"verificationId": "111111111111111111111111", // Verification ID that should be used for all future calls
"currentStep": "error", // The step in the verification flow the current verification is on
"errorIds": [
"invalidRequest"
],
"systemErrorMessage": "Unexpected property 'invalidKey', expected one of: firstName, lastName, birthDate, email, organization, metadata"
}
This lets you know you need to change the structure of your student subject request. Look
up the invalidRequest error in the program theme to find the message to show to the user. The systemErrorMessage tells you that you need to remove the invalidKey property
and only use the provided allowed keys.
Advanced & Reference
The following details are not part of the basic verification flow but are useful for richer integrations.
Program Theme
The program theme object contains all theme and messaging information that was configured for a program in the self-service tool at MySheerID. The theme includes a full CSS stylesheet that can be included when rendering the form (as long as CSS selectors match), and any messaging that should be used throughout the verification process, including field labels, success messages, etc.
Internationalization (i18n)
The program theme contains an intl property which is a structured JSON object containing translated messaging to use when rendering the forms to collect the data
necessary for the verification flow. This object will also include custom messaging that was configured in the self-service tool.
ErrorId
The errorId property under the intl property can be used to find error messaging to display to users when a given error is thrown. Any time a response has an
errorIds property, it means an error occurred and appropriate messaging should be looked up here in the program theme based on the error ID that was returned.
Custom CSS
The customCss property on the program theme contains a CSS stylesheet as it was configured in the self-service tool. This is heavily reliant on certain selectors
existing on the page, so it may or may not be useful when not using the JavaScript library.
Next Steps
- Webhooks — get notified of verification outcomes instead of polling.
- Conversion Tracking — measure verified conversions.
- JavaScript Library — the embeddable form most integrations use.
- REST API Reference — full endpoint and schema reference.
Related REST guides
Generate an API Client
Generate a typed API client from the SheerID OpenAPI spec — a TypeScript walkthrough plus links for 50+ languages.
Secure Verification Creation
Pre-generate a verification with an API token, then redirect the user to the hosted form.
Submitting CVEC Numbers for University Student Verifications in France
Using a new instant source for French university students which uses CVEC numbers

