Overview
Welcome to Sunlight's API! Use our api to create groups, invite users to a group, see the activities of a group's users and many other things.
The api is organized around REST and was built under the JSON API specifications.
Send your pull-requests to https://github.com/jalagrange/slate
Query parameters
All routes support query parameters to refine responses
include, e.g.
GET /api/v2/orders?include=category
to include properties of the order relationshipsort, e.g.
GET /api/v2/orders?sort=name
to sort all accounts ascending by namepage, e.g.
GET /api/v2/orders?page[number]=1&page[size]=10
to return only the first 10 ordersfilter, The
filter
is not defined by JSON API. Implementations must specify how thefilter
query parameter is supported.
Authentication
Pass a Bearer token in an Authorization header.
$ curl 'https://app.sunlight.is/api/endpoint' \
-H 'Authorization: Bearer c38e1f24a1b71ece08d29a04fa3daa7d58e71a5d58b660ae8b802732d42bf90b'
Authentication is done through the API key that will be provided by sunlight support.
Requests are authenticated passing your API key as a bearer token in an authorization header.
Groups
Groups help you organize better the users in sunlight. They allow you to monitor what the members are learning as well as know what they are spending their sunlight on.
Group Model
Example Group Object
{
"id": "806b946cf5",
"name": "Sunlight",
"address": "Planet Earth",
"bio": "Test",
"about-url": "https://sunlight.is",
"manager-approval": false,
"privacy-setting": "admin-invite",
"avatar-url": "https://sunlight-production-beanstalk.s3.amazonaws.com/avatar.jpeg",
"cover-url": "https://sunlight-production-beanstalk.s3.amazonaws.com/cover.jpeg",
"number-of-members": 1
"created-at": "2017-07-20T15:19:04.416Z",
"updated-at": "2017-07-20T15:19:04.416Z",
}
A group object contains the following fields
Attribute | Type | Description |
---|---|---|
id | string | The sunlight defined id representing the group |
name | string | The name of the group |
address | string | The address of the group |
bio | string | A short description of the group |
abour-url | strin g | Url for the group's website. |
manager-approval | boolean | If the orders requires manager approval |
privacy-setting | string | Group privacy type |
avatar-url | string | Avatar url of the group |
cover-url | string | Cover url of the group |
number-of-members | integer | The number of users in the group |
created-at | timestamp | The datetime the group was added to Sunlight |
updated-at | timestamp | The datetime the group was updated to Sunlight |
privacy-settings:
You can choose to allow people join your group at anytime, have them request invites or only allow them to join by an admin’s invitation.
admin-invite
: People can only join by an invitation from a group admin (Available)public_access
: People can join your group at anytime (Not available)request_invite
: People request invite to join a group (Not available)
manager-approval
true
: if you’d like every order that uses funds from this group to require approval from a group admin.false
: if you wouldn't like every order that uses funds from this group to require approval from a group admin.
Create group
Create Group Example
$ curl -X POST \
https://app.sunlight.is/api/groups \
-H 'accept: application/vnd.api+json' \
-H 'authorization: Bearer <your api key>' \
-H 'content-type: application/json' \
-d '{
"data": {
"attributes": {
"name": "Sunlight",
"address": "Planet Earth",
"about-url": "https://sunlight.is",
"bio": "Give Sunlight to employees, friends and family for them to spend on education."
"privacy-setting": "admin-invite",
"manager-approval": true
}
}
}'
The encoded json response looks like:
HTTP/1.1 201 CREATED
{
"data": {
"type": "groups",
"id": "806b946cf5",
"attributes": {
"id": "806b946cf5",
"name": "Sunlight",
"address": "Planet Earth",
"bio": "Give Sunlight to employees, friends and family for them to spend on education.",
"avatar-url": null,
"cover-url": null,
"about-url": "https://sunlight.is",
"privacy-setting": "admin-invite",
"manager-approval": true,
"created-at": "2017-07-20T15:19:04.416Z",
"slack-config-url": null,
"slack-url": null,
"slack-token": null,
"number-of-members": 1
},
"links": {
"self": "/groups/806b946cf5"
},
"relationships": {}
},
"included": []
}
Groups can be created via a POST
to https://app.sunlight.is/api/groups
, which accepts a JSON object describing the group.
Query Parameters
The table below shows the fields you can create for a group
Parameter | Required | Description |
---|---|---|
name | yes | The name of the group |
address | no | The address of the group |
bio | no | A short description of the group |
abour-url | no | Url for the group's website. |
manager-approval | no | If the orders require manager approval |
privacy-setting | yes | Group privacy type |
avatar-url | no | Avatar url of the group |
cover-url | no | Cover url of the group |
Invite a user to a group
Invite unregistered user to Group - Example
$ curl -X POST \
https://app.sunlight.is/api/v2/group-invitations \
-H 'accept: application/vnd.api+json' \
-H 'authorization: Bearer <your api key>' \
-H 'content-type: application/json' \
-d '{
"data": {
"attributes": {
"email": "jose@sunlight.is"
},
"relationships": {
"group": {
"data": {
"id": "9030927d27"
}
}
}
}
}'
The encoded json response looks like:
HTTP/1.1 201 CREATED
{
"data": {
"type": "group-users",
"id": "a910564e67",
"attributes": {
"id": "a910564e67",
"administrator": false
},
"links": {
"self": "/group-users/a910564e67"
},
"relationships": { }
},
"included": []
}
Invite registered user to Group - Example
$ curl -X POST \
https://app.sunlight.is/api/v2/group-users \
-H 'accept: application/vnd.api+json' \
-H 'authorization: Bearer <your api key>' \
-H 'content-type: application/json' \
-d '{
"data": {
"attributes": {
administrator: false
},
"relationships": {
"user": {
"data": {
"id": "54a4759f2c"
}
},
"group": {
"data": {
"id": "9030927d27"
}
}
}
}
}'
The encoded json response looks like:
HTTP/1.1 201 CREATED
{
"data": {
"type": "group-users",
"id": "832a222ad8",
"attributes": {
"id": "832a222ad8",
"administrator": false
},
"links": {
"self": "/group-users/832a222ad8"
},
"relationships": { }
}
}
The groups allow you to invite registered and unregistered users in sunlight, to each case there are different params and different endpoints.
To unregistered users
via a POST
to https://app.sunlight.is/api/group-invitations
, which accepts a JSON object.
Parameter | Required | Description |
---|---|---|
yes | The email of the user you want to invite | |
relationships[group][id] | yes | Group id which the user will be joining to. |
To registered users
via a POST
to https://app.sunlight.is/api/group-users
, which accepts a JSON object.
Parameter | Required | Description |
---|---|---|
administrator | yes | true if you want the user to be group admin |
relationships[user][id] | yes | User's id of the user you want to invite |
relationships[group][id] | yes | Group's id which the user will be joining |
Edit budget of an individual user
Edit budget of an individual user - Example
$ curl -X POST \
https://sunlight.is/api/credits \
-H 'accept: application/vnd.api+json' \
-H 'authorization: Bearer <your api key>' \
-H 'content-type: application/json' \
-d '{
"data": {
"attributes": {
"amount": "100"
},
"relationships": {
"group-user": {
"data": {
"id": "e70099a393"
}
}
}
}
}'
The encoded json response looks like:
{
"data": {
"type": "transactions",
"id": "ec28e8f7c2",
"attributes": {
"id": "ec28e8f7c2",
"amount": 100,
"created-at": "2017-07-26T14:30:54.649Z",
"source": "credit"
},
"links": {
"self": "/transactions/ec28e8f7c2"
},
"relationships": { }
}
}
Budget is one way that users in a group get sunlight, it allows groups to budget a certain amount of money they use to invest in their education.
Can edit the budget for each member of a group individually via POST
tohttps://app.sunlight.is/api/credit
Query Parameters
Parameter | Required | Description |
---|---|---|
amount | yes | Amount of money expressed in cents. |
relationships[group-user][id] | yes | group-user id |
Orders
An Order is a request for a purchase of a certain Item.
Order Model
Example Order Object
{
"id": "1d7986fed6",
"name": "Silent Child",
"url": "https://www.amazon.co.uk/Silent-Child-Sarah-Denzil-ebook/dp/B01MUDRSND",
"provider": "Amazon",
"cost": 0,
"price": 100,
"status": "completed",
"delivery-email": "user@sunlight.is",
"address": null,
"created-at": "2017-03-07T15:45:22.224Z",
"updated-at": "2017-05-29T20:30:07.969Z",
"status-changed-at": "2017-03-16T18:50:36.190Z"
}
A order object contains the following fields
Attribute | Type | Description |
---|---|---|
id | string | The sunlight defined id representing the order. |
name | string | The name of the order. |
url | string | Url to find out more about the item or where to buy it. |
provider | string | Name of the provider of the item to be purchased. |
cost | integer | Additional costs associated with the order. |
price | integer | Order price. |
status | string | Status in which the order is found. |
delivery-email | string | Email of the person who will receive the order. |
address | string | The delivery address of the order. |
created-at | timestamp | The time the order was added to Sunlight. |
updated-at | timestamp | The time the order was updated to Sunlight. |
status-changed-at | timestamp | The time the order status was update to Sunlight. |
Orders List
Orders List - Example
$ curl -X GET \
https://app.sunlight.is/api/v2/orders \
-H 'accept: application/vnd.api+json' \
-H 'authorization: Bearer <your api key>' \
-H 'content-type: application/json' \
The encoded json response looks like:
HTTP/1.1 200 OK
{
"data": [
{
"type": "orders",
"id": "1d7986fed6",
"attributes": {
"id": "1d7986fed6",
"name": "Silent Child",
"url": "https://www.amazon.co.uk/Silent-Child-Sarah-Denzil-ebook/dp/B01MUDRSND/ref=sr_1_1?ie=UTF8",
"provider": "Amazon",
"cost": 0,
"status": "cancelled",
"delivery-email": "juan@sunlight.is",
"address": null,
"price": 123,
"created-at": "2017-03-07T15:45:22.224Z",
"updated-at": "2017-05-29T20:30:07.969Z",
"status-changed-at": "2017-03-16T18:50:36.190Z"
},
"links": {
"self": "/orders/1d7986fed6"
},
"relationships": { }
},
{
"type": "orders",
"id": "a5cdf56821",
"attributes": {
"id": "a5cdf56821",
"name": "Platzi Subscription",
"url": "https://platzi.com/comprar/mensual/?course=todos",
"provider": "Platzi",
"cost": 0,
"status": "completed",
"delivery-email": "gabriel@sunlight.is",
"address": "Venezuela",
"price": 2900,
"created-at": "2017-03-06T16:38:18.516Z",
"updated-at": "2017-05-29T20:30:11.260Z",
"status-changed-at": "2017-03-06T16:39:38.110Z"
},
"links": {
"self": "/orders/a5cdf56821"
},
"relationships": { }
}
],
"meta": {
"total-open": 0,
"total-waiting": 0,
"total-waiting-manager-approval": 0,
"total-approved": 0,
"total-manager-approved": 0,
"total-payment-method-issued": 0,
"total-completed": 1,
"total-cancelled": 1,
"total-refunded": 0,
"totalPages": 1
},
"links": {
"self": "https://app.sunlight.is/orders?page[number]=1&page[size]=10",
"first": "https://app.sunlight.is/orders?page[number]=1&page[size]=10",
"prev": "https://app.sunlight.is/orders?page[number]=0&page[size]=10",
"next": "https://app.sunlight.is/orders?page[number]=2&page[size]=10",
"last": "https://app.sunlight.is/orders?page[number]=2&page[size]=10"
},
"included": []
}
You can fetch a list of orders via a GET
to https://app.sunlight.is/api/v2/orders
. The order list is sorted by the updated-at
field and by default is ordered descending, most recently updated first.
Query Parameters
Parameter | Required | Description |
---|---|---|
page[number] | no | What page of results to fetch defaults to first page. |
page[size] | no | How many results per page defaults to 10, max is 50. |
sort | no | what field to sort the results by. Valid values: name , created-at , update-at , total , status , provider |
filter | no | The filter query parameter is reserved for filtering data. Valid Values: group-id , received-by , status , id |
Filters
Filter | Description | Uri Example |
---|---|---|
id |
Filter by order id | /orders?filter[id]=e67c60e651 |
group-id |
Filter by group-id | /orders?filter[group-id]=410aff7f39 |
received-by |
Filter by user-id who owns the order | /orders?filter[received-by]=2bc8066314 |
status |
Filter by order status | /orders?filter[status]=completed |
Activities
The activities registers actions the users makes, like joining a group, leaving a group or buying a resource.
Activity Object
Order Object Example
"id": "a22a227b28",
"description": "has left the Slice Group",
"track-type": "leave-group",
"created-at": "2017-05-30T01:28:37.695Z",
"subjects": {
"owner_id": "2bc8066314",
"owner_name": "Gabriel Morillo",
"group_id": "6f2d1b48d8",
"group_name": "Slice Group"
}
A activity object contains the following fields
Attribute | Type | Description |
---|---|---|
id | string | The sunlight defined id representing the group. |
description | text | Activity description. |
track-type | string | Type of activity. |
created-at | timestamp | The time the order was added to Sunlight. |
subjects | json | Metadata of the subjects involved in the activity. |
Activities List
Activities List - Example
$ curl -X GET \
https://app.sunlight.is/api/activities \
-H 'accept: application/vnd.api+json' \
-H 'authorization: Bearer <your access token>' \
-H 'content-type: application/json' \
The encoded json response looks like:
HTTP/1.1 200 OK
{
"data": [
{
"type": "activities",
"id": "0c295bbaea",
"attributes": {
"id": "0c295bbaea",
"description": "Bought 'Platzi Monthly Subscription' on Platzi.",
"track-type": "bought",
"created-at": "2017-06-06T20:47:21.698Z",
"subjects": {
"owner_id": "2bc8066314",
"owner_name": "Gabriel Morillo",
"order_id": "e67c60e651",
"order_provider": "Platzi",
"order_url": "https://platzi.com/comprar/mensual/?course=todos",
"resource_id": "e19aa8719d",
"resource_name": "Platzi Monthly Subscription"
}
},
"links": {
"self": "/activities/0c295bbaea"
},
"relationships": { }
},
{
"type": "activities",
"id": "45869407dd",
"attributes": {
"id": "45869407dd",
"description": "has joined the Slice Group Group",
"track-type": "joined-group",
"created-at": "2017-05-30T01:28:50.978Z",
"subjects": {
"owner_id": "2bc8066314",
"owner_name": "Gabriel Morillo",
"group_id": "6f2d1b48d8",
"group_name": "Slice Group"
}
},
"links": {
"self": "/activities/45869407dd"
},
"relationships": { }
}
],
"meta": {
"totalPages": 1,
"totalResults": 2
},
"links": {
"self": "https://app.sunlight.is/activities?page[number]=1&page[size]=10",
"first": "https://app.sunlight.is/activities?page[number]=1&page[size]=10",
"prev": "https://app.sunlight.is/activities?page[number]=0&page[size]=10",
"next": "https://app.sunlight.is/activities?page[number]=2&page[size]=10",
"last": "https://app.sunlight.is/activities?page[number]=2&page[size]=10"
},
"included": []
}
You can fetch a list of activities via a GET
to https://app.sunlight.is/api/activities
The activities list is sorted by the created-at
field and by default is ordered descending, by most recently created first.
Query Parameters
Parameter | Required | Description |
---|---|---|
page[number] | no | What page of results to fetch defaults to first page. |
page[size] | no | How many results per page defaults to 10, max is 50. |
filter | no | The filter query parameter is reserved for filtering data. Valid Values: owner-id , include-friends |
Filters
Filter | Description | Uri Example |
---|---|---|
id |
Filter by activity-id | /activities?filter[id]=0c295bbaea |
owner-id |
Filter by user-id | /activities?filter[owner-id]=2bc8066314 |
include-friends |
True if you want to include friends activities | /activities?filter[include-friends]=true |
Errors
HTTP Status codes
The Sunlight API uses the following codes:
Code | Meaning |
---|---|
200 | Ok -- The request was successful. |
201 | Created -- The resource was successfully created. |
202 | Accept -- The resource was asynchronously created |
204 | No Content - The server successfully processed the request and is not returning any content. |
400 | Bad Request -- General client error, possibly malformed data. |
401 | Unauthorized -- Your API key is wrong. |
403 | Forbidden -- The requested is hidden for administrators only. |
404 | Not Found -- The specified kitten could not be found. |
422 | Unprocessable Entity -- The request was well-formed but was unable to be followed due to semantic errors. |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |