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
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;
byte[] messageBytes = toSign.getBytes("UTF-8");
byte[] secretBytes = apiSecret.getBytes("UTF-8")
Mac mac = Mac.getInstance("HmacSHA1"); SecretKeySpec signingKey = new SecretKeySpec(secretBytes, "HmacSHA1"); mac.init(signingKey); byte[] result = mac.doFinal(messageBytes);
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();
String signature = new String(Base64.encodeBase64(sign.getBytes("UTF-8")));
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 the2xx
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.
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
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.
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.
- 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.
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.
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...