NAV Navbar
shell

Parallel Markets API

On this side of the page, you’ll see some helpful examples of how to communicate with our APIs.

The Parallel Markets API allows users to assert their identity and accreditation status on other websites. Users have a portable investor identity that enables authentication and authorization on third party platforms without repeated accreditation verification.

Introduction

The Parallel Markets API uses the OAuth 2.0 protocol for authentication and authorization. Currently, only the web server OAuth 2.0 scenario is supported. Additional support for installed and client-side applications is currently planned for the near future.

To begin, OAuth 2.0 client credentials will be provided from Parallel Markets support. Then your client application requests an access token from the Authorization Server, extracts a token from the response, and uses the token in Paralell API calls for authentication on behalf of the user.

Basic Steps

All applications follow a basic pattern when accessing the Parallel Markets API using OAuth 2.0. At a high level, you follow four steps:

  1. Obtain OAuth 2.0 client credentials from Parallel Markets support.
  2. Obtain an access token from the Authorization Server. Before your application can access private data using the API, it must obtain an access token that grants access to that API. A single access token can grant varying degrees of access based on a parameter named scope that controls the set of resources and operations that an access token permits. During the access-token request, your application sends one or more values in the scope parameter. All API requests require an authentication step where the user logs in with their Parallel Markets account. After logging in, the user is asked whether they are willing to grant the permissions that your application is requesting. This process is called user consent. If the user grants the permission, the Authorization Server sends your application an authorization code that your application can use to obtain an access token. If the user does not grant the permission, the server returns an error.
  3. Use the access token to make calls to the API. After an application obtains an access token, it sends the token to a the Parallel Markets API in an HTTP authorization header. Access tokens are valid only for the set of operations and resources described in the scope of the token request. For example, if an access token is issued for profile information alone, it does not grant access to a user's accreditation documents. You can, however, send that access token to the API multiple times for similar operations relating to profile information.
  4. Refresh the access token. Access tokens have limited lifetimes. If your application needs access to the API beyond the lifetime of a single access token, it can obtain a refresh token. A refresh token allows your application to obtain new access tokens.

Scheduling API Status Updates

In general, you should schedule API calls in your system to update Profile Information, Accreditation Status, and the Refresh Token whenever:

  1. A user first creates an account or logs in to your site
  2. A user's accreditation has expired or been rejected within the last week (to allow time for users to be automatically re-accredited for those who qualify, or re-submit documentation for those who do not).
  3. A user's refresh token is about to expire

Obtaining Access Token

The following steps show how your application interacts with Parallel Market's OAuth 2.0 server to obtain a user's consent to perform an API request on the user's behalf. Your application must have that consent before it can execute a Parallel Market API request that requires user authorization.

The list below quickly summarizes these steps:

  1. Your application identifies the permissions it needs.
  2. Your application redirects the user to ParallelMarkets.com along with the list of requested permissions (usually via a "Parallel Login" button image click, see our Branding Assets page for button images you can use).
  3. The user decides whether to grant the permissions to your application.
  4. Your application finds out what the user decided.
  5. If the user granted the requested permissions, your application retrieves tokens needed to make API requests on the user's behalf.

Each of these steps is now described in detail in the following sections.

Step 1: Set authorization parameters

Sample redirect URL to Parallel Market's authorization server:

https://api.parallelmarkets.com/v1/oauth/authorize?
 scope=accreditation_status&
 state=Z9hLvSULzTSdm&
 redirect_uri=https%3A%2F%2Fcrowdfunding.example.com%2Fcallback&
 client_id=R1bh416wJQbuGdUFOzSO&
 response_type=code

Your first step is to create the authorization request. That request sets parameters that identify your application and define the permissions that the user will be asked to grant to your application.

Parallel Market's OAuth 2.0 endpoint is at:

https://api.parallelmarkets.com/v1/oauth/authorize

The authorization server supports the following query string parameters for web server applications:

Parameter Description
client_id Required. Provided by Parallel Markets support
redirect_uri Required. Determines where the API server redirects the user after the user completes the authorization flow. The value must exactly match one of the authorized redirect URIs for the OAuth 2.0 client that you shared with Parallel Markets support when setting up your OAuth client account. If this value doesn't match an authorized URI, the user will be shown an error message. Note that the http or https scheme, case, and trailing slash ('/') must all match.
scope Required. A space-delimited list of scopes that identify the resources that your application could access on the user's behalf. These values inform the consent screen that Parallel Markets displays to the user. Valid scopes are profile, accreditation_status, and accreditation_docs.
state Required. Specifies any string value that your application uses to maintain state between your authorization request and the authorization server's response. This parameter prevents a Cross-Site Request Forgery.
response_type Required. This value must be set to code.
force_accreditation_check Optional. If the entity is not known to be accredited (for instance, a new account or an expired accreditation), then force users through an accreditation flow after they authenticate. Default is true. See more details here.

Step 2: Redirect to Parallel Market's OAuth 2.0 server

Redirect the user to Parallel Market's OAuth 2.0 server to initiate the authentication and authorization process. Typically, this occurs when your application first needs to access the user's data. In the case of incremental authorization, this step also occurs when your application first needs to access additional resources that it does not yet have permission to access. Usually, this redirection is initiated via a "Parallel Login" button image click, see our Branding Assets page for button images you can use (see below for an example).

Medium button

Parallel Market's OAuth 2.0 server authenticates the user and obtains consent from the user for your application to access the requested scopes. The response is sent back to your application using the redirect URL you specified.

In this step, the user decides whether to grant your application the requested access. At this stage, Parallel Markets displays a consent window that shows the name of your application and the data (profile information, accreditation documents, etc) that it is requesting permission to access on behalf of the user. The user can then consent or refuse to grant access to your application.

Step 4: Handle the OAuth 2.0 server response

The OAuth 2.0 server responds to your application's access request by using the URL specified in the request.

If the user approves the access request, then the response contains an authorization code. If the user does not approve the request, the response contains an error message (described in detail here). The authorization code or error message that is returned to the web server appears on the query string, as shown below:

https://crowdfunding.example.com/callback?error=access_denied&state=Z9hLvSULzTSdm

Here's a valid authorization code response:

https://crowdfunding.example.com/callback?code=8n3yjrbyX83aPkuuv&state=Z9hLvSULzTSdm

Step 5: Exchange authorization code for refresh and access tokens

After the web server receives the authorization code, it can exchange the authorization code for an access token.

To exchange an authorization code for an access token, call the token API endpoint to exchange the temporary access code for a token. Once you have an access token, you can make API calls on behalf of the user. These API calls are described in detail below.

OAuth Token API

Request Token from Code

Given an access code, request an OAuth 2 token.

curl -X POST https://api.parallelmarkets.com/v1/oauth/token?code={code}&client_id={client_id}&client_secret={client_secret}&redirect_uri={redirect_uri}&grant_type={grant_type}

The above command returns JSON structured like this:

{
  "access_token": "MVXoULzTSdmDINFf",
  "token_type": "bearer",
  "expires_in": 86400,
  "refresh_token": "dmDINFfULzTSdMVXoU",
  "refresh_expires_in": 345600
}

This endpoint allows you to exchange an authorization code for an OAuth 2 access token.

HTTP Request

POST https://api.parallelmarkets.com/v1/oauth/token

Query Parameters

Parameter Description
code Required. The authorization code returned from Step 4 above.
client_id Required. Provided by Parallel Markets support
client_secret Required. Provided by Parallel Markets support
redirect_uri Required. The same value as you provided in the authorize call in Step 2
grant_type Required. As defined in the OAuth 2.0 specification this field must contain a value of authorization_code

Response Parameters

Parameter Description
access_token The OAuth 2 access token
token_type This will always be bearer
expires_in The number of seconds until this token expires
refresh_token A refresh token that can be used to get new access tokens. This will only be present if your client is authorized to recieve refresh tokens.
refresh_expires_in The number of seconds until refresh token expires

Refreshing a Token

Given an OAuth 2 refresh token, get a new authentication token.

curl https://api.parallelmarkets.com/v1/oauth/refresh?client_id={client_id}&client_secret={client_secret}&refresh_token={refresh_token}&scope={scope}&grant_type={grant_type}

The above command returns JSON structured like this:

{
  "access_token": "MVXoULzTSdmDINFf",
  "token_type": "bearer",
  "expires_in": 86400,
  "refresh_token": "dmDINFfULzTSdMVXoU",
  "refresh_expires_in": 345600
}

This endpoint allows you to exchange an OAuth 2 refresh token for a brand new access token. Refresh tokens have much longer live spans and can be used to replace short-lived access tokens whenever necessary.

HTTP Request

POST https://api.parallelmarkets.com/v1/oauth/refresh

Parameters

Parameter Description
client_id Required. Provided by Parallel Markets support
client_secret Required. Provided by Parallel Markets support
refresh_token Required. The refresh token provided in the result from the original token request
grant_type Required. As defined in the OAuth 2.0 specification this field must contain a value of refresh_token
scope Optional. If given, should be a subset of the original scopes granted.

Response Parameters

Parameter Description
access_token The OAuth 2 access token
token_type This will always be bearer
expires_in The number of seconds until this token expires
refresh_token A new refresh token that can be used to get new access tokens
refresh_expires_in The number of seconds until refresh token expires

Profile API

Request Profile

Get the profile information for a user/business.

curl https://api.parallelmarkets.com/v1/me \
  -H 'Authorization: Bearer {token}'

The above command returns JSON structured like this:

{
  "id": "VXNlcjox",
  "user_id": "VXNlcjox",
  "type": "individual",
  "profile": {
    "email": "test@example.com",
    "first_name": "Wyman",
    "last_name": "Manderly"
  }
}

