Introduction
Welcome to the VerifyInvestor.com API documentation. This document is a guide to getting started with the VerifyInvestor.com API, along with a reference of all endpoints and methods. In order to begin using the API, please contact us at accounts@verifyinvestor.com.
We maintain separate API and documentation for LITE API and Embedded API. Please contact us for access to LITE or Embedded API, even if you already have access to the Regular API.
Once you've been granted API access, you'll be able to view your API account
details on the VerifyInvestor.com website at
https://www.verifyinvestor.com/settings. API accounts have two tokens, an "API
Token" and a "User Authorization Token". The API token is private, and used
to authenticate all requests to API endpoints. The user authorization token is
public, and is used to generate links for new users signing up, or existing
users wanting to grant your application access to their data. Unless otherwise
specified, all endpoints respond with data in JSON format, so make sure to set a
Content-Type
header to application/json
.
This base URL for this version of the API is at https://www.verifyinvestor.com/api/v1.
Overview
These are the general steps for issuing a verification using the API, which are covered in more detail in subsequent sections.
- From your application, redirect your user to our User Authorization URL. This requires a User Authorization Token and not an API Token.
- Your user grants access to your application and is redirected to the "Redirect URL" you have in your account Settings.
- Create a Verification Request for that user using our API and receive an "Investor URL".
- Redirect your user to the Investor URL where they can fill out the verification form and submit it for review.
- If you provided a specific Redirect URL in the verification request API call, a button that redirects your user there will be presented.
Integration logic workflow charts are available to help you with your implementation. It is highly recommended to start with the Basic Integration Flowchart and use the features requiring the Advanced Flowchart as needed.
Advanced Integration Flowchart
Verification Request Status and Reminders Schedule
Available Servers
We've provided a staging server for you to test your integration before using our production server. Please note that your API Token and User Authorization Token are different on the staging and production servers.
To obtain credentials for the Staging environment, please contact accounts@verifyinvestor.com.
Staging Server
This server can be used for testing and matches our Production server. https://verifyinvestor-staging.herokuapp.com
Production Server
Once you are confident in your integration with the staging environments, please contact support@verifyinvestor.com to get access to the production environment. https://www.verifyinvestor.com
Authentication
To authenticate, use this code:
curl GET "https://www.verifyinvestor.com/api/v1" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json"
Make sure to replace
YOUR_API_TOKEN_HERE
with your API key. The above command returns JSON structured like this:
{
"version": "1.1",
"current_time": "2018-01-11T15:28:38.972-08:00",
"documentation_url": "https://www.verifyinvestor.com/docs/api-v1.pdf"
}
All API requests must be performed via HTTPS. Never send your API token over the wire with a plain HTTP request (not only is it insecure, it won't even work). To authenticate requests, simply include the header:
Authorization: Token YOUR_API_TOKEN_HERE
User Authorization
To authorize a user, provide them a link like:
https://www.verifyinvestor.com/authorization/YOUR_USER_AUTHORIZATION_TOKEN_HERE?identifier=abc123
Make sure to replace
YOUR_USER_AUTHORIZATION_TOKEN_HERE
with your User Authorization Token. Additional params may also be passed:
https://www.verifyinvestor.com/authorization/YOUR_USER_AUTHORIZATION_TOKEN_HERE?identifier=abc123&first_name=FirstName&last_name=LastName
When your users want to create a VerifyInvestor.com account (or want to grant
your application access to their existing account), you must send them to a
specified link containing your "User Authorization Token". This link must also
contain a unique identifier from your system, so you can connect their account
in your application to the vi_user_id
you will receive after they authorize
your application. You'll likely want to use something like an ID or email
address for the unique identifier, and they should not be reused. This link
should be in the format
https://www.verifyinvestor.com/authorization/YOUR_USER_AUTHORIZATION_TOKEN_HERE?identifier=abc123
where 'abc123' is just an example identifier that you should replace with your
own.
If the user already has an account and is signed in, they will be prompted to grant your application access to their data. If they are not signed in, they will be given the option to create a new account, or sign in to an existing account. If the user has already granted your application access, they will be redirected to your application as if they just completed the authorization process that follows.
You can help speed up the account creation process for new users by
pre-populating some fields you may already have in your database. To do so,
simply pass whatever fields you'd like pre-populated to the /authorization
link, like this:
https://www.verifyinvestor.com/authorization/YOUR_USER_AUTHORIZATION_TOKEN_HERE?identifier=abc123&first_name=FirstName&last_name=LastName.
The available options are:
first_name
last_name
email
identifier
legal_name
portal_name
(optional parameter if you are providing a white-labeled service or acting on behalf of a 3rd party)redirect_url
(optional parameter if you want the user redirected to a different URL than specificed in your account settings)
After a user authorizes your application, they will be sent to the "Redirect
URL" specified under your account Settings (unless specified in the params),
along with a vi_user_id
parameter, and the identifier
parameter you
originally sent. The vi_user_id
should be saved in your system, as it is used
to make calls to the VerifyInvestor.com system for that user's information.
In the event that you do not capture the vi_user_id
,
there is an API endpoint for requesting it by providing the identifier used in
the authorization.
Once you have the authorization, you can create a verification request and check statuses for the user by using the endpoints described below.
Specifying a Portal Name or Requesting Party
If you pass a portal_name
, the user will be authorized specifically to that
portal name, and you should use the same portal_name
when creating a
verification request (or they will see the default name for your issuer
account). You may authorize the same user for multiple portal names, and one
user may have concurrent verification requests for different portal names. If
you've already authorized a user previously (with or without a portal name), you
should re-authorize that user for any new portal names. Users may have multiple
legal names under one account, and these are authorized on a per portal name
basis. A user will have to authorize existing legal names they have (if
currently accredited) for any new portal names.
Users
Get all Users
To authenticate, use this code:
curl GET "https://www.verifyinvestor.com/api/v1/users" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json"
The above command returns a
200
and JSON structured like this:
[
{
"id": 135,
"first_name": "Violet",
"last_name": "Howard",
"email": "violet.howard44@example.com"
}
]
GET /api/v1/users
Displays a list of users who have authorized your application.
Response Code | Meaning |
---|---|
200 OK |
Users retrieved |
Get a User
curl GET "https://www.verifyinvestor.com/api/v1/users/135?legal_name=legal%20name%201" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json"
The above command returns a
200
and JSON structured like this:
{
"id": 135,
"first_name": "FirstName",
"last_name": "LastName",
"email": "name@example.com",
"meta": "This contains useful information about this endpoint including changes and updates."
"authorized_parties":
[
{
"name": null, # This represents you, the issuer, and is the default 'authorized party'.
"identifier": "abc123",
"authorized_legal_names": [ "LEGAL NAME 1", "ENTITY 1" ]
},
{
"name": "Some 3rd Party", # This may be a portal name or a 3rd party authorization.
"identifier": "91",
"authorized_legal_names": [ "ENTITY 2" ]
}
],
"legal_profile": {
"name": "legal name 1", # the legal name you provided
"verify_investor_legal_name": "LEGAL NAME 1", # the legal name as we store it at VerifyInvestor.com
"meta": "It is recommended that you store the VerifyInvestor's spelling of the legal name if different than what you provided.",
"verified_accredited_expires_at" : "2018-09-18", # will have a date if already verified as accredited or be nil if the investor is unverified
"authorized_parties": [
{
"name": null,
"identifier": "abc123"
}
]
}
}
GET /api/v1/users/:id
Displays a user who has authorized your application and 3rd parties through you. You can also check for the user's id by the original identifier you passed for their authorization (see the following API call below).
This endpoint can inform you if a user has been verified as accredited or not by
VerifyInvestor.com, if you provide a legal_name
param. The status will be
returned under legal_profile
. We use "fuzzy" logic to match the legal name you
provide with those associated to the investor's account. We automatically
capitalize all letters and will squash commas, hyphens, and periods when
matching. We'll also swap name orders, e.g., "first-name last-name" should match
positively with "last-name, first-name".
Query Parameters
Parameter | Default | Description |
---|---|---|
legal_name | Optional paramter but required to check the verification status of the user. |
Response Code | Meaning |
---|---|
200 OK |
Found user |
404 Not Found |
User does not exist, or has not authorized your application |
Verification Requests
Create Verification Request
Create a verification request:
curl -X POST "https://www.verifyinvestor.com/api/v1/users/135/verification_requests" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"issuer_email" : "violet.howard44%40@example.com",
"portal_name" : "Portal Name",
"deal_name" : "Investment Deal",
"legal_name": "Legal Name 1",
"redirect_url" : "http://www.portalwebsite.com/investor?param=3",
"webhook_url" : "http://www.portalwebsite.com/webhook"
}'
The above command returns a
201
and JSON structured like this:
{
"id": 90,
"waiting_for_info": true | false,
"redirect_url": "URL_TO_RETURN_INVESTOR_TO",
"portal_name": "Portal Name",
"deal_name": "Investment Deal",
"investor_url": "http://verifyinvestor.com/investor/verification-requests/90/verification-method",
"investor": {
"id": 135
},
"investor_url": "URL_TO_SEND_INVESTOR_TO"
}
If this user already has pending verification request with the same portal and legal names, a
422
and JSON structured like this is returned:
{
"error": "A pending verification request already exists.",
"pending_verification_request": {
"id": 90,
"redirect_url": "URL_TO_RETURN_INVESTOR_TO",
"portal_name": null,
"deal_name" : null,
"investor_url": "http://verifyinvestor.com/investor/verification-requests/90/verification-method",
"investor": {
"id": 135
}
}
}
POST /api/v1/users/:id/verification_requests
Creates a new verification request for the specified user.
Query Parameters
Parameter | Default | Description |
---|---|---|
portal_name | Optional, but the user must have already authorized the portal name. | |
deal_name | Optional, if you pass a deal name, it will be identified to the investor so that they know what deal this verification is for. | |
legal_name | Optional, if you pass a legal name, it will auto-filled for the investor, but they will remain able to change it if needed. | |
redirect_url | Optional, if you want a specific redirect URL to be redirected back, you can pass that in here | |
webhook_url | Settings-specified | Optional, if you pass a webhook url, webhook callbacks will POST to that url for this specific verification request. You must have an account webhook url set as default for this to work. |
issuer_email | Optional, the email address of the person this verification is being requested on behalf of, if applicable. |
Response Code | Meaning |
---|---|
201 Created |
Verification request created |
404 Not Found |
User does not exist, or has not authorized your application |
403 Forbidden |
Request couldn't be processed, likely due to a pending verification request or unauthorized portal name |
422 Unprocessable Entity |
Request couldn't be processed, due to, for example, an invalid issuer_email |
AML/KYC
Create an AML/KYC verification request:
curl -X POST "https://www.verifyinvestor.com/api/v1/users/135/verification_requests/aml_kyc" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"issuer_email" : "violet.howard44%40@example.com",
"portal_name" : "Portal Name",
"deal_name" : "Investment Deal",
"legal_name": "Legal Name 1",
"redirect_url" : "http://www.portalwebsite.com/investor?param=3",
"webhook_url" : "http://www.portalwebsite.com/webhook"
}'
The above command returns a
201
and JSON structured like this:
{
"id": 90,
"waiting_for_info": true | false,
"redirect_url": "URL_TO_RETURN_INVESTOR_TO",
"portal_name": "Portal Name",
"deal_name": "Investment Deal",
"investor_url": "http://verifyinvestor.com/investor/verification-requests/90/verification-method",
"investor": {
"id": 135
},
"investor_url": "URL_TO_SEND_INVESTOR_TO"
"type": "aml_kyc"
}
The Create Verification Request endpoint can also be used to create an AML/KYC verification request if this is enabled on your account. All the same parameters are available for AML/KYC verification requests. Use the endpoint shown below to create an AML/KYC verification request.
POST /api/v1/users/:id/verification_requests/aml_kyc
The response will contain an additional parameter in the JSON body identifying the verification request type.
"type": "aml_kyc"
All other endpoints apply to AML/KYC verification requests.
Qualified Purchaser and Qualified Client
Create a qualified purchaser verification request:
curl -X POST "https://www.verifyinvestor.com/api/v1/users/135/verification_requests/qualified_purchaser" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"issuer_email" : "violet.howard44%40@example.com",
"portal_name" : "Portal Name",
"deal_name" : "Investment Deal",
"legal_name": "Legal Name 1",
"redirect_url" : "http://www.portalwebsite.com/investor?param=3",
"webhook_url" : "http://www.portalwebsite.com/webhook"
}'
The above command returns a
201
and JSON structured like this:
{
"id": 90,
"waiting_for_info": true | false,
"redirect_url": "URL_TO_RETURN_INVESTOR_TO",
"portal_name": "Portal Name",
"deal_name": "Investment Deal",
"investor_url": "http://verifyinvestor.com/investor/verification-requests/90/verification-method",
"investor": {
"id": 135
},
"investor_url": "URL_TO_SEND_INVESTOR_TO"
"type": "qualified_purchaser"
}
The Create Verification Request endpoint can also be used to create Qualfied Purchaser or Qualified Client verification requests if these are enabled on your account. All the same parameters are available for these types of verification requests. An additional path element is required to identify the type of verification request you wish to create, as shown below.
POST /api/v1/users/:id/verification_requests/qualified_purchaser
POST /api/v1/users/:id/verification_requests/qualified_client
The response will contain an additional parameter in the JSON body identifying the verification request type.
"type": "qualified_purchaser"
"type": "qualified_client"
All other endpoints apply to all supported verification request types including Qualified Purchaser and Qualified Client.
Check Verification Request
Check verification request #90:
curl GET "https://www.verifyinvestor.com/api/v1/users/135/verification_requests/90" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json"
The above command returns a
200
and JSON structured like this:
{
"id": 90,
"created_at": "2017-06-15T02:01:37.113Z",
"waiting_for_info" : false,
"completed_at": "2017-06-15T02:01:55.971Z",
"verified_expires_at": "2017-09-13",
"legal_name": "Some Company, LLC",
"portal_name": null,
"deal_name" : null,
"status": "accredited",
"verification_request_step": "accredited", # Deprecated. Please check the "status" parameter instead now.
"investor": {
"id": 135
}
}
GET /api/v1/users/:user_id/verification_requests/:id
Checks the status of a verification request for the specified user. The legal
name returned is the one specified when creating a verification request or
inputted by the investor. If waiting_for_info
is true, then a reviewer has
requested additional information for the investor. Alternatively, a shorter
avaliable URL is /api/v1/verification_requests/:id
Status | Explanation |
---|---|
waiting_for_investor_acceptance |
The verification is ready and waiting for the investor to accept it. |
accepted_by_investor |
The investor has accepted the verification request but has not yet completed it. |
waiting_for_review |
Investor has completed the request, and it is now in the reviewers' queue. |
in_review |
The verification request has been assigned a reviewer and is under review. |
accredited |
The investor is verified as accredited. |
not_accredited |
After review, it appears the investor is not accredited. |
waiting_for_information_from_investor |
The reviewer has requested additional information from the investor. |
accepted_expire |
The verification request has expired. The investor accepted but did not complete. |
declined_expire |
The verification request has expired. The investor never accepted. |
declined_by_investor |
The investor has declined the verification request. |
self_not_accredited |
The investor has accepted then canceled the verification request. |
While we'd like to maintain compatibility, additional states or changes to these states may be made. When possible, these updates will occur in a new API version. It would be prudent to safely capture unexpected statuses in your API integration.
Response Code | Meaning |
---|---|
200 OK |
Verification request found |
404 Not Found |
User or verification does not exist, or API user is not authorized to check |
Get Verification Requests
Get a list of your verification requests:
curl GET "https://www.verifyinvestor.com/api/v1/users/135/verification_requests" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json"
The above command returns a
200
and JSON structured like this:
[
{
"id": 90,
"waiting_for_info": false,
"portal_name": null, # aka Requesting Party
"verified_expires_at": null,
"deal_name": null,
"api_issued": false
},
...
]
GET /api/v1/users/:user_id/verification_requests
Checks the status of all verification requests but with less information provided.
Response Code | Meaning |
---|---|
200 OK |
Verification requests retrieved |
Simulate Investor Completion of a Verification Request (staging servers only)
This endpoint takes a Verification Request and simulates an investor filling out his or her information so that the verification request is then waiting for review.
Successful response answer
{
"id": 1,
"dashboard_status": "waiting-for-review",
"investor": {
"id": 2,
"verification_status": "unverified"
}
}
Example error when simulating a review:
{
"error": "Incorrect or missing params provided."
}
POST /api/v1/users/:user_id/verification_requests/:id/simulate_investor_completion
Response Code | Meaning |
---|---|
200 OK |
Verification request simulation has occurred |
403 Unauthorized |
Unauthorized error, usually caused if the token does not have proper access |
422 Unprocessable Entity |
Wrong params error, usually caused if the verification request is not currently in the waiting-for-investor-acceptance state |
Certificates
Verification Certificate
Request certificate:
curl GET "https://www.verifyinvestor.com/api/v1/users/135/verification_requests/90/certificate" \
-H "Authorization: Token YOUR_API_TOKEN_HERE"
GET /api/v1/users/:id/verification_requests/:vr_id/certificate
This endpoint returns the verification certificate for the specified user and verification request.
Note: Investors verified through the Knowledgable Employee or Officer methods are restricted to participate only in the specific fund in which they are a knowledgeable employee or officer. As a result, these methods produce unique certificates that specify the company and deal name. Please double-check the certificate names to ensure they match your specific fund.
Response Code | Meaning |
---|---|
200 OK |
Certificate found |
404 Not Found |
No certificate found |
Verification Certificate (via the User)
Request certificate:
curl GET "https://www.verifyinvestor.com/api/v1/users/135/verification_certificate" \
-H "Authorization: Token YOUR_API_TOKEN_HERE"
GET /api/v1/users/:id/verification_certificate
This endpoint returns a user's latest verification certificate, if you provide a
legal_name
param. The same certificate may also be downloaded from
verification request endpoint above.
Query Parameters
Parameter | Default | Description |
---|---|---|
legal_name | The legal name of the verified person or entity is required to retrieve a certificate on this endpoint. |
Response Code | Meaning |
---|---|
200 OK |
User is verified |
404 Not Found |
Certificate not found |
404 Not Found |
Legal name not provided, not authorized, or not found. |
Webhooks
Example webhook body:
{
"action": "verification_result",
"verification_request_id": 90,
"investor_id": 135,
"legal_name": "Legal Name 1",
"status" : "waiting_for_review",
"verification_status": "pending_verification", # Deprecated. Please check the "status" parameter instead now.
"identifier" : "42"
}
Example webhook body:
{
"action": "verification_result",
"verification_request_id": 90,
"investor_id": 135,
"legal_name": "Legal Name 1",
"status" : "not_accredited",
"verification_status":
"unverified | pending_verification | verified | accredited | not_accredited | need_more_information",
# Deprecated. Please check the "status" parameter instead now.
"identifier" : "42"
}
If you specify a "WebHook URL" under your account Settings, VerifyInvestor.com will submit a POST request to that URL whenever a verification request submitted by you (where you are the issuer) is pending or completed. Webhooks are NOT guaranteed delivery and should not be relied on. Please make sure to regularly check user and open verification statuses using API endpoints to ensure you have the latest accurate information.
After receiving this WebHook, you can perform actions within your system, such as downloading the investor's verification certificate. Please see the certificates endpoint endpoint for more information.
Signing Webhooks
Webhooks are signed using the HMAC SHA256 hash function. To take advantage of this security feature, generate a webhook secret in the API Info section of your VerifyInvestor.com account settings. The signature is placed in the X-Signature-SHA256
response header. To validate the webhook, compute the HMAC of the raw body using the SHA-256 hash function and the webhook secret, and compare the result to the value of the X-Signature-SHA256
header. If the values match, this verifies that the webhook came from your VerifyInvestor.com account and that the body of the request has not been altered.
IP Whitelisting
All of our webhooks from our production server are sent from the IP addresses shown below. You can whitelist these for added security. This is not availble on staging since its outgoing IP addresses are dynamically allocated.
Webhook IP Addresses |
---|
54.173.229.200 |
54.175.230.252 |
Webhook Request
Manually fire a webhook:
curl "https://www.verifyinvestor.com/api/v1/users/135/verification_requests/90/webhook" \
-H "Authorization: Token YOUR_API_TOKEN_HERE"
Example response for a success webhook request:
{
"action": "verification_result",
"verification_request_id": 90,
"investor_id": 135,
"status" : "waiting_for_information_from_investor",
"verification_status": "pending_verification",
"identifier" : "42",
"verification_result_status": "need_more_information", # Deprecated. Please check the "status" parameter instead now.
"verification_request_step": "waiting_for_information_from_investor" # Deprecated. Please check the "status" parameter instead now.
}
Example error when requesting a webhook:
{
"error": "A verification request could not be found."
}
GET /api/v1/users/:id/verification_requests/:verification_request_id/webhook
This manually fires a webhook to return the current state of the verification request. The verification_request_id
is the
id returned when creating a new verification request.
Response Code | Meaning |
---|---|
200 OK |
Webhook request succeeded |
404 Not Found |
User does not exist, or has not authorized your application |
403 Forbidden |
Request couldn't be processed, likely due to an incorrect status being passed or the verification request has not been completed by the investor |
Billing
Pull verification request counts for for billing purposes:
curl -X GET "https://www.verifyinvestor.com/api/v1/billing?from_date=2023-01-01&to_date=2023-01-31" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Accept: application/json" \
Sample response with only Regular API enabled:
{
"from_date": "2023-01-01",
"to_date": "2023-01-31",
"regular": 23
}
Sample response with all API types enabled:
{
"from_date": "2023-01-01",
"to_date": "2023-01-31",
"regular": 23,
"lite": 5,
"embedded": 9
}
The following endpoint returns verification request counts for billing purposes.
GET /api/v1/billing
Query Parameters
Parameter | Default | Description |
---|---|---|
from_date | Earliest date | Optional, date in yyyy-mm-dd format. Data is pulled from the beginning of this date. |
to_date | Current date | Optional, date in yyyy-mm-dd format. Data is pulled through the end of this date. |
The parameters from_date
and to_date
are optional. The date should be in yyyy-mm-dd
format.
If the from_date
parameter is missing or unparseable, all data will be included up to the to_date
. If the to_date
parameter is missing or unparseable, data will be included from the from_date
to the present. If neither parameter is present or parseable, all data will be included.
If you have multiple API types enabled, the response will contain a count for each type. This endpoint returns only verification request counts. Specific pricing information is available on request.
Simulated Review (staging servers only)
Simulate a review as accredited:
curl -X POST "https://www.verifyinvestor.com/api/v1/users/135/verification_requests/90/review" \
-H "Authorization: Token YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"status" : "need_more_information"
}'
Example response for a success review:
{
"id":135,
"status" : "accredited",
"legal_name" : "LEGAL NAME 1",
"dashboard_status" : "accredited", #Deprecated
"investor":
{
"id":90,
"verification_status":"verified" #Deprecated
}
}
Example error when simulating a review:
{
"error": "Incorrect or missing params provided."
}
POST /api/v1/users/:id/verification_requests/:verification_request_id/review
Automatically reviews a verification request completed by an investor. The
verification request must be in a way "waiting-for-review" status. The
verification_request_id
is the id returned when creating a new verification
request.
Parameter | Default | Description |
---|---|---|
status | Please provide one of the following: accredited , not_accredited , need_more_information . |
Response Code | Meaning |
---|---|
201 Created |
Verification request review succeeded |
404 Not Found |
User does not exist, or has not authorized your application |
403 Forbidden |
Request couldn't be processed, likely due to an incorrect status being passed or the verification request has not been completed by the investor |