Planaday Public API URL

This documentation describes the calls available in the public API of planaday.

Overview

Last updated

See changelist at the end of this documentation!

API URL

Please replace apitest in the URL mentioned in the examples with your own company code. (as in apitest should be replaced with your prefix in your normal environment. i.e. https://myname.planaday.nl, apitest = myname)

Example URL

https://customer.api.planaday.nl/v1/booking/2

Notational Conventions

The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC2119.

Authentication

  • This API uses API Keys as configured in the main application (PAD) for authentication. Please read the support documentation for more information: Handleiding Publieke API.

  • Key MUST be provided in X-Api-Key header,

Example Header

X-Api-Key: 5113F6314DC7A397323EA383B0D65B39CD03FC9F77F30CDA6E0C9523543DF8B8

Consumer Identification

This API uses User-Agent headers to identify API consumer.

Example Headers

User-Agent: Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/_BuildID_) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36

HTTP Methods

This API uses HTTP verbs (methods) as following:

  • GET - Read - used to read (or retrieve) a representation of a resource,

  • POST - Create - used to create new resources. In particular, it’s used to create subordinate resources.

  • PUT - Update/Replace - used for update capabilities, PUT-ing to a known resource URI with the request body containing the newly-updated representation of the original resource. On successful request, replaces identified resource with the request body.

  • PATCH - Update/Modify - used for modify capabilities. The PATCH request only needs to contain the changes to the resource, not the complete resource.

  • DELETE - Delete - used to delete a resource identified by a URI.

Media Type

Where applicable this API MUST use the JSON media-type. Requests with a message-body are using plain JSON to set or update resource states.

Content-type: application/json & Accept: application/json headers SHOULD be set on all requests if not stated otherwise in the documentation.

Not sending the correct headers will result in an 415 Unsupported Media Type error from the server.

Example Headers

Content-type: application/json
Accept: application/json

Representation of Date and Time

All exchange of date and time-related data MUST be done according to ISO 8601 standard and stored in Europe/Amsterdam timezone.

  • When returning or sending date-related data YYYYMMDD format IS/MUST be used.

  • When returning or sending time-related related data HH:mm format IS/MUST be used.

Status Codes and Errors

This API uses HTTP status codes to communicate with the API consumer.

  • 200 OK - Response to a successful GET, PUT, PATCH or DELETE.

  • 201 Created - Response to a POST that results in a creation.

  • 204 No Content - Response to a successful request that won’t be returning a body (like a DELETE request).

  • 400 Bad Request - Malformed request; form validation errors.

  • 401 Unauthorized - When no or invalid authentication details are provided.

  • 403 Forbidden - When authentication succeeded but authenticated user doesn’t have access to the resource.

  • 404 Not Found - When a non-existent resource is requested.

  • 405 Method Not Allowed - Method not allowed.

  • 406 Not Acceptable - Could not satisfy the request Accept header.

  • 415 Unsupported Media Type - Unsupported media type in request.

  • 500 Server error - Something went realy wrong.

  • 503 Rate Limit Reached - Ratelimit reached, please try again later.

Ratelimiting

The API uses ratelimiting and shows the status about that in the response headers.

X-RateLimit-Limit: 720000
X-RateLimit-Remaining: 719999
X-RateLimit-Reset: 1610536876

The maximum amount of calls pers hours is shown in the X-RateLimit-Limit header. The calls remaining in the X-RateLimit-Remaining header. The last X-RateLimit header shows the reset timestamp

Pagination

Some of the responses will contain 2 special blocks:

  • meta

  • links

Meta

This block shows information about how many results there are (records), current(page), offset, limit per page and how many pages (total). The last one is based on your limit and offset.

"meta": {
  "page": {
    "current": 1,
    "offset": 1,
    "limit": 100,
    "total": 4
  },
  "records": 393
}
  • current: Current page shown of ‘total’

  • offset: Record of ‘records’ to start with showing

  • limit: Max amount of ‘record’ to fetch in one call

  • total: Total amount of pages of ‘limit’ records

  • records: Total amount of records found

Using offset

Example: with offset 200 will give the following answer (note the change in current and offset)

"meta": {
  "page": {
    "current": 3,
    "offset": 200,
    "limit": 100,
    "total": 4
  },
  "records": 393
}

Links

This block show the links to the current, first, next, previous and last page with records.

"links": {
    "self": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=20",
    "first": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=1",
    "last": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=40",
    "next": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=40",
    "previous": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=1"
}

VAT codes

The following vat_codes can be returned in the API:

  • 0 = 0% vat (none)

  • 1 = 9% vat (low)

  • 2 = 21% vat (high)

Attribute blocks

Notice: Attributes block can only be used when a Planaday employee gives the rights to use this!

Attributes blocks are special block with settings that are configured in the application. They can be used to trigger sales in the websites, set special colors for course, but also to select a course language, select multiple options for a course, etc.

The attribute blocks can be found beneath:

  • Coursetemplates

  • Courses

  • Daypart beneath courses

The attribute block look like this:

"Attributes": [
  "Aanbieding": {
      "code": "{E27A0D46-AAF1-BDB8-A667-D3C0510F0A5E}",
      "values": [
          "ja": {
            "value": "50",
            "description": "display tekst"
          },
          "nee": {
            "value": "0",
            "description": "display tekst"
          }
      ],
      "is_required": false,
      "multiple_values_allowed": false,
      "is_financial": false
  }
]

code

This is the field we expect back in the booking (see the ‘booking’ documentation for examples)

values

This is a list of possible values for a field. This can contain 1 or more items.

The following structures are possible:

Both value and description are known:

"value 1": {
    "value": "50",
    "description": "Text #1"
}

Only value is known:

"value 2": {
    "value": "50",
    "description": null
}

Only description is known:

"value 3": {
    "value": null,
    "description": "description #1"
}

Both value/description are unknown:

"value 4": []

is_required

This will be true when the booking required this item to be posted! (see the ‘booking’ documentation for examples)

multiple_values_allowed

WHen this is true, multiple values can be posted in the booking (see the ‘booking’ documentation for examples)

is_financial

When an attribute involes a financial thing (i.e. an course option which has a price), the is_financial will be true and the vat and vat_code item will be included

The values will then look like:

"Attributes": [
  "Mogelijke opties": {
      "code": "{E27A0D46-AAF1-BDB8-A667-D3C0510F0A5E}",
      "values": [
          "EPT": {
            "value": null,
            "description": "Text #1"
          },
          "Heftruck": {
            "value": '25',
            "description": "Text #2"
          },
          "Reachtruck": {
            "value": '50',
            "description": null
          },
          "Anders": []
      ],
      "is_required": false,
      "multiple_values_allowed": false,
      "is_financial": false,
      "vat": 21,
      "vat_code": 2
  }
]

Booking

With the booking api you can create new course booking for students.

Booking

POST https://apitest.api.planaday.net/v1/booking/course_id
RequestsCreate booking for 2 studentCreate booking for a student with extra fieldsCreate booking for a student with attributes
Headers
Content-Type: application/json
X-Api-Key: <apikey>
Body
{
  "students": [
    {
      "id": 12312312,
      "gender": "m", // m, f, nvt, null
      "initials": "P.W.M.",
      "first_name": "Pieter",
      "nick_name": "Piet",
      "last_name": "Pietersen",
      "email": "pieter@pietersen.nl",
      "address": "Straat",
      "house_number": "1",
      "house_number_extension": null,
      "postal_code": "2132PS",
      "city": "Hoofddorp",
      "country": "Nederland",
      "phonenumber": null,
      "date_of_birth": "20000101",
      "hometown": "maastricht",
      "country_of_birth": "Nederland",
      "employeeId": "ABR1234",
      "costcentercode": "700123",
      "company_position": "Scrum leader",
      "is_contact_person": true,
      "is_student": false,
      "internal_reference": "123445AA",
      "process_code95": false,
      "process_soob": false,
      "language": "NL"
    },
    {
      "id": 12312313,
      "gender": "f",
      "initials": "K.S",
      "first_name": "Klara",
      "last_name": "Pietersen",
      "email": "klara@pietersen.nl",
      "address": "Straat",
      "house_number": "1",
      "house_number_extension": null,
      "postal_code": "2132PS",
      "city": "Hoofddorp",
      "phonenumber": null,
      "date_of_birth": null,
      "employeeId": "ABR1235",
      "costcentercode": "700123",
      "company_position": "Scrum leader",
      "is_contact_person": false,
      "is_student": true,
      "internal_reference": "123445AA",
      "remark": "This is a remark"
    }
  ],
  "company": {
    "name": "Pietersen BV",
    "email": "klara@pietersen.nl",
    "address": "Straat",
    "house_number": "1",
    "house_number_extension": null,
    "postal_code": "2132PS",
    "city": "Hoofddorp",
    "phonenumber": null,
    "invoice_email": "facturatie@pietersen.nl"
  },
  "created_at": "2017-12-17T22:50:27+00:00",
  "creating_source": "www.testsite.nl",
  "course_id": 2,
  "dayparts": [
    76,
    77,
    78,
    79
  ],
  "materials": [
    405,
    407
  ],
  "label": "Group1",
  "is_payed": true,
  "payment" : {
    "party": "ideal",
    "transaction_id": "1231ASSBBD12321"
  }
}
Responses200400400404
Headers
Content-Type: application/json
Body
{
  "result": "OK",
  "booking_id": "API5ce597c40e0fc6.85265205",
  "details": {
    "company": {
      "action": "resused",
      "id": 52,
      "name": "Pietersen BV"
    },
    "students": [
      {
        "action": "reused",
        "type": "employee",
        "id": 12312312,
        "name": "Pietersen, Pieter",
        "option_ids": [
          65,
          66,
          67,
          68
        ]
      },
      {
        "action": "reused",
        "type": "employee",
        "id": 12312313,
        "name": "Pietersen, Klara",
        "option_ids": [
          69,
          70,
          71,
          72
        ]
      }
    ]
  }
}
Headers
Content-Type: application/json
Body
{
  "error": 402,
  "message": "Missing students block"
}
Headers
Content-Type: application/json
Body
{
  "error": 425,
  "message": "attribute: unknown value given for attribute {1A811192-969F-323B-04C7-257C7BC6C897} : foo. Allowed: Reachtruck/ EPT"
}
Headers
Content-Type: application/json
Body
{
  "message": "Unavailable course selected"
}
Headers
Content-Type: application/json
X-Api-Key: <apikey>
Body
{
  "students": [
    {
      "id": 12312312,
      "gender": "m", // m, f, nvt, null
      "initials": "P.W.M.",
      "first_name": "Pieter",
      "last_name": "Pietersen",
      "email": "pieter@pietersen.nl",
      "address": "Straat",
      "house_number": "1",
      "house_number_extension": null,
      "postal_code": "2132PS",
      "city": "Hoofddorp",
      "country": "Nederland",
      "phonenumber": null,
      "date_of_birth": "20000101",
      "hometown": "maastricht",
      "country_of_birth": "Nederland",
      "employeeId": "ABR1234",
      "costcentercode": "700123",
      "company_position": "Scrum leader",
      "is_contact_person": true,
      "is_student": false,
      "internal_reference": "123445AA",
      "fields": [
        "extra_field_1": "Value 1",
        "extra_field_2": "true",
        "extra_field_3": "false",
        "extra_field_4": "15"
      ],
      "process_code95": false,
      "process_soob": false,
      "language": "NL"
    }
  ],
  "company": {
    "name": "Pietersen BV",
    "email": "klara@pietersen.nl",
    "address": "Straat",
    "house_number": "1",
    "house_number_extension": null,
    "postal_code": "2132PS",
    "city": "Hoofddorp",
    "phonenumber": null,
    "invoice_email": "facturatie@pietersen.nl"
  },
  "created_at": "2017-12-17T22:50:27+00:00",
  "creating_source": "www.testsite.nl",
  "course_id": 2,
  "dayparts": [
    76,
    77,
    78,
    79
  ]
}
Responses200400400404
Headers
Content-Type: application/json
Body
{
  "result": "OK",
  "booking_id": "API5ce597c40e0fc6.85265205",
  "details": {
    "company": {
      "action": "resused",
      "id": 52,
      "name": "Pietersen BV"
    },
    "students": [
      {
        "action": "reused",
        "type": "employee",
        "id": 12312312,
        "name": "Pietersen, Pieter",
        "option_ids": [
          65,
          66,
          67,
          68
        ]
      },
      {
        "action": "reused",
        "type": "employee",
        "id": 12312313,
        "name": "Pietersen, Klara",
        "option_ids": [
          69,
          70,
          71,
          72
        ]
      }
    ]
  }
}
Headers
Content-Type: application/json
Body
{
  "error": 402,
  "message": "Missing students block"
}
Headers
Content-Type: application/json
Body
{
  "error": 425,
  "message": "attribute: unknown value given for attribute {1A811192-969F-323B-04C7-257C7BC6C897} : foo. Allowed: Reachtruck/ EPT"
}
Headers
Content-Type: application/json
Body
{
  "message": "Unavailable course selected"
}
Headers
Content-Type: application/json
X-Api-Key: <apikey>
Body
{
  "students": [
    {
      "id": 12312313,
      "gender": "f",
      "initials": "K.S",
      "first_name": "Klara",
      "last_name": "Pietersen",
      "email": "klara@pietersen.nl",
      "address": "Straat",
      "house_number": "1",
      "house_number_extension": null,
      "postal_code": "2132PS",
      "city": "Hoofddorp",
      "phonenumber": null,
      "date_of_birth": null,
      "employeeId": "ABR1235",
      "costcentercode": "700123",
      "company_position": "Scrum leader",
      "is_contact_person": false,
      "is_student": true,
      "internal_reference": "123445AA",
      "remark": "This is a remark"
    }
  ],
  "company": {
    "name": "Pietersen BV",
    "email": "klara@pietersen.nl",
    "address": "Straat",
    "house_number": "1",
    "house_number_extension": null,
    "postal_code": "2132PS",
    "city": "Hoofddorp",
    "phonenumber": null,
    "invoice_email": "facturatie@pietersen.nl"
  },
  "created_at": "2021-05-01T22:50:27+00:00",
  "creating_source": "www.testsite.nl",
  "course_id": 2,
  "dayparts": [
    76,
    77
  ],
  "attributes": [
    {
      "code": "{E27A0D46-AAF1-BDB8-A667-D3C0510F0A5EF",
      "values": [
        "foo",
        "bar"
      ]
    }
  ]
}
Responses200400400404
Headers
Content-Type: application/json
Body
{
  "result": "OK",
  "booking_id": "API5ce597c40e0fc6.85265205",
  "details": {
    "company": {
      "action": "resused",
      "id": 52,
      "name": "Pietersen BV"
    },
    "students": [
      {
        "action": "reused",
        "type": "employee",
        "id": 12312312,
        "name": "Pietersen, Pieter",
        "option_ids": [
          65,
          66,
          67,
          68
        ]
      },
      {
        "action": "reused",
        "type": "employee",
        "id": 12312313,
        "name": "Pietersen, Klara",
        "option_ids": [
          69,
          70,
          71,
          72
        ]
      }
    ]
  }
}
Headers
Content-Type: application/json
Body
{
  "error": 402,
  "message": "Missing students block"
}
Headers
Content-Type: application/json
Body
{
  "error": 425,
  "message": "attribute: unknown value given for attribute {1A811192-969F-323B-04C7-257C7BC6C897} : foo. Allowed: Reachtruck/ EPT"
}
Headers
Content-Type: application/json
Body
{
  "message": "Unavailable course selected"
}

Create booking
POST/booking/{course_id}

Use this call to create booking for optional company and one (1) or more students. These booking are visible in the application in the section: cursus->openstaande aanvragen (/cursus/aanvragen).

Student block

The students block is required and can contain one or more student objects.

The complete list of fields for each student object is listed in the request example. The following fields are required:

  • first_name

  • last_name

  • email (can be null)

  • phonenumber (can be null)

Possible gender values are:

  • ‘m’ (male)

  • ‘f’ (female)

  • ‘nvt’ (inapplicable) or ‘nr’ (not relevant)

  • ‘null’ value or ‘u’ (unkown)

  • no gender field = ‘u’

The language field is optional, but these are the possible language values:

  • ‘NL’ (dutch)

  • ‘ENG’ (english)

  • ‘FR’ (French)

  • ‘DU’ (German)

  • ‘PL’ (Polish)

  • No language field = ‘NL’

When an id is specified we will link the booking to this user known in Planaday. This field is optional.

The optional costcentercode field must contain a known code you defined in Planaday (beheer -> kostenplaats).

The optional fields block can contain ‘extra/custom’ fields as defined in the Planaday application. Please note that these combination are always in the format: “fieldname” : “value” (including the double quotes)

You can create contacts for a company by using the is_contact and is_student fields. When you make ‘is_contact’ true and ‘is_student’ false, only a contact will be added for the company.

You can add an optional internal reference to a student, wich will be copied from the booking to the real student. This field is called internal_reference.

Company block

The whole company block is optional. When it’s added the following fields are required:

  • name

  • address

  • house_number

  • postal_code

  • city

When no company block is added, each student will be added as a private (particulier) student.

Dayparts block

The dayparts block is an optional list of dayparts ids that will be booked for the students. If the ‘dayparts’ block is an empty list then the students will be booked for all dayparts of the selected course.

Payment block

If the is_payed field is added and has the true value, the payment block is required!

This must contain the following fields

  • party

  • transaction_id

Attributes block

Notice: This block can only be used when a Planaday employee gives the rights to use this!