Get profile information given a token. Some fields may not be returned based on the scope that was authorized by the user.

HTTP Request

GET https://api.parallelmarkets.com/v1/me

Query Parameters

None

Response Parameters

Parameter Scope Required Description
id A unique identifier for the entity (individual or business)
user_id A unique identifier for the person who authenticated. If type is individual, this will be the same as id (otherwise, this will be an identifier for the user acting as the business)
type Either "individual" or "business"
profile profile Either a User Profile or Business Profile

Accreditations API

Request Accreditations

Get the accreditation information for a user/business.

curl https://api.parallelmarkets.com/v1/accreditations \
  -H 'Authorization: Bearer {token}'

The above command returns JSON structured like this:

{
  "id": "VXNlcjox",
  "user_id": "VXNlcjox",
  "type": "individual",
  "indicated_unaccredited": null,
  "accreditations": [
    {
      "assertion_type": "income",
      "certified_at": 1568474142,
      "created_at": 1568560542,
      "expires_at": 1571152542,
      "id": "VXNlckFjY3JlZGl0YXRpb246MQ==",
      "status": "current"
    }
  ]
}

Get accreditation information given a token. Some fields may not be returned based on the scope that was authorized by the user.

HTTP Request

GET https://api.parallelmarkets.com/v1/accreditations

Query Parameters

None

Response Parameters

Parameter Scope Required Description
id A unique identifier for the entity (individual or business)
user_id A unique identifier for the person who authenticated. If type is individual, this will be the same as id (otherwise, this will be an identifier for the user acting as the business)
type Either "individual" or "business"
indicated_unaccredited accreditation_status or accreditation_docs If the user has indicated they are not accredited, this will be the Unix timestamp of when they made that indication. This will become null if the user subsequently submits an accreditation application.
accreditations accreditation_status or accreditation_docs A list of Individual Accreditations or Business Accreditations depending on the type.

Data Structures

These are some JSON structures that can be returned as parts of API responses.

User Profile Object

Example user profile object:

{
  "email": "test@example.com",
  "first_name": "Wyman",
  "last_name": "Manderly"
}
Name Description
email User's email address
first_name First name of user
last_name Last name of user

Business Profile Object

Example business profile object:

{
  "name": "Compu-Global-Hyper-Mega-Net, Inc.",
  "business_type": "Partnership LLC"
}
Name Description
name Name of business
business_type One of the business types below

Business types:

Business Accreditation Object

Example accreditation object:

{
  "assertion_type": "income",
  "certified_at": 1568474142,
  "created_at": 1568560542,
  "expires_at": 1571152542,
  "id": "VXNlckFjY3JlZGl0YXRpb246MQ==",
  "status": "current",
  "name": "Compu-Global-Hyper-Mega-Net, Inc."
}
Name Description
id Unique identifier for the accreditation
status One of the statuses listed below
expires_at Unix timestamp of when accreditation certification letter expires
assertion_type One of the types listed below
created_at Unix timestamp of when the accreditation request was submitted by the user
certified_at Unix timestamp of when the accreditation was certified and accreditation certification letter was issued
name The name of the company that has been accredited
documents A list of Accreditation Document Objects

Accreditation statuses:

Assertion types:

Individual Accreditation Object

Example accreditation object:

{
  "assertion_type": "income",
  "certified_at": 1568474142,
  "created_at": 1568560542,
  "expires_at": 1571152542,
  "id": "VXNlckFjY3JlZGl0YXRpb246MQ==",
  "status": "current",
  "first_name": "Snake",
  "last_name": "Plissken"
}
Name Description
id Unique identifier for the accreditation
status One of the statuses listed below
expires_at Unix timestamp of when accreditation certification letter expires
assertion_type One of the types listed below
created_at Unix timestamp of when the accreditation request was submitted by the user
certified_at Unix timestamp of when the accreditation was certified and accreditation certification letter was issued
first_name The first name of the accredited individual
last_name The last name of the accredited individual
documents A list of Accreditation Document Objects

Accreditation statuses:

Assertion types:

Accreditation Document Object

Example accreditation document object:

{
  "download_url": "https://api.parallelmarkets.com/files/business_accreditation_document/123?token=abc123def456",
  "download_url_expires": 30,
  "type": "certification-letter"
}

An accreditation document can be a supporting document that was used as evidence to make the accreditation determination (only available if you have requested the accreditation_docs scope) or it can be a certification letter (available for the accreditation_status scope).

Name Description
download_url Url where the document is available. There's a token as a part of the URL to enable embedding of the document in a webpage
download_url_expires Number of seconds until the token in the download_url expires
type Document type (see below)

Document types:

Errors

In the event of an error, the reponse will often have a type of application/json and there will be a error key with a description of the error.

These error codes could be returned from the API:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key or token is wrong.
404 Not Found -- The specified object could not be found.
405 Method Not Allowed -- You tried to access with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Libraries

This is the current list of first party open source libraries for interacting with the APIs.