TinTok tries to comply with standard HTTP and REST conventions as closely as possible in its use of HTTP methods (verbs).
Method | Usage |
---|---|
GET | Used to retrieve a resource |
POST | Used to create a new resource |
PUT | Used to replace an existing resource. Does not update associated resources. |
DELETE | Used to delete an existing resource |
TinTok tries to comply with standard HTTP and REST conventions as closely as possible in its use of HTTP status codes. All response bodies will include an error providing further information. If the Accept-Language
is present we try to return the response in the specified language. Currentlly only English and German
are supported.
Status code | Usage |
---|---|
200 OK | The request completed successfully |
201 Created | A new resource has been created successfully. The resource’s URI is available from the response’s Location header |
204 No Content | An update to an existing resource has been applied successfully, including deletes |
206 Partial Content | Indicates after a client request with a Range header the success of only returning partiall data |
400 Bad Request | The request was malformed |
401 Unauthrorized | The User is not authorized |
403 Forbidden | The User is not allowed to access this resource |
404 Not Found | The requested resource does not exist |
405 Method Not Allowed | The method is not allowed |
406 Not Acceptable | Only JSON is supported, if the client uses a different type of Content-Type this error is returned |
409 Conflic | The state of the Resource prevents the execution of the request |
411 Length Required | If the client did not provide a Content-Length field |
413 Payload To Large | The uploaded data or the request is bigger then 55 MB |
416 Range Not Satisfiable | If the client used an unsatisfiablle Range header |
422 Unprocessable Entity | The uploaded data is syntactically correct but contained semantic errors |
502 Bad Gateway | API Gateway is online but the server is offline ... |
5XX Internal Server Error | ... for every other 500er we don't know what went wrong, but be sure somebody is getting fired for that |
We use the following error structur for returning errors:
Field | Type | Description |
---|---|---|
timestamp | datetime | timestamp when the error occured |
status | Integer | http status code |
error | String | http reason phrase |
message | String or List of Object | In most of the cases this is a String describing the error, for constraint violations this is an object containg field name and error description |
path | String | path were the error occured |
TinTok uses the following headers:
Header | Description |
---|---|
Content-Encoding | Responses are always served as UTF-8 encoded |
Caching | Rresponses contain an apropriate caching header |
Content-Type | Only JSON is supported |
ETag | ETags are used to help the client optimize requests |
If-None-Match | Used in combination with ETag header to only fetch a resource if the resource changed |
Accept-Language | English and German are supported, if no Accept-Language header is present english is picked |
Accept | Is ignored, response is always served as JSON |
Location | Returned in case of a POST create response. It indicates for the client were the newlly created resource is awaylable |
Range | On endpoints were data like an image or video is returned this can be used by the client to retrieve data partially |
Besides the default JWT claims sub
, nbf
, iss
, exp
, iat
we include the following custom claims:
Claim Name | Description | Example |
---|---|---|
id | The token owners User id | 5982feee-64b7-11eb-ae93-0242ac130002 |
Register for TinTok
username required | string <email> <= 64 characters |
password required | string <password> [ 6 .. 64 ] characters ^(?!\s*$).+ |
given_name required | string <= 64 characters ^(?!\s*$).+ |
family_name required | string <= 64 characters ^(?!\s*$).+ |
location | string <= 64 characters Nullable |
biography | string <= 512 characters Nullable |
{- "username": "john@doe.de",
- "password": "secret",
- "given_name": "John",
- "family_name": "Doe",
- "location": "Darmstadt",
- "biography": "Hey! I'm using WhatsApp"
}
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "username": "john@doe.de",
- "given_name": "John",
- "family_name": "Doe",
- "location": "Darmstadt",
- "biography": "23, Informatiker"
}
Login to TinTok
username required | string <email> <= 64 characters |
password required | string <password> [ 6 .. 64 ] characters ^(?!\s*$).+ |
{- "username": "elliotalderson@protonmail.ch",
- "password": "pa$$word"
}
{- "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
- "prefix": "Bearer"
}
Refresh your JWT token if it is not expired for more then two weeks
token required | string^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-... old token to refresh |
{- "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}
{- "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
- "prefix": "Bearer"
}
There are two types of Notifications:
MATCH
CHAT
The Notifications data Map contains the following keys and values:
Chat Notifications are triggered if a User send a Chat message to another user.
Field Name | Description | Example |
---|---|---|
id | The senders User id | 5982feee-64b7-11eb-ae93-0242ac130002 |
name | The senders full name | Elliot Alderson |
messageId | The messages id | 13439a06-97c2-47fe-b167-6bc87675aed1 |
message | The chat messages content | Hey, what's up? |
type | is always CHAT |
CHAT |
Match Notifications are triggered if two Users match.
Field Name | Description | Example |
---|---|---|
id | The matches User id | 5982feee-64b7-11eb-ae93-0242ac130002 |
name | The matches full name | Elliot Alderson |
type | is always MATCH |
MATCH |
Add the FCM Token to your account to retrieve FCM notifications.
token required | string^(?!\s*$).+ |
{- "token": "e8emisqrQqyzQ2Sx41Svvb:APA91bFwq-Rj9GAIEBgFMirCtnLYLhu-jEeihMAJavwvdV6o6rgWh8yfFBSzN5hkgwq3qyM3EuZ5by2bTOS0SLy1t41M9jKul2LrdZxKa1x1nAxRhY5r0rIRU6477a8a4uTwsTkhtvKs"
}
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "username": "john@doe.de",
- "given_name": "John",
- "family_name": "Doe",
- "location": "Darmstadt",
- "biography": "23, Informatiker"
}
Update your own User Profile
given_name required | string <= 64 characters ^(?!\s*$).+ |
family_name required | string <= 64 characters ^(?!\s*$).+ |
location | string <= 64 characters Nullable |
biography | string <= 512 characters Nullable |
{- "given_name": "Elliot",
- "family_name": "Alderson",
- "location": "Darmstadt",
- "biography": "I'm Mr. Robot"
}
Update your password. If you registered with an OAuth provider like Google every password is accepted as old_password.
old_password | string <password> [ 6 .. 64 ] characters ^(?!\s*$).+ the Users old password. In case the account was registered with an OAuth2 provider this can be left empty. |
new_password required | string <password> [ 6 .. 64 ] characters ^(?!\s*$).+ new password to use |
{- "old_password": "pa$$word",
- "new_password": "new_pa$$word"
}
Retrieve a List of all your Matches. The collection is sorted on name
DESC.
[- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "Elliot Alderson",
- "biography": "Hello Friend.",
- "location": "Darmstadt"
}
]
Get a Post by its id. You can retrieve Posts which are recommended, one of your own Posts or if the Post is from one of your Matches.
id required | string <uuid> |
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "location": {
- "latitude": 17.82,
- "longitude": 19.01
}, - "text": "Hello Stranger.",
- "tags": [
- "series"
], - "created": "2019-08-24T14:15:22Z",
- "updated": "2019-08-24T14:15:22Z",
- "type": "TEXT"
}
Retrieve all Posts included in your feed. The page entries are sorted on created
DESC.
page | number Default: 0 Page number |
size | number Default: 20 Number of Elements per Page |
nbf | string <date-time> Default: "1900-01-01T00:00:00.000+00:00" Not Before - Only get Posts which are created after the supplied date. This should be used in case of updates of the Feed screen. You should not use that in combination with naf. |
naf | string <date-time> Default: "2100-01-01T00:00:00.000+00:00" Not After - Only get Posts which are created before the supplied date. This should be used for scrolling down the Feed screen. You should not use that in combination with nbf. |
{- "content": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "location": {
- "latitude": 0,
- "longitude": 0
}, - "text": "TigerKing!",
- "tags": [
- "series"
], - "created": "2019-08-24T14:15:22.000+01:00",
- "updated": "2019-08-24T14:15:22.000+01:00",
- "type": "IMAGE",
- "author": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f09",
- "name": "Elliot Alderson"
}, - "likes": 0,
- "dislikes": 0,
- "status": "NEUTRAL"
}
], - "last": true,
- "totalPages": 2,
- "totalElements": 10,
- "sort": {
- "sorted": false,
- "unsorted": true,
- "empty": true
}, - "number": 0,
- "first": true,
- "numberOfElements": 5,
- "size": 5,
- "empty": false,
- "pageable": {
- "sort": {
- "sorted": false,
- "unsorted": true,
- "empty": true
}, - "pageNumber": 0,
- "pageSize": 5,
- "offset": 0,
- "paged": true,
- "unpaged": false
}
}
Retrieve all your Posts in a paged fashion. The page entries are sorted by created
DESC.
page | integer Default: 0 page number |
size | integer >= 1 Default: 20 page size |
{- "content": [
- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "location": {
- "latitude": 0,
- "longitude": 0
}, - "text": "TigerKing!",
- "tags": [
- "series"
], - "created": "2019-08-24T14:15:22.000+01:00",
- "updated": "2019-08-24T14:15:22.000+01:00",
- "type": "IMAGE"
}
], - "last": true,
- "totalPages": 2,
- "totalElements": 10,
- "sort": {
- "sorted": false,
- "unsorted": true,
- "empty": true
}, - "number": 0,
- "first": true,
- "numberOfElements": 5,
- "size": 5,
- "empty": false,
- "pageable": {
- "sort": {
- "sorted": false,
- "unsorted": true,
- "empty": true
}, - "pageNumber": 0,
- "pageSize": 5,
- "offset": 0,
- "paged": true,
- "unpaged": false
}
}
Create a new Post. You can create a Post containing a Video, a Post containing an Image or a Post which only includes a Text
Create Post. There are three different kinds. You can either create a Post which only contains text - TextPost, you can create a Post which has an attached Image - ImagePost or you can create a Post with an attached video - VideoPost
required | object If you want to create a Text Post. |
{ "text_post": { "location": { "latitude": -90, "longitude": -180 }, "tags": [ "politics" ], "text": "Are you a one or a zero?" } }
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "location": {
- "latitude": 15,
- "longitude": 17
}, - "text": "Tiger King is so funny man! This is my all time fav",
- "tags": [
- "series"
], - "created": "2019-08-24T14:15:22Z",
- "updated": "2019-08-24T14:15:22Z",
- "type": "TEXT"
}
Update one of your Posts. You can update the Posts text and reassign Tags to the Post. You can not change the Posts type nor the Posts attached data
id required | string <uuid> Post ID |
id | number Post ID |
text | string <= 512 characters Nullable |
tags required | Array of strings [ 1 .. 8 ] items unique |
{- "text": "I love TigerKing so much, Trump should pardon Joe Exotic",
- "tags": [
- "series",
- "politics"
]
}
Get posts recommended to you. The collection is sorted from most likelly to least likelly for you.
latitude required | number [ -90 .. 90 ] current locations latitude |
longitude required | number [ -180 .. 180 ] current locations longitude |
size | integer <= 20 Default: 5 amount of posts to return |
except | Array of strings <uuid> <= 100 items unique Example: except=f39105eb-a43e-453f-a7de-97d5700bfa49&except=f39105eb-a43e-453f-a7de-97d5700bfa48 array of Post ids. Post ids are UUIDs. The response is garantued to not return posts which id is included in this array |
[- {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "location": {
- "latitude": 0,
- "longitude": 0
}, - "text": "TigerKing!",
- "tags": [
- "series"
], - "created": "2019-08-24T14:15:22.000+01:00",
- "updated": "2019-08-24T14:15:22.000+01:00",
- "type": "IMAGE"
}
]
Get a List of all Chats the User is participating in. Conversation entries are sorted by last
DESC
page | integer Default: 0 page number |
size | integer Default: 20 page size |
{- "content": [
- {
- "partner": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "Elliot Alderson"
}, - "last": "2020-08-24T14:15:22Z",
- "unread": 2,
- "message": "Hello Stranger.",
- "send": false
}
], - "last": true,
- "totalPages": 0,
- "totalElements": 0,
- "sort": {
- "sorted": true,
- "unsorted": true,
- "empty": true
}, - "number": 0,
- "first": true,
- "numberOfElements": 0,
- "size": 0,
- "empty": true,
- "pageable": {
- "sort": {
- "sorted": true,
- "unsorted": true,
- "empty": true
}, - "pageNumber": 0,
- "pageSize": 0,
- "offset": 0,
- "paged": true,
- "unpaged": true
}
}
Retrieve all Messages related to one specific Conversation sorted by newest to oldest in a Paged fashion. Each retrieved Chat is indiretlly marked as read on retrieve. The page is sorted on the message created
attribute DESC.
chatPartnerId required | string Your Matches id, you want to Chat with |
page | number Default: "0" page number |
size | number Default: 20 page size |
{- "content": [
- {
- "id": "497f6eca-6276-4993-bfeb-54cbbbba6f08",
- "created": "2019-08-24T14:17:22Z",
- "message": "How are you?",
- "send": false
}, - {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "created": "2019-08-24T14:15:22Z",
- "message": "Hello Stranger.",
- "send": true
}
], - "last": true,
- "totalPages": 0,
- "totalElements": 0,
- "sort": {
- "sorted": true,
- "unsorted": true,
- "empty": true
}, - "number": 0,
- "first": true,
- "numberOfElements": 0,
- "size": 0,
- "empty": true,
- "pageable": {
- "sort": {
- "sorted": true,
- "unsorted": true,
- "empty": true
}, - "pageNumber": 0,
- "pageSize": 0,
- "offset": 0,
- "paged": true,
- "unpaged": true
}
}
Send a message to a matched user. After sending the first message a Conversation is implicitlly created. Trying to send a message to a non matched User results in an error.
chatPartnerId required | string id of the Conversation / your Match |
message required | string <= 512 characters ^(?!\s*$).+ |
{- "message": "Hey, whats up?"
}
{- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "created": "2019-08-24T14:15:22Z",
- "message": "Hello.",
- "send": true
}