When dayparts or course has attributes that are required, the attributes block in the post is also required! The booking API gives as much information as possible when there are errors in the post.

When there are attributes required in a course/daypart it is NOT possible to send multiple students in the booking.

Attributes block always contains the following:

"attributes": [
    {
        "code": "{E27A0D46-AAF1-BDB8-A667-D3C0510F0A5EF",
        "values": [
            "foo"
        ]
    }
]

and when multiple items (in this case items with values) are allowed the value can contain:

"attributes": [
    {
        "code": "{E27A0D46-AAF1-BDB8-A667-D3C0510F0A5E}",
        "values": [
          "Foo",
          "Bar"
        ]
    }
]

General items

You can add an additional creating_source string which you can use to determine the source of the API request. (i.e. the url of the website which uses the API) This string will be visible in the Planaday application.

It is possible to label a booking with the optional label field. This field may contain a-z, A-Z, 0-9 and - (dash). No spaces or other character are allowed

Error codes

Code Message
400 Bad Request, 400: parameters missing: id
400 Bad Request, 401: unable to parse posted json
400 Bad Request, 402: missing students block
400 Bad Request, 403: students:gender missing, empty or invalid value (m/f/nvt/u/nr allowed)
400 Bad Request, 404: students:first_name missing or empty
400 Bad Request, 405: students:last_name missing or empty
400 Bad Request, 406: students:email contains invalid value ()
400 Bad Request, 407: course_id missing or not the same as url parameter
400 Bad Request, 408: company:name missing or empty
400 Bad Request, 409: company:address missing or empty
400 Bad Request, 410: company:house_number missing or empty
400 Bad Request, 411: company:postal_code missing or empty
400 Bad Request, 412: company:city missing or empty
400 Bad Request, 413: course selected without dayparts
400 Bad Request, 414: unknown course selected
400 Bad Request, 415: course selected without dayparts
400 Bad Request, 416: dayparts includes id not present in given course
400 Bad Request, 417: material includes id not present in given course
400 Bad Request, 418: payment block is missing
400 Bad Request, 419: attribute:attributes block is missing
400 Bad Request, 420: attribute:only 1 student allowed when attributes block is set
400 Bad Request, 421: attribute:code is missing
400 Bad Request, 422: attribute:value is missing
400 Bad Request, 423: attribute:unknown attribute code given for this course/daypart: {}. Allowed codes: [list]
400 Bad Request, 424: attribute:not all required attributes are posted. Missing attributes: [list]
400 Bad Request, 425: attribute:unkown value given for attribute {}: [value], Allowed values: [list]
400 Bad Request, 426: students:unknown language given (), allowed: [list]
400 Bad Request, 427: attribute:Attributes given, but none required/configured
400 Bad Request, 428: attribute:Multiple item given for attribute {}. Only 1 allowed
400 Bad Request, 429: attribute:Value required, but non given
401 No Access Right
404 Course not found
URI Parameters
HideShow
course_id
number (required) 

ID of the Course to create booking for in the form of an integer


Booking payed

POST https://apitest.api.planaday.net/v1/booking/payed/booking_id
RequestsMark booking as payed
Headers
Content-Type: application/json
X-Api-Key: <apikey>
Body
{
  "is_payed": true,
  "payment": {
    "party": "ideal",
    "transaction_id": "1231ASSBBD12321"
  }
}
Responses200400404
Headers
Content-Type: application/json
Body
{
  "result": "OK",
  "bookingId": "API5ce597c40e0fc6.85265205"
}
Headers
Content-Type: application/json
Body
{
  "error": 401,
  "message": "Parameters missing: id"
}
Headers
Content-Type: application/json
Body
{
  "message": "Unavailable booking selected"
}

Mark booking as payed
POST/booking/payed/{booking_id}

Use this call to mark a booking as payed. This can be handy after handeling a payment callback.

If the ‘is_payed’ field is ‘true’, the ‘payment’ block is required!

Error codes

Code Message
400 Bad Request, 400: Parameters missing: booking_id
400 Bad Request, 401: Unable to parse posted json
400 Bad Request, 402: Missing payment block
400 Bad Request, 403: Missing party
400 Bad Request, 404: Missing transaction_id
404 Booking not found
URI Parameters
HideShow
booking_id
string (required) 

ID of the booking received in the booking post call (i.e API5ce597c40e0fc6.85265205)


Delete booking

DELETE https://apitest.api.planaday.net/v1/booking/booking_id
RequestsDelete booking
Headers
Content-Type: application/json
X-Api-Key: <apikey>
Responses200400404
Headers
Content-Type: application/json
Body
{
  "result": "OK",
  "bookingId": "API5ce597c40e0fc6.85265205"
}
Headers
Content-Type: application/json
Body
{
  "error": 401,
  "message": "Parameters missing: bookingid"
}
Headers
Content-Type: application/json
Body
{
  "message": "Booking not found"
}

Delete made booking
DELETE/booking/{booking_id}

Use this call to delete an earlier made booking.

Important: this is only possible when the booking isn’t converted to a planned student yet!

Error codes

Code Message
400 Bad Request, 400: Parameters missing: bookingid
404 Booking not found
URI Parameters
HideShow
booking_id
string (required) 

ID of the booking received in the booking post call (i.e API5ce597c40e0fc6.85265205)


Course

With the course api you can fetch information about a course.

Course list

