menu
Particeep

Particeep API

Introduction

Overview

The Particeep API is organized around REST. Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors. We use built-in HTTP features, like HTTP verbs, which are understood by off-the-shelf HTTP clients. JSON is returned by all API responses, including errors, although our API libraries convert responses to appropriate language-specific objects.

To make the API as explorable as possible, accounts have test mode and live mode API keys. There is no "switch" for changing between modes, just use the appropriate key to perform a live or test transaction. Requests made with test mode credentials never hit the banking networks and incur no cost.
This page allows you to test the API in a sandbox environment. It's shared with other people and reset from time to time.

This API service is provided by Particeep

Questions, Concerns, Bug Reports

We'll occasionally send announcement emails to all developers with registered apps. You should follow @particeep for frequent updates. And please, send your feedback via our contact page

you can see the whole list on our roadmap page.

Access

2 environments are available : test and production. You target an environment by using the correct base url :

  • Test : https://test-api.particeep.com/v1
  • Prod : https://api.particeep.com/v1

HTTP / HTTPS

All endpoints are available over HTTPS only.

Registration

You need to register your app to access the API
Then we will give you your api key and secret for both test and production environnement.
Test key are free

Send us an email at support@particeep.com or call us to get your API key

Authentification

All access to the API must be authenticated.
We use specific headers :

  • DateTime: the date of the request in the iso 8601 format. e.g: 2015-10-19T11:04:18Z
  • Authorization: a hash formed with the api keys and the DateTime.

How to build the Authorization's header

Follow these steps to build your Authorization's header. This is provided with an example of implementation in Java.

  • Concat your keys and DateTime in the following order : APISecret + APIKey + DateTime.
  • String apiKey = "1234567890";
    String apiSecret = "0987654321";
    String dateTime = "2015-10-19T11:04:18Z";
    String toSign = apiSecret + apiKey + dateTime;
  • Get a list of bytes from the resulting string in UTF-8 format.
  • byte[] messageBytes = toSign.getBytes("UTF-8");
  • Get a list of bytes from your APISecret in UTF-8 format.
  • byte[] secretBytes = apiSecret.getBytes("UTF-8")
  • Sign 'messageBytes' with 'secretBytes' using SHA1.
  • Mac mac = Mac.getInstance("HmacSHA1");
    SecretKeySpec signingKey = new SecretKeySpec(secretBytes, "HmacSHA1");
    mac.init(signingKey);
    byte[] result = mac.doFinal(messageBytes);
  • Encode the resulting bytes in hexadecimal format.
  • char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
    
    int len = result.length;
    char[] hexChars = new char[len * 2];
    
    for (int charIndex = 0, startIndex = 0; charIndex < hexChars.length;) {
    int bite = result[startIndex++] & 0xff;
    hexChars[charIndex++] = HEX_CHARS[bite >> 4];
    hexChars[charIndex++] = HEX_CHARS[bite & 0xf];
    }
    
    // We use lowercase
    String sign = new String(hexChars).toLowerCase();
  • Encode the bytes of the result in base 64.
  • String signature = new String(Base64.encodeBase64(sign.getBytes("UTF-8")));
  • Concat all results like this: PTP:APIKey:signature
  • String authorization = "PTP:" + apiKey + ":" + signature;

If you don't provide the correct authentification information, you will get a '403 - Forbidden' response.

Data Format

Response Format

Unless specified otherwise, all responses are of type 'application/json' and use the following envelope:

{
"error" : {
    "hasError" : false,
    "errors" : [
        //list of potential error
    ]
},
    "result" : {
        //result data
    },
    "meta" : {
        "version": "1"
    }
} 

Data Format

  • We use UTF-8 encoding for everything.
  • The content-type of requests must be application/json
  • All dates must be endoded in iso 8601 format.
  • In every response we always use UTC timezone, e.g. 2015-08-10T08:50:00Z
  • In every request you're free to use the timezone you want as long as it's specified in the format, e.g. 2015-08-10T08:50:00+01

Password security

Regarding the security of your data, everything related to Users' passwords is encrypted.
We don't ever have knowledge of the Users' passwords.

If a User forget his password, you can always use the changePassword endpoint.
Once again, be aware that we do little checks and that it is up to you to ensure that a User does not change the password of another User.

Regarding that matter, we will soon have a tutorial available. Explaining the best practice on how to handle a User's password reset.

Errors

Particeep uses conventional HTTP response codes to indicate the success or failure of an API request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a charge failed, etc.), and codes in the 5xx range indicate an error with Particeep's servers (these are rare).

Not all errors map cleanly onto HTTP response codes, so there may be some exception. If a return code is not clear, please contact us

HTTP status code summary
200 - OK Everything worked as expected.
400 - Bad Request The request was unacceptable, often due to missing a required parameter.
401 - Unauthorized No valid API key provided.
403 - Forbidden You don't have the right to do this
404 - Not Found The requested resource doesn't exist.
500, 502, 503, 504 - Server Errors Something went wrong on Particeep's end. (These are rare.)

Error format

When the api respond with an error, the body of the response contains explanation about the error.
We use json with the following structure

{
  "hasError": true,
  "errors": [
    {
      "technicalCode": "error.user.none",
      "message": "error.user.none"
    }
  ]
}
Attributes
hasError Indicate if error is present
errors a list of error
technicalCode A unique string that we use to track error in our system
message A human-readable message providing details about the error

Metadata

On every response we add headers to indicate metadata about the api and your usage.

The debug-xxx header is not activated by default. We may turn it on in live environnement if you experience any trouble with the api.
You can also ask for it on a per request basis if you add the header Info-Debug-Enabled to your request. (you may put any value in the header)

Metadata
meta-version version of the api you're currently using
meta-endpoint relative path of the endpoint you just call
request-quota the number of request you did during the current month
request-quotamax the maximum number of request you're allowed to do during this month according to your subscription.
0 means you don't have a limit
debug-request-time timestamp in milisecond when the server receive the request
e.g. 1480005111761 means 24th of november 2016 at 16:31:52 and 761 ms in UTC time
debug-response-time timestamp in milisecond when the server send the response
debug-time-on-server number of milisecond spend on the particeep server

Pagination

A lot of endpoint return list of entities. Theses list are always paginate the same way : by using limit and offset parameters.

Parameters
limit default: 30 The number of element you want to retrieve. Usually the number of element in a given page
offset default: 0 The number of element you want to drop. For instance you have 30 element per page and you want to retrive the third page you will use : limit = 30, offset = 60

The response use this json envelop. It is your job to know which offset and limit you have used.
total_size is the total amount of element available for your request.
For instance you query your users with default parameters, "total_size": 1230 indicate you have 1 230 users and the response will contains the first 30 users in the data array.

{
  "total_size": 1230, // total number of element available
  "data": [
    {
      "id": "bf5788e8-9756-4d18-8b0f-100d7fba17a2",
      "created_at": "2015-08-10T00:00:00Z",
      ... other fields of the object
    },
    {
      "id": "bf5788e8-9756-4d18-8b0f-100d7fba17a2",
      "created_at": "2015-08-10T00:00:00Z",
      ... other fields of the object
    },
    ...
  ]
}

Modules

The Particeep API architecture is based around modules.
Modules are designed to work on their own without any dependencies on other modules.
For example, you can use the module User on its own, or even the Transaction one.

Some modules, however, have dependencies to other modules.
Here is a list of these modules with their dependencies:

Module Dependencies
Enterprise User, Link, Group
User Event
Kyc Wallet
Group Link, Event
Role Event
Form Event
Scoring metrics Event
Wallet User, Event
Transaction Event
Payment/td> Transaction, Wallet, Event
Fund Transaction, Payment, User, Event
Fundraise Equity Transaction, Payment, User, Event
Fundraise Reward Transaction, Payment, User, Event
Fundraise Loan Transaction, Payment, User, Event
Club deal Event
Partner Transaction, Role, Open Data, Event
Signature Event
Document Event
Document Generation Document, ConvertApi, Event
Webhook Event
Data Import User, Enterprise, Transaction, Fundraise Reward, Fundraise Loan, Fundraise Equity, Form, Role, Document, Partner, Event
Open Data Event
Event

Rights management

Consumer

The Consumer is what describes the entity consuming the API i.e. it's you !
The consumer is identified by your api key.
The api only see your api key doing request. It doesn't see your real user doing request.

The Particeep API only knows you as a consumer through your api key

Rights

That being said, we choose to not manage your end-user right. To the Particeep API, every request comes from a consumer that own the data so we always show all of it. The right to see some data or to modify some data must be handle on your side i.e. in the application that use this API.

