NAV
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 Parallel 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 scope 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 status. 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 sees what the user decided when they are redirected back to your application.
  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 listed in the Scopes Section.
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. It should not be longer than 1024 characters.
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. Ignored if scope doesn't include accreditation_status. 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).

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 redirecting the user to the redirect_uri specified in the original request. The URL parameters will either contain a code value on success, or an error value if the user failed to consent or if there was some other issue.

Success

If the user approves the access request, then the response contains an authorization code. Here's a valid authorization code response example, showing the access code:

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

If the user does not approve the request or if there is another issue with the request, the response will contain an error code in an error parameter. Here's an example:

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

The possible error codes are based on the OAuth 2 specification and will be one of these:

Error Code Description
invalid_request The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.
unauthorized_client The client is not authorized to request an authorization code using this method.
access_denied The user declined to grant consent for the scopes requested.
unsupported_response_type The authorization server does not support obtaining an authorization code using the response_type requested.
invalid_scope The requested scope is invalid, unknown, or malformed.
server_error The authorization server encountered an unexpected condition that prevented it from fulfilling the request.

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 life 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 for a user or business. This API requires the profile scope permission.

HTTP Request

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

You must send an Authorization header with a value of Bearer {token}, where {token} is a valid OAuth Token.

Query Parameters

None

Response Parameters

Parameter 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 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 for a user or business. This API requires the accreditation_status scope permission.

HTTP Request

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

You must send an Authorization header with a value of Bearer {token}, where {token} is a valid OAuth Token.

Query Parameters

None

Response Parameters

Parameter 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 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 A list of Individual Accreditations or Business Accreditations depending on the type.

Identity API

Request Identity

Get detailed information about an individual.

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

The above command returns JSON structured like this:

{
  "id": "VXNlcjox",
  "user_id": "VXNlcjox",
  "type": "individual",
  "first_name": "Snake",
  "last_name": "Plissken",
  "ssn": "123-45-6789",
  "born_at": 647115414,
  "marital_status": "married",
  "phone": "12025551234",
  "residence_status": "us-citizen",
  "primary_location": {
    "address_one": "123 Fake St",
    "address_two": "Apt 3",
    "city": "New York",
    "region": null,
    "zip": "10011",
    "state": "NY",
    "country": "US"
  },
  "identity_document": {
    "type": "passport",
    "download_url_expires": 30,
    "download_url": "https://api.parallelmarkets.com/files/user_identity_document/123?token=abc123def456"
  },
  "tin_response": {
    "name": "Snake Plissken",
    "address_one": "123 Fake St",
    "address_two": "Apt 3",
    "city": "New York",
    "zip": "10011",
    "state": "NY",
    "us_person": true,
    "not_subject_withholding": true,
    "esigned_at": 1593886991,
    "tin": "123-45-6789"
  }
}

Get identity information for an individual, including detailed contact information, identity documents, and Taxpayer Identification Certification (W-9). This API requires the identity scope permission.

HTTP Request

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

You must send an Authorization header with a value of Bearer {token}, where {token} is a valid OAuth Token.

Query Parameters

None

Response Parameters

Parameter 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"
first_name The individual's first name
last_name The individual's last name
ssn The individual's self-reported social security number
born_at Date of birth, as a Unix timestamp
marital_status If not null, one of married, single, separated, or divorced
phone Phone number with country code (E.123 international phone number notation without a leading +).
residence_status If not null, one of us-citizen, us-permanent-resident, us-resident, or other
primary_location User's primary address, as a Location
identity_document User's most recently provided identity document, as an Identity Document
tin_response User's most recently provided Taxpayer ID Number and Certification (W-9) details, as a TIN Response

Employment API

Request Employment

Get the employment status and history information for an individual.

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

The above command returns JSON structured like this:

{
  "id": "VXNlcjox",
  "user_id": "VXNlcjox",
  "type": "individual",
  "occupation": "Full stack engineer",
  "employment_status": "employed",
  "employment_records": [
    {
      "started_at": 1568560542,
      "business": "Awesome Company"
    }
  ]
}

Get the employment status and history information for an individual. This API requires the employment scope permission. If called with a business token, no fields will be returned.

HTTP Request

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

You must send an Authorization header with a value of Bearer {token}, where {token} is a valid OAuth Token.

Query Parameters

None

Response Parameters

Parameter 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"
occupation The user's self-reported occupation
employment_status If not null, this will be one of employed, self-employed, retired, or not-employed.
employment_records A list, where each item is an Employment Record.

Suitability API

Request Suitability

Get the suitability information for a user/business.

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

The above command returns JSON structured like this:

{
  "id": "VXNlcjox",
  "user_id": "VXNlcjox",
  "type": "individual",
  "investment_experience": "professional",
  "investment_objective": "speculation",
  "acceptable_risk_level": "moderate",
  "investment_time_horizon": {
    "at_least": 20,
    "less_than": null,
    "granularity": "year"
  },
  "years_investing_securities": {
    "at_least": 1,
    "less_than": 5,
    "granularity": "year"
  },
  "years_investing_illiquid": {
    "at_least": 10,
    "less_than": 15,
    "granularity": "year"
  },
  "liquid_net_worth": {
    "at_least": 0,
    "less_than": 1000000
  },
  "estimated_net_worth": {
    "at_least": 1000000,
    "less_than": 2100000
  },
  "income_level": {
    "at_least": 100000,
    "less_than": 250000
  },
  "joint_income_level": {
    "at_least": 250000,
    "less_than": 500000
  }
}

Get the latest results of an investor suitability questionnaire for an individual or business. This API requires the suitability scope permission.

HTTP Request

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

You must send an Authorization header with a value of Bearer {token}, where {token} is a valid OAuth Token.

Query Parameters

None

Response Parameters

Parameter 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"
investment_experience One of not-experienced, moderate, extensive, professional
investment_objective One of preservation-of-capital, income, growth, or speculation
acceptable_risk_level One of conservative, moderate, or significant
investment_time_horizon The amount of time the investor is looking to invsest as a Time Period
years_investing_securities The number of years the investor has experience investing in securities as a Time Period
years_investing_illiquid The number of years the investor has experience investing in illiquid assets as a Time Period
liquid_net_worth The investor's liquid net worth as a Worth Level
estimated_net_worth The investor's total net worth as a Worth Level
income_level The investor's individual income as an Income Level
joint_income_level The investor's joint income with their spouse as an Income Level

Scopes

When users are initially redirected to the Parallel Markets Authentication server, a scope parameter must be provided. This scope should be 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, and determine what API's the resulting token will have access to based on user consent.

Here is a list of all available scopes:

Scope Description
profile This scope provides access to the Profile API and basic information about an individual or business.
accreditation_status This provides access to the Accreditations API and the full accreditation history for an individual or business.
employment This scope provides access to the Employment API and an individual's current employment status and previous employment history.
suitability This scope provides access to the Suitability API and the latest results of an investor suitability questionnaire for an individual or business.
identity This scope provides access to the Identity API and detailed contact information, identity documents, and Taxpayer Identification Certification (W-9).

Data Structures

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

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"
}

The accreditation documents currently available are the certification letters issued by the Parallel Markets subsidieary broker-dealer (FM (USA), LLC) indicating that the user or business is accredited.

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 This will always be certification-letter.

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:

Business Profile Object

Example business profile object:

{
  "name": "Compu-Global-Hyper-Mega-Net, Inc.",
  "business_type": "Partnership LLC",
  "primary_contact": {
    "email": "test@example.com",
    "first_name": "Wyman",
    "last_name": "Manderly"
  }
}
Name Description
name Name of business
business_type One of the business types below
primary_contact A User Profile Object representing the primary contact for the business.

Business types:

Employment Record

Example employment record object:

{
  "started_at": 1568560542,
  "business": "Awesome Company"
}

This represents an individual's employment at a business.

Name Description
started_at The start date for the individual's employment, as a Unix timestamp.
business The name of company where the individual is employed.

Identity Document Object

Example identity document object:

{
  "download_url": "https://api.parallelmarkets.com/files/user_identity_document/123?token=abc123def456",
  "download_url_expires": 30,
  "type": "passport"
}

This is a government issued identification document (either as an image or PDF format) as provided by the user.

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 One of drivers-license, state-id-card, or passport

Income Level Object

Example income level object:

{
  "at_least": 100000,
  "less_than": 250000
}

This is used to indicate an entity's income on an annual basis in US dollars.

Name Description
at_least Entity's annual income is at least this US dollar amount.
less_than Entity's annual income is no more than this US dollar amount. If there's no upper bound, this will be null.

The at_least values are in increments from less than $50k to $5M or more:

Description At Least Less Than
less than $50k 0 50000
at least $50k, less than $107k 50000 107000
at least $107k, less than $200k 107000 200000
at least $200k, less than $300k 200000 300000
at least $300k, less than $500k 300000 500000
at least $500k, less than $1M 500000 1000000
at least $1M, less than $5M 1000000 5000000
$5M or more 5000000 null

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:

Location Object

Example location object:

{
  "address_one": "123 Fake St",
  "address_two": "Apt 3",
  "city": "New York",
  "region": null,
  "zip": "10011",
  "state": "NY",
  "country": "US"
}
Name Description
address_one Street address
address_two Second address line (apartment, suite, block, etc)
city Name of city
region Region is available for non-US addresses
zip A postal code
state State for US-based addresses
country 2 letter ISO 3166-1 country code

Time Period Object

Example time period object:

{
  "at_least": 1,
  "less_than": 5,
  "granularity": "year"
}

This is used to represent time periods with various possible granularity unit levels.

Name Description
at_least At least this discrete number of granularity units.
less_than No more than this discrete number of granularity units. If there's no upper bound, this will be null.
granularity The granularity unit. In most cases this will be year.

TIN Response Object

Example TIN Response object:

{
  "name": "Snake Plissken",
  "address_one": "123 Fake St",
  "address_two": "Apt 3",
  "city": "New York",
  "zip": "10011",
  "state": "NY",
  "us_person": true,
  "not_subject_withholding": true,
  "esigned_at": 1593886991,
  "tin": "123-45-6789"
}

This represents the most recently provided Taxpayer ID Number and Certification (W-9) details for either an individual or a business.

Name Description
name The name of the business or the individual
address_one Street address
address_two Second address line (apartment, suite, block, etc)
city Name of city
state US-based state
zip A postal code
us_person Boolean based on an indication of whether the entity is considered a US Person (see the IRS Form Instructions for more details)
not_subject_withholding Boolean based on whether the entity indicated they are subject to withholding (see the IRS Form Instructions for more details)
esigned_at A Unix timestamp of when the entity signed the form
tin The Taxpayer Identification Number provided at signature

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

Worth Level Object

Example worth level object:

{
  "at_least": 1000000,
  "less_than": 2100000
}

This is used to indicate an entity's worth (net, liquid, gross, etc) in US dollars.

Name Description
at_least Entity's worth is at least this US dollar amount.
less_than Entity's worth is no more than this US dollar amount. If there's no upper bound, this will be null.

The at_least values are in increments from less than $100k to $10M or more:

Description At Least Less Than
Less Than $100k 0 100000
At least $100k, less than $250k 100000 250000
At least $250k, less than $500k 250000 500000
At least $500k, less than $1M 500000 1000000
At least $1M, less than $2.1M 1000000 2100000
At least $2.1M, less than $5M 2100000 5000000
At least $5M, less than $10M 5000000 10000000
$10M or more 10000000 null

Errors

Example of an error response:

{ "error": "The client_id and client_secret provided are invalid." }

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 HTTP Status codes could be returned from the API if there is an error:

Error Code Name Description
400 Bad Request Your request is invalid.
401 Unauthorized Your API credentials are not recognized (your client/secret or token is wrong).
403 Forbidden Your credentials are recognized, but you don't have permissions to do what you're trying to do.
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.

Sandbox

Overview

The Parallel Markets API sandbox is a self-contained, isolated testing environment that simulates the live Parallel Markets API production environment. The sandbox provides a safe space where you can test your integration without danger of touching any live Parallel Markets accounts.

Sandbox Functionality

The sandbox mirrors the functionality of production endpoints with some additional functionality designed for ease of testing, namely:

  1. All new accreditation applications for individuals with a minus sign at the end of their last name (i.e. John Doe-) will get automatically rejected within 10 minutes of submission
  2. All new accreditation applications for businesses with a minus sign at the end of their name (i.e. A Company Inc.-) will get automatically rejected within 10 minutes of submission
  3. All new accreditation applications for individuals with a plus sign at the end of their last name (i.e. John Doe+) will get automatically certified within 10 minutes of submission
  4. All new accreditation applications for businesses with a plus sign at the end of their name (i.e. A Company Inc.+) will get automatically certified within 10 minutes of submission

Endpoints

The sandbox environment endpoints are almost the same as the live ones, just add the demo- prefix like in the following examples:

Production Endpoint Sandbox Endpoint
https://api.parallelmarkets.com/v1/oauth/authorize https://demo-api.parallelmarkets.com/v1/oauth/authorize
https://api.parallelmarkets.com/v1/employment https://demo-api.parallelmarkets.com/v1/employment
https://api.parallelmarkets.com/v1/identity https://demo-api.parallelmarkets.com/v1/identity

Javascript SDK

Copy this code into the <head> of your website:

<script src="//app.parallelmarkets.com/sdk/v1/parallel.js"></script>
<script>
  Parallel.init({ client_id: 'your_client_id' });

  // Or - if you're testing in the sandbox environment, you
  // can use this code instead:
  // Parallel.init({
  //   client_id: 'your_client_id',
  //   api_location: 'https://demo-api.parallelmarkets.com'
  // });
</script>

The Parallel Javascript SDK allows you to quickly and easily integrate the Parallel Markets API into a single page application (SPA) or other frontend. You can use Javascript to authenticate users and call the Parallel APIs. The same basic OAuth 2.0 process is followed as described above, but you don't need to implement any code on a server if you use the Javascript SDK.

To get started, you'll need the client_id assigned to you when you signed up. Then, you can copy the example code to the right to add the SDK to your page initialize it with your client_id.

Initiating a Login Redirect

Add a "Parallel Passport" button somewhere on your page:

<script>Parallel.showButton()</script>
<div class="parallel-login-button"></div>

Or explicitly initiate a login flow with this function call:

<a href="#" onClick="Parallel.login()">
  Log in with Parallel
</a>

To automatically load a Parallel Passport button on your page, just follow these steps:

  1. Add the class parallel-login-button to the parent element where you want the button to appear.
  2. Call Parallel.showButton(), which will then find that element and render a login button.

Alternatively, you can provide your own button or link and call Parallel.login() when you're ready to send the user into an authentication flow.

The user will be dropped back off on the same page on your site where the authentication redirect was initiated (which must be the same URL as the redirect_uri you provided when your account was first set up). This URL must match only for the initial redirection authentication process - after that, you can call the Parallel.getLoginStatus() and Parallel.api() functions on any page in your domain that has the Parallel Javascript SDK loaded.

User Authentication Status

Parallel.getLoginStatus(function (result) {
  if (result.status === 'connected') {
    // user is logged in and you can call the API now
  } else if (result.status === 'not_authorized') {
    // the user canceled authentication or failed
    // to consent to sharing with your site
  } else {
    // user authentication unknown (i.e., the user
    // is not logged in) - so show the login button
    Parallel.showButton()
  } 
});

To get a user's authentication status, use the Parallel.getLoginStatus() function. It takes a single argument that is a callback function, which will be called once the user's login status can be determined. The callback function will be called with one object parameter that will have a status field. The status can one of:

If there is any unexpected error attempting to determine the user's status, then an error field will be present as well with a string message indicating the issue.

Calling the API

Here's an example calling the Profile API ("/me" endpoint).

Parallel.getLoginStatus(function (result) {
  // check to make sure the user is logged in first
  if (result.status !== 'connected') return;

  Parallel.api('/me', function (profile) {
    console.log('You are a ' + profile.type);
    if (profile.type === 'individual')
      console.log('Your name is ' + profile.first_name);
    else console.log('Your business is ' + profile.name);
  });
});

Here's an example calling the Accreditation API.

Parallel.getLoginStatus(function (result) {
  // check to make sure the user is logged in first
  if (result.status !== 'connected') return

  Parallel.api('/accreditations', function (accreds) {
    var status = 'unaccredited';
    for (var i=0; i<accreds.length; i++) {
      if (accreds[i].status === 'current')
        status = 'accredited';
    }
    console.log('Accreditation status: ' + status);
  });
});

Once a user is logged in, you can call any of the API methods above using the Parallel.api() function. This function accepts an endpoint as the first argument, and a callback function as the second.

For instance, to get the user's profile or accreditation status, see the examples to the right.

Optional Asynchronous Loader

Place this in your <head> section on your page:

<script>
// copy and paste this section exactly as is
(function(d,s){var a=d.createElement("script");a.async=!0;
 a.onload=function(){this.onload=function(){};
 window.pmLoaderInit&&pmLoaderInit()};
 a.onreadystatechange=function(){
 this.readyState==='complete'&&this.onload()};a.src=s;
 var b=d.getElementsByTagName("script")[0];
 b.parentNode.insertBefore(a, b)
})(document,'https://app.parallelmarkets.com/sdk/v1/parallel.js');

// copy this section and fill in with your details
window.parallelInit = function() {
  Parallel.init({ client_id: 'my_client_id' });

  Parallel.getLoginStatus(function (resp) {
    ...
  });
};
</script>

If you prefer to load the Parallel Javascript SDK asynchronously (so that it's non-blocking), you can use the method to the right. Just make sure to define a pmLoaderInit function that calls the Parallel init.

Libraries

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