GET https://apitest.api.planaday.net/v1/course/list?start=start&end=end&templateid=templateid&offset=offset&limit=limit&label=label
RequestsNormal answerAnswer with freefield
Headers
X-Api-Key: <apikey>
Responses200
Headers
Content-Type: application/json
Body
{
  "meta": {
    "page": {
      "offset": 0,
      "limit": 30,
      "total": 1
    },
    "records": 2
  },
  "data": [
    {
      "id": 1,
      "code": "d52-201710-001",
      "name": "Gereedschap verkleinen",
      "description": null,
      "type": "open",
      "status": "active",
      "daypart_amount": 1,
      "dayparts": [
        {
          "id": 3,
          "href": "https://apitest.api.planaday.nl/v1/daypart/3",
          "visible": true
        }
      ],
      "users": {
        "min": 7,
        "max": 14,
        "available": 11,
        "options": 1
      },
      "costs": {
        "user": 321,
        "course": 2884,
        "vat": 21,
        "vat_code": 2,
        "remark": null
      },
      "coursetemplate": {
        "id": 123,
        "href": "https://apitest.api.planaday.nl/v1/coursetemplate/123"
      },
      "start_guaranteed": 0,
      "moneyback_guaranteed": 1,
      "has_elearning": 1,
      "has_code95": 1,
      "has_soob": 0,
      "href": "https://apitest.api.planaday.nl/v1/course/1",
      "labels": [
        "EHBO",
        "BHV"
      ],
      "attributes": {
          "Take exam": {
              "code": "{182BF814-FAA4-1C3C-941A-FCD180A78033}",
              "values": [
                  "ja": {
                    "value": "50",
                    "description": "display tekst"
                  },
                  "nee": {
                    "value": "0",
                    "description": "display tekst"
                  }
              ],
              "is_required": true,
              "multiple_values_allowed": false,
              "is_financial": true,
              "vat": 21,
              "vat_code": 2
          }
      },
      "language": "NL"
    },
    {
      "id": 2,
      "code": "986-201710-003",
      "name": "Fiets slopen",
      "description": null,
      "type": "open",
      "status": "concept",
      "daypart_amount": 1,
      "dayparts": [
        {
          "id": 2,
          "href": "https://apitest.api.planaday.nl/v1/daypart/2",
          "visible": false
        }
      ],
      "users": {
        "min": 5,
        "max": 12,
        "available": 9,
        "options": 2
      },
      "costs": {
        "user": 109,
        "course": 3482,
        "vat": 21,
        "vat_code": 2,
        "remark": null
      },
      "coursetemplate": {
        "id": 124,
        "href": "https://apitest.api.planaday.nl/v1/coursetemplate/124"
      },
      "start_guaranteed": 0,
      "moneyback_guaranteed": 1,
      "has_elearning": 0,
      "has_code95": 0,
      "has_soob": 0,
      "href": "https://apitest.api.planaday.nl/v1/course/2",
      "labels": [
        "CODE95"
      ],
      "attributes": [],
      "language": "NL",
    }
  ],
  "links": {
    "self": "https://apitest.api.planaday.nl/v1/course/list?start=20171101&end=20171101&offset=1",
    "first": "https://apitest.api.planaday.nl/v1/course/list?start=20171101&end=20171101&offset=1",
    "last": "https://apitest.api.planaday.nl/v1/course/list?start=20171101&end=20171101&offset=10",
    "previous": "",
    "next": "https://apitest.api.planaday.nl/v1/course/list?start=20171101&end=20171101&offset=10"
  }
}
Headers
X-Api-Key: <apikey>
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1,
  "href": "http://apitest.api.planaday.localhost/v1/course/1",
  "code": "96a-202108-001",
  "name": "EAD en reanimatie",
  "description": "",
  "type": "open",
  "status": "concept",
  "daypart_amount": 0,
  "dayparts": [],
  "users": {
    "min": 6,
    "max": 15,
    "available": 15,
    "options": 0
  },
  "costs": {
    "user": 387,
    "course": 2469,
    "vat": 21,
    "vat_code": 2,
    "remark": ""
  },
  "coursetemplate": {
    "id": 1,
    "href": "http://apitest.api.planaday.localhost/v1/coursetemplate/1"
  },
  "level": "Advanced",
  "level_description": "",
  "start_guaranteed": false,
  "moneyback_guaranteed": false,
  "has_elearning": false,
  "has_code95": false,
  "has_soob": false,
  "labels": [],
  "language": "NL",
  "freefields": {
    "Startdatum": "23-08-2021"
  },
  "repeating_courses": [
    {
      "id": null,
      "href": null
    }
  ]
}

Get a list of courses
GET/course/list?start={start}&end={end}&templateid={templateid}&offset={offset}&limit={limit}&label={label}

Use this call to get a list of courses. You can use the optional parameter templateid to limit your search to courses belonging to one course. Or add the optional parameter label to filter on labels connected to the course.

label

The label parameter can contain 1 label to select courses that matches 1 label

&label=BHV

or a list of labels seperated by , (comma) to select courses that matches ALL labels:

&label=BHV,LOGISTIEK

Error codes

Code Message
400 Bad Request
401 No Access Right
404 Course not found
URI Parameters
HideShow
start
date (required) 

Start date of planned courses to look for (YYYYMMDD)

end
date (required) 

End date of planned courses to look for (YYYYMMDD)

templateid
number (optional) 

ID of the Coursetemplate to find courses for

offset
number (optional) 

Start offset of courses to show (i.e. 25)

limit
number (optional) 

Amount of courses to show in one response (i.e. 25, limited to 100)

label
string (optional) 

labels which the course MUST have (see also label API calls)


Get Course

GET https://apitest.api.planaday.net/v1/course/course_id
Requestsexample 1
Headers
X-Api-Key: <apikey>
Responses200
Headers
Content-Type: application/json
Body
{
    "id": 8,
    "code": "Test-01/10",
    "name": "Test cursus",
    "description": "Dit is een test cursus",
    "type": "open",
    "status": "active",
    "daypart_amount": 2,
    "dayparts" : [
       {
           "id" : 1,
           "href": "https://apitest.api.planaday.nl/v1/daypart/1",
           "labels": [
               "CODE95"
           ],
           "visible": true,
           "status": "option",
           "attributes": {
             "Aanbieding": {
               "code": "{E27A0D46-AAF1-BDB8-A667-D3C0510F0A5E}",
               "values": [
                 "ja": {
                    "value": "50",
                    "description": "display tekst"
                  }
               ],
               "is_required": false,
               "multiple_values_allowed": false,
               "is_financial": true,
               "vat": 21,
               "vat_code": 2
             },
           }
       },
       {
           "id" : 2,
           "href": "https://apitest.api.planaday.nl/v1/daypart/2",
           "labels": [
               "EHBO",
               "BHV"
           ],
           "visible": true,
           "status": "concept"
       }
    ],
    "users": {
       "min": 5,
       "max": 10,
       "available": 7,
       "options": 2
    },
    "costs": {
       "user": 1299,
       "course": 4500,
       "vat": 21,
       "remark": null
    },
    "coursetemplate": {
      "id": 123,
      "href": "https://apitest.api.planaday.nl/v1/coursetemplate/123"
    },
    "level": "Advanced",
    "level_description": "Higher level course",
    "start_guaranteed": 0,
    "moneyback_guaranteed": 1,
    "has_elearning": 1,
    "has_code95": 1,
    "code95" : {
        "practice": 12,
        "theory": 5
    },
    "has_soob": 0,
    "href": "https://apitest.api.planaday.nl/v1/course/1",
    "labels": [
      "CODE95"
    ],
    "attributes": {
      "Aanbieding": {
          "code": "{E27A0D46-AAF1-BDB8-A667-D3C0510F0A5E}",
          "values": [
              "ja": {
                "value": "50",
                "description": "display tekst"
              }
          ],
          "is_required": false,
          "multiple_values_allowed": false,
          "is_financial": false
      },
      "Taal": {
          "code": "{B299A824-1174-9501-70B0-1F505B50E18F}",
          "values": [
              "nl": {
                "value": null,
                "description": "display tekst"
              },
              "eng": {
                "value": '25',
                "description": "Engels"
              },
              "du": [],
              "pl": {
                "value": '50',
                "description": null
              }
          ],
          "is_required": true,
          "multiple_values_allowed": false,
          "is_financial": true,
          "vat": 21,
          "vat_code": 2
      }
    },
    "recurrence": [
        {
            "id": 1,
            "period": 14,
            "unit": "maanden",
            "is_required": true,
            "href": "http://development.api.planaday.localhost/v1/coursetemplate/1"
        },
        {
            "id": 1,
            "period": 23,
            "unit": "maanden",
            "is_required": true,
            "href": "http://development.api.planaday.localhost/v1/coursetemplate/1"
        }
    ],
    "language": "NL",
}

View Course Detail
GET/course/{course_id}

Use this call to fetch detailed information about one (1) course

Error codes

Code Message
401 No Access Right
404 Course not found
URI Parameters
HideShow
course_id
number (required) 

ID of the Course in the form of an integer


Course dayparts

GET https://apitest.api.planaday.net/v1/course/course_id/dayparts&offset=offset&limit=limit
Responses200
Headers
Content-Type: application/json
Body
{
    "meta": {
       "page": {
           "offset": 1,
           "limit": 2,
           "total": 1
       }
    },
    "data": [
       {
           "id" : 1,
           "name": "Dagdeel 1",
           "description": "",
           "status": "active",
           "date": "20160301",
           "start_time": "09:00",
           "end_time": "17:00",
           "is_elearning": 0,
           "visible": true,
           "users": {
               "scheduled": 10,
               "options": 0,
               "waitinglist": 2
           },
           "locations": [
               "id": 1,
               "href": "https://apitest.api.planaday.nl/v1/location/1"
           ],
           "costs": {
               "user": "0",
               "vat": "0"
           },
           "has_code95": 1,
           "code95" : {
               "practice": 12,
               "theory": 5
           },
           "labels": [
               "CODE95"
           ],
           "attributes": {
              "Take exam": {
                  "code": "{182BF814-FAA4-1C3C-941A-FCD180A78033}",
                  "values": [
                      "ja": {
                        "value": "50",
                        "description": "display tekst"
                      },
                      "nee": {
                        "value": "0",
                        "description": "display tekst"
                      }
                  ],
                  "is_required": true,
                  "multiple_values_allowed": false,
                  "is_financial": true,
                  "vat": 21,
                  "vat_code": 2
             }
           },
           "href": "https://apitest.api.planaday.nl/v1/daypart/1"
       },
       {
           "id" : 2,
           "name": "Dagdeel 2: elearning",
           "description": "",
           "status": "active",
           "date": "20200901",
           "start_time": "09:00",
           "end_time": "17:00",
           "is_elearning": 1,
           "visible": true,
           "date_finish_before": "20210901",
           "users": {
               "scheduled": 10,
               "options": 0,
               "waitinglist": 2
           },
           "locations": [
               "id": 2,
               "href": "https://apitest.api.planaday.nl/v1/location/2"
           ],
           "costs": {
               "user": "0",
               "vat": "0",
               "vat_code": 0
           },
           "has_code95": 0,
           "is_elearning": 1,
           "labels": [
               "EHBO",
               "BHV"
           ],
           "href": "https://apitest.api.planaday.nl/v1/daypart/2"
       }
    ],
    "links": {
           "self": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=20",
           "first": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=1",
           "last": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=40",
           "next": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=40",
           "previous": "https://apitest.api.planaday.net/v1/course/1/dayparts?limit=20&offset=1"
    }
}

View list of dayparts of Course
GET/course/{course_id}/dayparts&offset={offset}&limit={limit}

Use this call to fetch detailed information the dayparts of one (1) course

Error codes

Code Message
401 No Access Right
404 Course not found
URI Parameters
HideShow
course_id
number (required) 

ID of the Course in the form of an integer

offset
number (optional) 

Start offset of dayparts to show (i.e. 25)

limit
number (optional) 

Amount of dayparts to show in one response (i.e. 25, limited to 100)


Course materials

GET https://apitest.api.planaday.net/v1/course/course_id/materials&offset=offset&limit=limit&label=
Responses200
Headers
Content-Type: application/json
Body
{
  "meta": {
    "page": {
      "offset": 1,
      "limit": 20,
      "total": 2
    }
  },
  "data": [
    {
      "id": 450,
      "code": "b997b",
      "name": "Brandblusser stift",
      "description": "",
      "selling_price": 125
    },
    {
      "id": 450,
      "code": "0460d",
      "name": "Verband schrift",
      "description": "",
      "selling_price": 88,
      "vat": 21,
      "vat_code": 2
    }
  ],
  "links": {
    "self": "https://apitest.api.planaday.net/v1/course/1/materials?limit=20&offset=20",
    "first": "https://apitest.api.planaday.net/v1/course/1/materials?limit=20&offset=1",
    "last": "https://apitest.api.planaday.net/v1/course/1/materials?limit=20&offset=40",
    "next": "https://apitest.api.planaday.net/v1/course/1/materials?limit=20&offset=40",
    "previous": "https://apitest.api.planaday.net/v1/course/1/materials?limit=20&offset=1"
  }
}

View list of materials of Course
GET/course/{course_id}/materials&offset={offset}&limit={limit}&label=

Use this call to fetch the materials of one (1) course

Error codes

Code Message
401 No Access Right
404 Course not found
URI Parameters
HideShow
course_id
number (required) 

ID of the Course in the form of an integer

offset
number (optional) 

Start offset of materials to show (i.e. 25)

limit
number (optional) 

Amount of materials to show in one response (i.e. 25, limited to 100)


Coursetemplate

With the coursetemplate api you can fetch information about a coursetemplate.

List Coursetemplates

GET https://apitest.api.planaday.net/v1/coursetemplate/list
Requestsexample 1
Headers
X-Api-Key: <apikey>
Responses200
Headers
Content-Type: application/json
Body
{
  "coursetemplates": [
    {
      "id": 1,
      "code": "a5f-#Y#M-#3C",
      "name": "Achterdeur maken",
      "description": null,
      "daypart_amount": 1,
      "has_elearning": 1,
      "has_code95": 0,
      "has_soob": 0,
      "labels": [
        "CODE95"
      ],
      "language": "NL",
      "href": "https://apitest.api.planaday.nl/v1/coursetemplate/1"
    },
    {
      "id": 2,
      "code": "b44-#Y#M-#3C",
      "name": "Band repareren",
      "description": null,
      "daypart_amount": 3,
      "has_elearning": 0,
      "has_code95": 0,
      "has_soob": 0,
      "labels": [
        "EHBO",
        "BHV"
      ],
      "language": "NL",
      "href": "https://apitest.api.planaday.nl/v1/coursetemplate/2"
    }
}

Get list of Coursetemplates
GET/coursetemplate/list

Use this call to get a list of coursetemplates. Only coursetemplates with 1 or more dayparts are returned.

Error codes

Code Message
400 Bad Request
401 No Access Right

Get Coursetemplate

GET https://apitest.api.planaday.net/v1/coursetemplate/coursetemplate_id
Requestsexample 1
Headers
X-Api-Key: <apikey>
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1,
  "href": "https://apitest.api.planaday.nl/v1/coursetemplate/1",
  "code": "511-#Y#M-#3C",
  "name": "Televisie opkopen",
  "description": null,
  "daypart_amount": 2,
  "dayparts": [
    {
      "id": 2,
      "href": "https://apitest.api.planaday.nl/v1/daypart/2"
    },
    {
      "id": 1,
      "href": "https://apitest.api.planaday.nl/v1/daypart/1"
    }
  ],
  "users": {
    "min": 5,
    "max": 12
  },
  "costs": {
    "user": 384,
    "course": 3179,
    "vat": 21,
    "vat_code": 2,
    "remark": null
  },
  "level": "Advanced",
  "has_elearning": 1,
  "has_code95": 0,
  "has_soob": 0,
  "labels": [
      "EHBO",
      "CODE95"
  ],
  "attributes": {
    "Take exam": {
      "code": "{182BF814-FAA4-1C3C-941A-FCD180A78033}",
      "values": [
          "ja": {
            "value": "50",
            "description": "display tekst"
          },
          "nee": {
            "value": "0",
            "description": "display tekst"
          }
      ],
      "is_required": true,
      "multiple_values_allowed": false,
      "is_financial": true,
      "vat": 21,
      "vat_code": 2
    }
  },
  "language": "NL"
}

View Coursetemplate Detail
GET/coursetemplate/{coursetemplate_id}

Use this call to fetch detailed information about one (1) coursetemplate.

Error codes

Code Message
400 Bad Request
401 No Access Right
404 Coursetemplate not found
URI Parameters
HideShow
coursetemplate_id
number (required) 

ID of the Location in the form of an integer


Daypart

With the daypart api you can fetch information about dayparts.

Get Daypart

GET https://apitest.api.planaday.net/v1/daypart/daypart_id
Requestsexample 1
Headers
X-Api-Key: <apikey>
Responses200
Headers
Content-Type: application/json
Body
{
  "href": "https://apitest.api.planaday.nl/v1/daypart/1",
  "id": 1,
  "code": null,
  "name": "Dagdeel #0",
  "description": null,
  "status": "concept",
  "date": "20200710",
  "date_finish_before": "20210710",
  "start_time": "12:30",
  "end_time": "17:00",
  "locations": [],
  "users": {
    "scheduled": 0,
    "options": 0,
    "waitinglist": 0
  },
  "costs": {
    "user": null,
    "vat": 21,
    "vat_code": 2
  },
  "has_code95": 1,
  "code95" : {
      "practice": 12,
      "theory": 5
  },
  "is_elearning": 1,
  "visible": true,
  "labels": [
      "CODE95"
  ],
  "attributes": {
    "Take exam": {
        "code": "{182BF814-FAA4-1C3C-941A-FCD180A78033}",
        "values": [
            "ja": {
              "value": "50",
              "description": "display tekst"
            },
            "nee": {
              "value": "0",
              "description": "display tekst"
            }
        ],
        "is_required": true,
        "multiple_values_allowed": false,
        "is_financial": true,
        "vat": 21,
        "vat_code": 2
    }
  }
}