We only provide a Role end point that answer one questions : which role this user have ?

If you need more information about role management, please contact us

We don't manage access rights for your end-users

Practical topic

You configuration is linked to your consumer. This include the payment provider you use or your request's quota. To create your Consumer see the registration section.

For practical reason, your api key is linked to a secret (for security) and an email (for communication). All three of them must be unique so you can't manage multiple api key with the same email.

For advanced endpoint such as Wallet, KYC or Payment you have to create a User entity with the same email as your Consumer. Usually this is handle in the registration process.

Being Reactive

Reactive application are a hot topic right now. This section is about how to be reactive with the Particeep API.

Events

For every request that chane the state of your data, i.e. every PUT, POST or DELETE, we store an event that describe the changes.
An event is a name and a json that describe the state. The json is the same as the response to the request that generate the event.

Exemple : you delete one of your user

DELETE /v1/user/{user_id}
In response to the request we send you back the deleted user. In the meantime we generate an event with the name user_deleted and the deleted user representation in json.

You can find which events are launched in the description of each endpoint

How to respond to events

The events are generated inside the Particeep API. To be notified about an event you need to register to it. This happend in the webhook endpoint.

The webhook endpoint allows you to simply add notifications for your client application.
Webhooks are simple objects represented by a name and an url. The name must match the name of an event and when this event is triggered in the API, we launch a POST request to the provided url. The request body is the json representation of the event. Some headers provide additionnal information.
You may register only one url by event.

Webhook headers
X-Particeep-Event The name of the event
DateTime The date when the webhook was send in iso 8601 format
Authorization A signature to ensure the request comes from Particeep API and is not forged

Common use case

We don't send email on your behalf because we don't know your branding. So when an asynchronous events occur in the system, webhook is a good way to notify your users.
For instance you can be notified when a Transaction has been paid. Allowing you to promptly send an email to your customers to notify them of the succeeded payment.

Some asynchronous events
  • CB payment
  • Electronique signature
  • Scoring available on enterprise
  • KYC validation

Security

In the land of notification, security is extremely important. We use the same pattern to identify a request coming from the API that the pattern use to identify a request coming from you. The api will build an authorisation header following the rule defined here and store it in the Authorization header.
You can rebuild the same header on your side and compare it to the header you receive in order to check the origin of the request.

To protect you from man-in-the-middle attack you must provide a https url to the webhook. We don't enforce it because according to what you're doing with the webhook's request it may not be required.
You need to have a proper ssl certificate installed on your server in order to https request to succeed.

Use https url for your webhook for maximum security

If you encounter any trouble to verify a webhook's header, please contact us

Customize the API

Overview

Particeep's API is focus on core stock, if you need some customization for your own project, that's possible thanks to custom fields.

Custom fields allow you to extend the native objects of the API with your own attributes.
Every major object in the data model should support custom fields. Basically it's a json attribute named custom that is added to the object. You can store any json object inside it.

A custom field should be a json Object, not a json array or a json value like a boolean

Custom field is a black box for the api : we store it and return it unchanged. It use the classical lifecycle of objects : you add it via the PUT or POST endpoint and you get the result on the GET endpoint.

It's available on all major object like User, Enterprise, Transaction, Fundraise, Document, etc...

Common use case

For instance you may want to store multiple avatars for your users. You can add custom field by doing a POST request on /v1/user/<user_id> with the following body

{
  "custom" : {
    "avatars" : {
      "small"  : "https://url_to_small_avatar",
      "medium" : "https://url_to_medium_avatar",
      "large"  : "https://url_to_large_avatar"
    }
  }
}

Then you'll get this response on the by id endpoint

{
  "id": "06a4dc77-9770-4165-b54d-b5e44730d2aa",
  "created_at": "2017-07-17T15:59:20Z",
  "email": "jean@particeep.com",
  "first_name": "jean",
  "has_been_claimed": true,
  "address": {},
  "custom": {
    "avatars" : {
      "small"  : "https://url_to_small_avatar",
      "medium" : "https://url_to_medium_avatar",
      "large"  : "https://url_to_large_avatar"
    }
  }
}

Other common use case include

  • Specific warnings that you have to display on a fundraise page to be compliant with local laws
  • Specific data on a transaction such as the amount in letter
  • etc...

Endpoints