Go to Yoplanning

Authentication

First of all, you must request an API token to be able to query the Yoplanning API.
To do so, please request a token in your Yoplanning settings (section "Advanced")

Once you have your token in hands, you can start working with the API. All API methods require authentication.
We use standard token-based authentication system. To authenticate, just provide your API token on the header of each request like so:
Authorization: Token 4804c2cb4d87a13146d4de029f407c82149f2ada
Be careful : the space between "Token" and the token is important.

Here is a full example using curl
curl -H "Content-Type: application/json" https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/clients/8d23503e-041e-4180-98d1-641183bc5ead -H 'Authorization: Token 4804c2cb4d87a13146d4de029f407c82149f2ada'

If you don't provide a token or if the token is invalid, the API will respond with a 401 HTTP code (Unauthorized) and will give you a "details" field in the response JSON to help you understand the problem.
{"detail":"Invalid token."} or {"detail":"Authentication credentials were not provided."}

Permissions

When you have requested your API token, you have been granted specific permissions on a certain set of teams.
This means you probably cannot use all the API methods listed.
If you call the Yoplanning API without permissions (for instance, you don't have permission to create session-groups on the team), the API will respond with a 403 HTTP code (Forbidden) with the following details.
{"detail":"You do not have permission to perform this action."}

Throttling

For security reasons, the number of requests you can perform is limited. You can send up to 5 requests/second and 1000 requests/day.
Beyond that rate, the server will respond with a 429 HTTP code (Too Many Requests) with the following details :
{"detail":"Request was throttled. Expected available in 86368 seconds."}

Concepts

Team

The team is the most fundamental concept in Yoplanning (which is a collaborative tool).
Almost all methods take a team_id parameter in the url. That means all the actions are relative to a team.

UUID

Lots of methods requires an "id" parameter in the url. This is the unique identifier for the resource you are trying to retrieve / create / update / delete.
Yoplanning uses UUID (version 4) as unique identifier for all resources.

Endpoints and HTTP verbs

For many resources, 2 endpoints are available :
- one to access a specific instance. The endpoint basically ends with {id}, for example :
/api/v3.1/teams/{teamId}/clients/{id}/

You can call these endpoints with the following http verbs :
  • GET : Retrieve the resource
  • PUT : Update the resource
  • DELETE : Delete the resource
- one to access the instances manager : You call these endpoints with the following http verbs :
/api/v3.1/teams/{teamId}/clients
  • GET : get a list of all resources (see Pagination)
  • POST : create a new resource (The id will be generated by the server)
All these actions are not available for all endpoints. Please see each endpoint documentation to know which methods are allowed.

Using PUT properly

When you want to update a resource, you should always use the following workflow :
  1. Retrieve the resource with a GET request
  2. Modify the JSON data
  3. Send a PUT request with the updated JSON
If you don't, the API may reject you because some nested resources require an ID that you don't give.
In addition, you may loose some data.

Online selling

For online selling purposes (retrieving products and availabilities), only 2 endpoints should be used:
  • /api/v3.1/teams/{teamId}/online-products/
  • /api/v3.1/teams/{teamId}/online-products/{productId}/availabilities/

Storing your ID

It might be useful to store your own id on each resource you manage, especially if you want to synchronize your system with Yoplanning.
For example, in case of synchronization problems on your side, these ids allow you to recover resources even if you lost the Yoplanning ID.
Therefore, you can store your ID in the external_reference fields in many resources (client, order, session_group, session, payment, ...)
This is not mandatory at all.

When you create an object or a sub-object (the main_client of a new order for exemple), you should not give the "id" property. Yoplanning will ignore that and create its own ID (that you will get in the response).
For instance, if the client already exist in the database, Yoplanning will try to reuse it instead of adding a duplicate.

Pagination

For all API methods that provide a large list of resources, pagination is used.
That means all the results will not be given in a single request. You will have to perform several requests to get the full list of resources.
You can see that as "pages in a book".

For each request, you can use query parameters (query string) in the url to navigate through the result.
Two query parameters can be provided : "offset" and "limit".
offset => the starting point where you want to retrieve data (you can see this as a cursor). Default : 0
limit => the number of results you want to retrieve per request. Default : 100 (which is also the maximum value)


For example : curl -H "Content-Type: application/json" -L "https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/clients?offset=20&limit=2" -H 'Authorization: Token 4804c2cb4d87a13146d4de029f407c82149f2ada'

Here is an example of response for methods using pagination:
{ "count":53, "next":"https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/clients?limit=2&offset=22", "previous":"https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/clients?limit=2&offset=18", "results":[ { "first_name" : "Jack", "last_name" : "Ichan", "email" : "jack.ichan@gmail.com", "phone_number" : "+32684952685", "birth_date" : "1975-05-22", "language" : "fr", "note" : "Pretty cool client :)", "street" : "rue du phare", "city" : "Brest", "postal_code" : "29200", "state" : null, "country" : "FR" "id":"7db70b5c-5175-4ba8-b471-78006940b79c" }, { "first_name":"Loic", "last_name":"Lepoivre", "email":null, "phone_number":null, "birth_date":null, "language":null, "note":null, "street":null, "city":null, "postal_code":null, "state":null, "country":null, "id":"669763dd-3bad-47a9-ac37-02d915a90bbe" } ] }

Explanation:
count => the total number of resources
next => the url to use to retrieve the next page. If there is no next page, the value will be null.
previous => the url to use to retrieve the previous page. If there is no previous page, the value will be null.
results => the list of resources

Filtering

For some endpoints, you can filter the results by adding query parameters to the request.
The following request will give you only the clients with first name "Norbert". https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/clients?offset=20&limit=2&first_name=Norbert

For date and numeric fields, you can filter using __lt (lower than), __gt (greater than), __lte (lower than or equal), __gte (greater than or equal).
The following request will give you only the clients with birth date greater than 1995-01-25. https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/clients?offset=20&limit=2&birth_date__gt=1995-01-25

Please see each endpoint documentation to know which fields can be used as filters (filters allowed).

Expand fields

For some endpoints, the resource object contains nested resources. For example, a session contains staff.
When you retrieve this resource (using a GET request), you will only retrieve the nested resources ids (here: staff ids).
To avoid sending more requests, you can use the expand mechanism of the API to retrieve the full nested object.

To do so, just append a query parameter in the url : "expand=" with the name of the nested resource you want to expand.
/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/payments/c21010f4-0e68-435b-b076-480087a49db1?expand=operator

You can use a dot notation to go deeper in the object.
/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/orders?expand=items.voucher.product

You can also expand several nested objects using a comma notation
/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/orders?expand=items.voucher.product,payments.operator

Please refer to each endpoint documentation to know which field is expandable.
Note : When you retrieve an instance using a GET request on an instance endpoint, some nested objects may be expanded by default. This forced expand is sometimes necessary in order to allow you to provide this JSON in a PUT request.

Important : If you want to retrieve a resource in order to update it with a PUT request, you MUST NOT USE the expand mechanism.

Webhooks

Webhooks are also called "web callback" or "HTTP push API". It is a notification system.
You can subscribe to webhooks in order to be notified when a particular event occurs (for example, each time a client is created).
In order to subscribe, please contact us through YoPlanning.

How does it work?
When subscribing to webhooks, you will give us a callback url and tell us on which event and for which team you want to be notified.
When this event is fired on this team, we will send a POST request on the callback url with data formatted like this :
{ "resource": { "id": "8d23503e-041e-4180-98d1-641183bc5ead", "type": "client" }, "link": "https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/clients/8d23503e-041e-4180-98d1-641183bc5ead", "event": "updated" }

Explanation:
resource.id => the resource that have been created / modified / deleted
resource.type => the type of resource (client / session / member, etc...)
link => the url to use to retrieve the resource.
event => the event fired


When you receive a POST request on the callback url, you will be able to send a GET request to the Yoplanning API using the "link" field to retrieve the corresponding resource.
Don't forget to add authentication information when calling the API!
Important : When you receive a webhook, you can send a GET request to the API in order to retrieve the changes and update your system. Then, never send a PUT request, it could lead to infinite loop.

Errors

Yoplanning uses HTTP response status codes to indicate the success or failure of your API requests. In general, there are three status code ranges you can expect:
  • 2xx success status codes confirm that your request worked as expected
  • 4xx error status codes indicate an error because of the information provided (e.g., a required parameter was omitted)
  • 5xx error status codes are rare and indicate an error with Yoplanning’s servers. You can still get this error in some rare case if the data you provided is not valid
4xx errors include some data to help you identify what was the problem. Here is an example:
{"price":["This field is required."]}
Keys: The name of the fields that have wrong value.
Values: A list of string describing the errors corresponding to this field.

Tutorial: Sell activities online

Introduction

This tutorial will show you how to build a booking engine based on the Yoplanning API. If you want to be able to sell Yoplanning activities in your system, you are in the right place to start. We assume that you have read the API documentation and that you already have your API token.

We will cover the following steps involved in the workflow :
  1. Retrieve your teams data
  2. Get the list of products
  3. Get availabilities for a specific product
  4. (Optional) Retrieve available options (resources)
  5. (Optional) Check everything is still available
  6. (Optional) Handle the payment via Payment Manager
  7. Place the order

Retrieve your teams data


First, you need to retrieve your teams IDs to be able to make use of the API
There are 2 very important information you need to retrieve and store in your system :
  • team_id : You will need this id for pretty much every request on the API
  • vendor_id : You will need this id only if you want to use the Payment Manager for the payment - see (Optional) Handle the payment via Payment Manager
You can retrieve all your teams at once using the following endpoint : /api/v3.1/teams/
This step should not be done for every payment ! You should do this only once and store the team_id and vendor_id in your system.

Depending on your needs, you can also skip this step and simply contact the support to ask for your team_id and vendor_id.

Get the list of products

First of all, you want to know what you can sell. To do so, you will have to retrieve the list of products that can be sold online for your team.
Here is the endpoint you are going to use : /api/v3.1/teams/{teamId}/online-products/
Example of call using Curl :
curl https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/online-products -H 'Authorization: Token 4504c2cb0d87a93106d4de029f407c86149f2ada'
Obviously, you have to replace the ID by the ID of your team and the token by the token we gave to you.
This will return a list of products (please see Pagination, Filter and expand fields in the documentation)

Each product contains a title, a description and other translatable content. You can retrieve this content in several different languages (the same ones available in the Yoplanning interface).
To do so, just give an additional query parameter with the language code (ISO 2).
Example : curl https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/online-products?lang=fr -H 'Authorization: Token 4504c2cb0d87a93106d4de029f407c86149f2ada'

You can also filter by category. If you want to do so please refer to /api/v3.1/categories/.

You can now display the list of products.

Get availabilities for a product

The next step is to retrieve the availabilities (sessions) for a given product. Basically, when the user will click on a product, you are going to display the availabilities for this product.
Here is the endpoint you are going to use : /api/v3.1/teams/{teamId}/online-products/{productId}/availabilities/
Example of call using Curl :
curl https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/online-products/f16ed6c6-e972-4232-b452-ecd393e61642/availabilities -H 'Authorization: Token 4504c2cb0d87a93106d4de029f407c86149f2ada'
Obviously, you have to replace the team ID(5a90332e-568f-4980-9859-88a984844a4d), product ID(f16ed6c6-e972-4232-b452-ecd393e61642) and token.
You can filter by date, price, number of tickets, staff (instructor) etc...

For each availability, you will get the associated prices. The "standard price" is the default price. This is the price everyone will get without anything else specified.
The "other prices" are a set of prices that can be chosen for each participant. For example : child price, member price, etc... You can now display the availabilities.

(Optional) Retrieve available options (resources)

In case the team is selling/renting equipments along with sessions, you might want to present them to the purchaser after they chose an availability from the list retrieved in the previous step ("Get availabilities for a product").

To do so, you will need to retrieve the details of the desired availability using the following endpoint : /api/v3.1/teams/{teamId}/availability-details/{id}/
Replace {id} with the "session_group" id you retrieved from the previous call ("Get availabilities for a product").
This endpoint will give you all you need about the different options available. The current stock is taken into account so only the available resources will be in the response.
For more information about what is an option, how you should display them and what's the json structure, please refer to the API documentation.

Here is an example using CURL : curl https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/availability-details/374facd3-df50-4295-a0ff-7b90eb6a26e2/ -H 'Authorization: Token 4504c2cb0d87a93106d4de029f407c86149f2ada'

You can now display each option as a dropdown. When you will finally create the order, you will use the "id" retrieved here to fill the "resource" field.
And you will use the "session_group" id to fill the "resource_target_group". Please take a look at the last step "Place the order" and to the API documentation for more information.

(Optional) Check everything is still available

If you have a lot of customers making bookings at the same time, you might want to increase the robustness of the system to avoid overbooking. To do so, you can simply check that the cart content is still available before checkout.
Here is the endpoint we are going to use : /api/v3.1/teams/{teamId}/order-validation
You just need to send the exact same JSON you would send to place an order (see below : "Place the order"). The only difference is the URL.
Here is an example using CURL : curl -H "Content-Type: application/json" -X POST -d '{"external_reference" : "956", "items" : [{"session_group" : "53071a97-0c2d-4973-89f5-cafd10665b3b", "price" : {"amount" : 51.25}, "client" : {"id" : "71ea849f-226c-4302-a433-528179634aa7", "first_name" : "John", "last_name" : "Doe", "email" : "john.doe@gmail.com"}}], "payments" : [{"amount" : 51.25, "client" : {"first_name" : "Framold", "last_name" : "Doe", "email" : "john.doe@gmail.com"}}]}' https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/order-validation -H 'Authorization: Token 4504c2cb0d87a93106d4de029f407c86149f2ada'
If everything is still available (most of the time), you should receive this answer : { "success": true }

If some items are not available anymore, you should receive an answer similar to this one : { "success": false, "unavailable_items": { "group_ids": ["2265cac0-cba5-46eb-8095-b89f93e7473f"], "dry_resource_ids": [], "voucher_ids": [], "resources": [] } }
if success is true, you can proceed to the next step.

(Optional) Create a payment via Payment Manager

Before getting started, make you sure you have stored the vendor_id in your system (see step 1 : Retrieve your teams data)
Once the cart is ready, the next step is to checkout and proceed to payment. To handle your client payment, you have 2 options : you can use your own payment solution or you can use the Payment Manager provided by Yoplanning. If you choose to use the Payment Manager, here is the workflow you need to implement :
  1. Create a payment and retrieve the payment link
  2. Redirect your client on the payment link
  3. handle the IPN (Instant Payment Notification)
First, you need to create a payment
To do so, you will use another API and thus another base URL : https://payment.yoplanning.pro/api/
The endpoint we are going to use here is : https://payment.yoplanning.pro/api/create-payment
We are going to use the POST HTTP method because we want to create a new payment.
You will need to setup a callback url on your system. This url must be reachable without authentication and must accept POST requests. Once the payment is done, you will receive an IPN on this url. Here is the JSON data you can provide : { "order_id": (required) This is the order id in your system "vendor_id":(required) This is your vendor id "price": (required) "currency": (required) "callback_url": (required) Once the payment is done, you will receive an IPN on this url "redirection_url": When the payment is done, the user will be redirected to this URL "cancel_url" : The user will be redirected on this url if the payment is cancelled "payer_email": used to pre-fill the payment form "cardholder_first_name": used to pre-fill the payment form "cardholder_last_name": used to pre-fill the payment form "billing_address_line1": "billing_address_line2": "billing_address_city": "billing_address_postal_code": "billing_address_country": "billing_address_state": }

Example of call using Curl :
curl -H "Content-Type: application/json" -X POST -d '{"order_id": "RFGYJ52","vendor_id": "a3dfc41e-5869-42d1-a8ec-a1d0280dcbf8","price": 59.84,"currency": "EUR","callback_url": "https://mysite.com/payment-callback","redirection_url": "https://mysite.com/payment-redirection","cancel_url" : "https://mysite.com/payment-cancelled","payer_email": "yousef.dupond@gmail.com","cardholder_first_name": "Yousef","cardholder_last_name": "Dupond","billing_address_line1": "7 route du chef-lieu","billing_address_city": "Annecy","billing_address_postal_code": "74000", "billing_address_country": "FR"}' https://payment.yoplanning.pro/api/create-payment -H 'Authorization: Token 3ef270c8a2ed6e15207ba8b0dab59ed7eb872ae8'
Be careful : the header "Content-Type: application/json" is important.
Here is an example of the answer you should get : { "payment_solution": "Stripe", "vakario_fee": "1.40", "customer_id": null, "success": true, "payment_id": "18135b43-f61b-4041-b89c-98c7086e8f68", "payment_url": "https://payment.yoplanning.pro/pay/3be2d0a0-f9a2-4fb0-aba2-bc3301c399c9" }
if success is true, you can proceed to the next step.

Redirect the client on the payment page
All you need to do is to redirect the client on the payment_url received in the previous step.

Handle the IPN
When the payment is done, you will receive an Instant Payment Notification on the callback_url you provided when you created the payment. The callback url must be accessible by POST without authentication. Here is an example of the IPN JSON data you should receive : { 'title': null, 'payment_solution': 'Stripe', 'card_brand': null, 'success': True, 'payer_lang': 'fr', 'id': '3d23247e-6115-4f2a-9258-f8071c0d0e07', 'seller_id': null, 'order_id': 'E816E3DA', 'payed': true, 'payment_method': null }
if success is true, you can proceed to the next step.

Place the order

Once the client has paid his cart, you will basically want to place an order to Yoplanning. When you place an order, the team planning is updated, the order & participants are displayed in Yoplanning, the staffs are notified, the availabilities are updated for the future bookings, etc...

Here is the endpoint you are going to use : /api/v3.1/teams/{teamId}/orders/
For the previous 2 calls, we used the HTTP method GET (because we wanted to retrieve data). This time, we are going to use POST method because we want to add a new order.
Example of call using Curl :
curl -H "Content-Type: application/json" -X POST -d '{"external_reference" : "956", "items" : [{"session_group" : "4f655815-58d9-4c7c-b1c9-2ea152073371", "price" : {"amount" : 51.25}, "client" : {"id" : "71ea849f-226c-4302-a433-528179634aa7", "first_name" : "John", "last_name" : "Doe", "email" : "john.doe@gmail.com"}}], "payments" : [{"amount" : 51.25, "client" : {"first_name" : "Framold", "last_name" : "Doe", "email" : "john.doe@gmail.com"}}]}' https://yoplanning.pro/api/v3.1/teams/5a90332e-568f-4980-9859-88a984844a4d/orders -H 'Authorization: Token 4504c2cb0d87a93106d4de029f407c86149f2ada'
Obviously, you have to replace the team ID(5a90332e-568f-4980-9859-88a984844a4d) and token.
Be careful : the header "Content-Type: application/json" is important.
The session-group correspond to the session-group of an availability.