View Daypart Detail
GET/daypart/{daypart_id}

Use this call to fetch detailed information about one (1) daypart.

Error codes

Code Message
400 Bad Request
401 No Access Right
404 Daypart not found
URI Parameters
HideShow
daypart_id
number (required) 

ID of the Daypart in the form of an integer


Daypart materials

GET https://apitest.api.planaday.net/v1/daypart/daypart_id/materials&offset=offset&limit=limit&label=
Responses200
Headers
Content-Type: application/json
Body
{
  "meta": {
    "page": {
      "offset": 0,
      "limit": 20,
      "total": 1
    }
  },
  "data": [
    {
      "id": 450,
      "code": "b997b",
      "name": "Brandblusser stift",
      "description": "",
      "selling_price": 125,
      "vat": 21,
      "vat_code": 2
    }
  ],
  "links": {
    "self": "https://apitest.api.planaday.net/v1/daypart/1/materials?limit=20&offset=20",
    "first": "https://apitest.api.planaday.net/v1/daypart/1/materials?limit=20&offset=1",
    "last": "https://apitest.api.planaday.net/v1/daypart/1/materials?limit=20&offset=40",
    "next": "https://apitest.api.planaday.net/v1/daypart/1/materials?limit=20&offset=40",
    "previous": "https://apitest.api.planaday.net/v1/daypart/1/materials?limit=20&offset=1"
  }
}

View list of materials of a Daypart
GET/daypart/{daypart_id}/materials&offset={offset}&limit={limit}&label=

Use this call to fetch the materials of one (1) daypart

Error codes

Code Message
401 No Access Right
404 Daypart not found
URI Parameters
HideShow
daypart_id
number (required) 

ID of the Daypart in the form of an integer

offset
number (optional) 

Start offset of materials to show (i.e. 25)

limit
number (optional) 

Amount of materials to show in one response (i.e. 25, limited to 100)


Label

With the label api you can fetch information about used labels.

Label list

GET https://apitest.api.planaday.net/v1/label/list
Requestsexample 1
Headers
X-Api-Key: <apikey>
Responses200
Headers
Content-Type: application/json
Body
{
  "labels": [
    {
      "id": 1,
      "name": "EHBO",
      "description": null,
    },            
    {
      "id": 2,
      "name": "CODE95",
      "description": null,
    },
    {
      "id": 3,
      "name": "BHV",
      "description": "Alle BHV gerelateerde items",
    }
  ]
}

Get a list of labels
GET/label/list

Use this call to get a list of label.

Error codes

Code Message
400 Bad Request
401 No Access Right

Location

With the location api you can fetch information about locations.

Get Location

GET https://apitest.api.planaday.net/v1/location/location_id
Requestsexample 1
Headers
X-Api-Key: <apikey>
Responses200
Headers
Content-Type: application/json
Body
{
  "id": 1,
  "name": "Dolores.",
  "code": "65b77",
  "address": {
    "street_1": null,
    "street_2": null,
    "housenumber": 219,
    "housenumber_extension": null,
    "zipcode": "8618WY",
    "city": "Soerendonk",
    "country": "Nederland",
    "lat": 0,
    "lng": 0
  },
  "contact_info": {
    "phonenumber_1": null,
    "email": null,
    "website": null
  },
  "description": null,
  "capacity": 11,
  "overbookable": false,
  "costs": {
    "price": 40,
    "vat": 21,
    "vat_code": 2
  },
  "href": "https://apitest.api.planaday.nl/v1/location/1"
}

View Location Detail
GET/location/{location_id}

Use this call to fetch detailed information about one (1) location.

Error codes

Code Message
400 Bad Request
401 No Access Right
404 Location not found
URI Parameters
HideShow
location_id
number (required) 

ID of the Location in the form of an integer


Changelist

Here you will find a list of changes made to the API.

Symbol Description
+ Added
- Removed
* Bugfix
. General

21-09-2021

What Changes
+ Added ‘status’ in daypart block to ‘GET /course/{courseId}’
+ Added ‘status’ in daypart block to ‘GET /course/{courseId}/dayparts’
+ Added ‘status’ in daypart block to ‘GET /daypart/{daypartId}’

23-08-2021

What Changes
+ Added optional ‘freefields’ to ‘GET /course/{courseId}’

History

Date What Changes
What Changes
02-08-2021 +
02-08-2021 +
02-08-2021 +
02-08-2021 +
02-08-2021 +
01-05-2021 +
01-05-2021 +
01-05-2021 .
01-05-2021 +
28-04-2021 +
28-04-2021 +
28-04-2021 +
28-04-2021 +
28-04-2021 +
15-30-2021 +
17-02-2021 +
17-02-2021 +
17-02-2021 +
17-02-2021 +
17-02-2021 +
17-02-2021 +
17-02-2021 +
17-02-2021 +
17-02-2021 +
13-01-2021 .
23-11-2020 +
23-11-2020 +
23-11-2020 +
18-11-2020 +
18-11-2020 +
18-11-2020 +
18-11-2020 +
30-10-2020 +
30-10-2020 +
30-10-2020 +
30-10-2020 +
20-10-2020 +
20-10-2020 +
20-10-2020 +
27-08-2020 +
27-08-2020 +
27-08-2020 +
27-08-2020 +
21-08-2020 +
21-08-2020 +
21-08-2020 +
17-08-2020 .
17-08-2020 +
17-08-2020 +
17-08-2020 +
17-08-2020 +
17-08-2020 +
17-08-2020 +
17-08-2020 +
17-08-2020 +
31-07-2020 +
31-07-2020 *
19-05-2020 +
19-05-2020 +
19-05-2020 +
18-05-2020 +
18-05-2020 *
03-02-2020 +
03-02-2020 .
03-02-2020 +
18-10-2019 +
18-10-2019 *
01-01-2019 .

Generated by aglio on 11 Nov 2021