Our API

Welcome to Kourses API docs.

API methods provided can be used to create members and grant and revoke permission to access memberships.

Beside having an API routes, you can create a member and grant/revoke access for specific memberships using webhooks as well.

Authorization

API uses API key authorization (through Authorization Bearer authentication).

API key can be generated in Kourses App on Settings / API keys screen. When generating key you need to select a website for which the key will be intended. After generating the key, copy it and use it for authorization.

Example request

$ curl --location --request GET 'https://app.kourses.com/api/v1/memberships' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer GENERATED-API-KEY-TOKEN'

Memberships

Get list of all memberships that has at least one hub attached.

Membership entity

Property Type Description
id string Membership ID
name string Membership name
slug string Membership slug
url string Membership URL

List memberships

Lists all published memberships (with at least one hub) for a particular account (website).

Memberships will be paginated. Listed below are optional parameters that can be used for pagination.

Optional parameters

Property Default Description
per_page 100 number of memberships to return per page
page 1 current page
GET
/memberships

Example request

$ curl --location --request POST 'http://app.kourses.com/api/v1/memberships' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer GENERATED-API-KEY-TOKEN'

Example response

{
    "data": [
        {
            "id": "abcd1234",
            "title": "Membership name",
            "slug": "membership-name",
            "url": "https://example.com/membership/membership-name"
        },
        ...
    ],
    "meta": {
        "current_page": 2,
        "from": 11,
        "last_page": 3,
        "path": "https://app.kourses.com/api/v1/memberships",
        "per_page": 10,
        "to": 20,
        "total": 50
    }
}

Members

Create a member or list all of the memberships they are granted the access permission.

Member entity

Property Type Description
id string Member ID
email string Member email,
first_name string Member first name,
last_name string Member last name,
memberships array collection of allowed memberships or null
status string either created or updated depending whether member existed before

Create a member

Create a member for your Kourses website.

If member with the given email address already exists they will be overwritten with given optional parameters and the member status property returned will be set to updated.

Required parameters

Property Type Description
email string Member email address

Optional parameters

Property Type Description Default
first_name string First name "Unnamed"
last_name string Last name "Member"
country string Country (ISO Alpha-2)
state string State
city string City
zip string Postal code / zip
address string Address
address_2 string Apartment, suite, etc.
title string Profile title
send_activation_notification bool Flag whether to send newly created member an activation email "1" (will be sending out email)
POST
/members

Example request

$ curl --location --request POST 'http://app.kourses.com/api/v1/members' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer GENERATED-API-KEY-TOKEN' \
--form 'email="[email protected]"'

Example response

{
    "data": {
        "id": "abcd1234",
        "email": "[email protected]",
        "first_name": "Unnamed",
        "last_name": "Member",
        "memberships": null,
        "status": "created"
    }
}

Create a member and grant permissions to memberships

In order to save an API call (or two), while creating a member you can grant permissions for memberships in the same request.

Property Type Description Default
memberships array List of membership IDs to grant access to. For example ['abcd1234', 'bcde2345']
memberships_ends_at array List of key / value array with a permission ending date. For example ['abcd1234' => '2020-12-31']. Expects YYYY-MM-DD or YYYY-MM-DD hh:mm:ss date format
memberships_skip_drip_schedule array List of key / value array with a 0|1 flag whether to skip set drip schedule for a membership "0" (drip will be set according to original settings)
memberships_run_email_integrations array List of key / value array with a 0|1 flag whether to run email integrations for a membership "0" (email integrations will not be ran)
memberships_send_notification array List of key / value array with a 0|1 flag whether to send membership notification "0" (won't be sending out email)

We support additional request data structure in order to allow for easier Zapier and Make.com integrations. memberships array can be a nested structure with multiple items.

Each membership item should have a structure with this params:

Property Type Description Default
id string Membership IDs to grant access to. For example 'abcd1234'
ends_at string Permission ending date. For example '2020-12-31'. Expects YYYY-MM-DD or YYYY-MM-DD hh:mm:ss date format
skip_drip_schedule string String with a 0|1 flag whether to skip set drip schedule for a membership "0" (drip will be set according to original settings)
run_email_integrations string String with a 0|1 flag whether to run email integrations for a membership "0" (email integrations will not be ran)
send_notification string String with a 0|1 flag whether to send membership notification "0" (won't be sending out email)

Response is the same but we are showing it here as well.

POST
/members

Example request

$ curl --location --request POST 'https://app.kourses.com/api/v1/members' \
--header 'Accept: application/json' \
--header 'Authorization: GENERATED-API-KEY-TOKEN' \
--form 'email="[email protected]"' \
--form 'memberships[0]="abcd1234"' \
--form 'memberships[1]="bcde2345"' \
--form 'memberships_ends_at[abcd1234]="2020-12-31"' \
--form 'memberships_skip_drip_schedule[abcd1234]="1"'
--form 'memberships_run_email_integrations[abcd1234]="1"'
--form 'memberships_send_notification[abcd1234]="1"'

Example response

{
    "data": {
        "id": "abcd1234",
        "email": "[email protected]",
        "first_name": "Unnamed",
        "last_name": "Member",
        "memberships": [{
            "id": "abcd1234",
            "name": "Membership name",
            "slug": "membership-name",
            "url": "http://example.com/membership/membership-name"
        },{
            "id": "bcde2345",
            "title": "Another membership",
            "slug": "another-membership",
            "url": "http://example.com/membership/another-membership"
        }],
        "status": "updated"
    }
}

Example request

$ curl --location --request POST 'https://app.kourses.com/api/v1/members' \
--header 'Accept: application/json' \
--header 'Authorization: GENERATED-API-KEY-TOKEN' \
--form 'email="[email protected]"' \
--form 'memberships[0][id]="abcd1234"' \
--form 'memberships[0][ends_at]="2020-12-31"' \
--form 'memberships[0][skip_drip_schedule]="0"'
--form 'memberships[0][run_email_integrations]="0"'
--form 'memberships[0][send_notification]="0"'

Example response

{
    "data": {
        "id": "abcd1234",
        "email": "[email protected]",
        "first_name": "Unnamed",
        "last_name": "Member",
        "memberships": [{
            "id": "abcd1234",
            "name": "Membership name",
            "slug": "membership-name",
            "url": "http://example.com/membership/membership-name"
        },{
            "id": "bcde2345",
            "title": "Another membership",
            "slug": "another-membership",
            "url": "http://example.com/membership/another-membership"
        }],
        "status": "updated"
    }
}

List all memberships member have access to

List all member's memberships that they have been granted permission and whose permission has not expired yet.

To identify {member} either member's email or their ID needs to be used.

GET
/members/{member}/memberships

Example request

$ curl --location --request GET 'https://app.kourses.com/api/v1/members/abcd1234/memberships' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer GENERATED-API-KEY-TOKEN'

Example response

{
    "data": [{
        "id": "abcd1234",
        "name": "Membership name",
        "slug": "membership-name",
        "url": "http://example.com/membership/membership-name"
    }]
}

Generate signed login link which can be used to sign in existing member.

To identify {member} either member's email or their ID needs to be used.

Generated link will expire in 5 min (300 seconds).

Optional parameters

Property Type Description
redirect string Relative URL path where to redirect user after login
POST
/members/{member}/login-link

Example request

$ curl --location --request POST 'https://app.kourses.com/api/v1/members/abcd1234/login-link' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer GENERATED-API-KEY-TOKEN'

Example response

{
    "data": {
        "login_link": "https://test.mykourses.com/sso?expires=1234567890key=abcd1234&signature=abcdef1234567890",
        "expires_at": "2021-11-22T06:29:11.459707Z"
    }
}

Permissions

Grant or revoke a permission for a member to access the membership in Kourses website.

Access system is based on hubs. Member will be granted (or revoked) access for each hub in the membership.

Grant a permission

Grant member an access permission for the given membership. Optionally send ends_at datetime when the permission should expire.

Provide identification for {member} either as an email address or their ID and identification for a {membership} as its ID.

Optional parameters

Property Type Description Default
ends_at datetime Date when permission will stop working. Uses YYYY-MM-DD or YYYY-MM-DD hh:mm:ss format
skip_drip_schedule bool Flag whether to skip set drip schedule for a given membership "0" (drip will be set according to original settings)
run_email_integrations bool Flag whether to run email integrations for a given membership (set it to 1 in order for email integrations to be run) "0" (email integrations will not be ran)
send_notification bool Flag whether to send membership notification "0" (won't be sending out email)
POST
/members/{member}/memberships/{membership}/permissions

Example request

$ curl --location --request POST 'https://app.kourses.com/api/v1/members/abcd1234/memberships/abcd1234/permissions' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer GENERATED-API-KEY-TOKEN'

Example response

{
    "status": "Permission added!"
}

Revoke a permission

Revoke access for member for the given membership. Optionally send ends_at datetime when the permission should expire.

Provide identification for {member} either as an email address or their ID and identification for a {membership} as its ID.

Optional parameters

Property Type Description
ends_at datetime Date when permission will stop working. Uses YYYY-MM-DD or YYYY-MM-DD hh:mm:ss format
DELETE
/members/{member}/memberships/{membership}/permissions

Example request

$ curl --location --request DELETE 'https://app.kourses.com/api/v1/members/abcd1234/memberships/abcd1234/permissions' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer GENERATED-API-KEY-TOKEN'
$ curl --location --request DELETE 'https://app.kourses.com/api/v1/members/abcd1234/memberships/abcd1234/permissions?ends_at=2030-04-05' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer GENERATED-API-KEY-TOKEN'

Example response

{
    "status": "Permission removed!"
}
{
    "status": "Permission will be removed on 2030-04-05!"
}

Errors

Authorization errors

If provided API key is invalid or missing you'll get the HTTP 401 Unauthorized response.

Error response

{
    "error": "Unauthorized"
}

API throttling errors

Each API key has an API rate limit set to 200 requests per minute. If you exceed this number you'll get the HTTP 429 Too Many Requests response.

Error response

{
    "message": "Too Many Attempts."
}

Invalid API URL errors

If API URL is invalid a HTTP 404 Not found response will be returned.

Error response

{
    "error": "Not Found"
}

Validation errors

When creating members, if email is not provided, a HTTP 422 Unprocessable Entity response will be returned.

Error response

{
    "message": "The given data was invalid.",
    "errors": {
        "email": [
            "The email field is required."
        ]
    }
}

Permission errors

When granting (or revoking) a permission for a membership to a member, and provided member indentification (or membership ID, or both) are either invalid or if the records are not found in the DB the HTTP 400 Bad Request response will be returned.

This error may be returned if for example member was deleted or they does not exist at all. Or if the membership was deleted, unpublished or does not exist at all.

Example response

{
    "message": "Membership with ID abcd1234 not found."
}

Webhooks

Beside creating members and granting and revoking access using API, you may use special webhooks which are generated for each membership.

URLs for these webhooks can be found in your membership Integration / Webhooks screen. Log in to Kourses App, click on the "Memberships" page (in your main menu) and then click on the membership for which you want to get webhook URLs. Then click on the "Integration" link (in the membership top menu) and then select "Webhooks".

Two URLs are given. One for "Activation" and one for "Deactivation" and they look similar to these:

Grant permission

https://yoursubdomain.mykourses.com/api/memberships/abcd1234/activate?_token=a1b2c3d4e5f6a1b2c3d4e5f6

Revoke permission

https://yoursubdomain.mykourses.com/api/memberships/abcd1234/deactivate?_token=a1b2c3d4e5f6a1b2c3d4e5f6

Sending a GET or POST requests to there URL will create member and grant access to the membership or revoke access.

Granting access

Sending a GET or POST request to the "Activation" endpoint will create a member (assuming the member with a given email does not exist) and send them an activation email. And then grant an access to the membership.

In order to send out notification about newly assigned membership permissions, set send_membership_notification to 1.

Required parameters

Property Type Description
email string Email address
first_name string First name
last_name string Last name

Optional parameters

Property Type Description
ends_at string Date when permission access should expire. Expects YYYY-MM-DD or YYYY-MM-DD hh:mm:ss date format
external_user_id string Member ID from your platform

If member with a given email already exist, a HTTP 422 response will be thrown.

GET|POST
https://yoursubdomain.mykourses.com/api/memberships/{membership}/activate?_token={token}&send_membership_notification=(0|1)

Example request

$ curl --location --request POST 'https://yoursubdomain.mykourses.com/api/memberships/abcd1234/activate?_token=a1b2c3d4e5f6a1b2c3d4e5f6&send_membership_notification=1' \
--form 'email="[email protected]"' \
--form 'first_name="John"' \
--form 'last_name="Doe"' \
--form 'ends_at="2030-04-05"' \
--form 'external_user_id="cus_123"'

Example response

{
    "data": {
        "id": 1,
        "member_id": 1,
        "membership_id": 1,
        "website_id": 1,
        "ends_at": "2030-04-05 00:00:00",
        "external_user_id": "cust_123",
    }
}

Revoking access

Sending a GET or POST request to the "Deactivation" endpoint will revoke access to the membership for a member identified by email or external_user_id.

Parameters

Property Required Type Description
email required if external_user_id not set string Email address
external_user_id required if email not set string Member ID from your platform
ends_at optional string Date when permission access should expire. Expects YYYY-MM-DD or YYYY-MM-DD hh:mm:ss date format

If member with a given email (or external_user_id) is not found exist, a HTTP 404 response will be thrown.

GET|POST
https://yoursubdomain.mykourses.com/api/memberships/{membership}/activate?_token={token}

Example request

$ curl --location --request POST 'https://yoursubdomain.mykourses.com/api/memberships/abcd1234/deactivate?_token=a1b2c3d4e5f6a1b2c3d4e5f6' \
--form 'email="[email protected]"' \
--form 'ends_at="2030-04-05"'

Example response

{
    "status": {
        "id": 1,
        "member_id": 1,
        "membership_id": 1,
        "website_id": 1,
        "ends_at": "2030-04-05 00:00:00",
        "external_user_id": "cust_123",
    }
}
Show examples in:
Kourses API Documentation