DevelopersDocumentation

Feel REST API

API endpoints

Partner resource

All requests to do tips must be signed with partner token. Partner token is a string that must be obtained via the following API.

API online documentations: OpenAPI specification, Swagger, Scalar, API docs.

Get partner token

GET /api/v1/partner/<partner-key>/token?user=<user-id>

Parameters

URL parameter:

Headers:

Security note.

If the token is exposed to users (e.g. is used with Feel App JavaScript library), then it’s strongly recommended to provide user id parameter, otherwiser this token can be used to send signals to ANY user.

Response (JSON)
{
  partner_token: 'partner-token'
}

The token is valid for 24 hours. Please note that each subsequent request can return a different partner token. Multiple tokens obtained this way can be valid at the same time as long as they are not expired.

For security reason, to avoid partner key exposure we recommend to perform such requests from server side only, not from the client side.

User resource

Represents external users (users registered on partners’ websites)

Get user status

GET /api/v1/user/<user-id>/status?partner_token=<partner-token>

Parameters

URL parameter

Headers:

Response (JSON)

{ user_id: ‘user-id’, authenticated: true | false, online: true | false devices: , rooms: }

Request user authorization with QR code

GET /api/v1/user/<user-id>/auth?partner_token=<partner-token>

Parameters

URL parameter

Headers:

Response (JSON)

{ auth_token: ‘auth-token’ }

This request returns auth token which should be displayed as the QR code and scanned with FeelConnect.

Possible errors

Request user authorization with connection code

GET /api/v1/user/<user-id>/conncode

Parameters

URL parameter

Response (JSON)

{ connection_code: ‘connection-code’ } This request returns connection code which should be typed in in FeelConnect. Note The token is valid for 1 minute.

Possible errors

Getting notified about user status (beta)

Partners can be notified about user status change via http callback (web hook call). In order to do that the partner must implement a webhook endpoint web page which will be called by Feel platform each time user status is changed.

This webhook endpoint web page should be published somewhere on the internet and Feel platform should be notified about endpoint URL. This URL will be stored in the Feel platform database. Every time the status of any user has changed, Feel platform will send an HTTP request to the webhook endpoint.

Partners can use following script to submit URL of your webhook endpoint page to Feel platform: https://github.com/dulta/feelapp-api/blob/master/examples/webhook.php

Please download the script, change $PARTNER_KEY variable, upload it to your local web server and open in your browser.

You can also contact us so we change this URL in our database manually.

Each user status change will initiate a POST request to your webhook endpoint page. User status will be provided in POST variables:

Signed webhook messages

Partners can opt for receiving the user status web-hooks post messages with an authorization header in order to enforce end-to-end integrity. The signature headers included in the message by the Feel API are:

To verify the message integrity, the following steps are necessary according IETF HTTP Signatures draft RFC. We will use the following header as an example to illustrate the steps.

'Content-Type': 'application/x-www-form-urlencoded'
'Host': '127.0.0.1:40975'
'Authorization': 'Signature keyId="partner_key",algorithm="hmac-sha256",headers="date digest",signature="F+VUsyOcbpcOCGj9WbrBwG6vp1jseEb/feMv4gpUQuk="'
'Content-Length': '136', (), (), ('Date', u'Wed, 06 Mar 2019 16:34:53 GMT'), ('),
'Accept-Encoding': u'identity'
  1. Construct the signing string using the values of the headers specified in headers in that order:
    >> digest = sha256(message_payload)
    >> digest
    'Digest': 'SHA-256=pDxRTfF3W7ErElFzkhJ7M3t92luH6X4CLwYDY4o67q4='
    >> # construct the string concatenating headers...
    >> sts
    'date: Wed, 06 Mar 2019 16:34:53 GMT\ndigest: SHA-256=pDxRTfF3W7ErElFzkhJ7M3t92luH6X4CLwYDY4o67q4='
    
  2. Decode the base64 signature string:
	>> sig = b64decode("F+VUsyOcbpcOCGj9WbrBwG6vp1jseEb/feMv4gpUQuk=")
	>> sig
	'\x17\xe5T\xb3#\x9cn\x97\x0e\x08h\xfdY\xba\xc1\xc0n\xaf\xa7X\xecxF\xff}\xe3/\xe2\nTB\xe9'
  1. Compare the decoded signature with the hash the signing string using the algorithm (hmac-sha256) and the secret partner_key.
	>> sig == hmac.new(str(partner_key), sts, digestmod=hashlib.sha256).digest()
	True

Python example:

# receive incoming request...
# load partner_key ...
import base64
import hashlib
import hmac


# check that there is a authorization header
assert  "Authorization"  in incoming_request.headers
assert incoming_request.headers["Authorization"].startswith("Signature ")
import pdb; pdb.set_trace()

# check required signature parameters
_, sig_struct = incoming_request.headers["Authorization"].split(" ", 1)
sig_struct = {i.split("=", 1)[0]: i.split("=", 1)[1].strip('"') for i in sig_struct.split(",")}
for field in  "keyId", "algorithm", "signature":
	assert field in sig_struct

# check hash algorithm
assert sig_struct["algorithm"] == "hmac-sha256"

# get string to sign
headers = sig_struct.get("headers", "date").split(" ")
sts = []
for header in headers:
	value = incoming_request.headers[header]
	sts.append("{k}: {v}".format(k=header.lower(), v=value))
sts = "\n".join(sts).encode()

# verify signature
sig = base64.b64decode(sig_struct["signature"])
assert sig == hmac.new(str(partner_key), sts, digestmod=hashlib.sha256).digest()

Send a tip to the user

POST /api/v1/user/<user-id>/tip?partner_token=<partner-token>

Parameters

URL parameters:

Headers:

POST parameters:

Incremental strength increase

It possible to make the vibration ot the tip to be incrementally increasead by a percentage of is strength value by defining strength_increment and timestamp in the POST paramaters. The increment takes place when the actual tip timeframe overlaps with the previous tip time frame until the accumualted strength adds up to 100.

Example:

Possible errors

Getting realtime resource

GET /api/v1/user/<user-id>/realtime?partner_token=<partner-token>

Parameters

URL parameters:

Headers:

Response (JSON)

{ realtime_resource_id: ‘realtime-resource-id’ }

This request returns the realtime resource id which should be used with FellMe JavaScript SDK.

ERRORS

Room resource

Add user to the room

POST /api/v1/room/<room-id>/users?partner_token=<partner-token>

NOTE

User cannot be added to more than one room at the same time. If the user has already joined another room, this call will return error.

Parameters

URL parameters:

Headers:

POST parameters:

Response (JSON)

Returns {} in case of success

ERRORS

Delete user from the room

DELETE /api/v1/room/<room-id>/users/<user-id>?partner_token=<partner-token>

Parameters

URL parameters:

Headers:

Response (JSON)

Returns {} in case of success

ERRORS

Webpage resource

Add a webpage for the user

POST /api/v1/user/<user-id>/webpage?partner_token=<partner-token>

Parameters

URL parameters:

Headers:

POST parameters:

Response (JSON)

Returns {} in case of success

ERRORS

Delete page for the user

DELETE /api/v1/user/<user-id>/webpage?partner_token=<partner-token>

Parameters

URL parameters:

Headers:

POST parameters:

Response (JSON)

Returns {} in case of success

ERRORS

get all rooms with the user ids per room

GET /api/v1/rooms_with_users?partner_token=<partner-token>

Parameters

URL parameters:

Headers:

Response (JSON)
### Supported device models Feel Platform provides the list of all supported bluetooth device models via the following endpoint: `GET /api/v1/device_models` No authorization is required to access this endpoint. The endpoint returns a list of device records. Each record has following fields: - `product` - Bluetooth device model name, e.g. `Pearl` - `type` - Bluetooth device type, can be `Vibrator` or `Masturbator` - `manufacturer` - Bluetooth device manufacturer, e.g. `Kiiroo` * Note. This list is not about to be changed often. Please cache the returned value for a reasonable amount of time in order to decrease Feel Platform load.