咕咚网成立于2010年,是以用社会化、碎片化、移动化鼓励用户形成 更健康生活方式为目标的移动健康社交网络! 我们专注于移动互联网产品研发、提供产品配套网络平台服务。致力于解决亚健 康问题,运用先进的互联网、移动互联网技术与运动健康理念相结合, 通过将个 人运动电子产品网络化,打造最具影响力的互联网运动健康服务平台。
了解更多本文档用于引导第三方开放者在自己的应用中集成咕咚的帐号和该帐号所产生的数据。开发者通过认证鉴权接口从咕咚网获取咕咚用户的认证令牌,绑定认证令牌后。 即可通过此令牌访问咕咚的数据,并且在注册回调接口后还能在用户上传数据后得到实时的通知。
接入API需要申请咕咚网接入的AppKey和AppSecret。因为咕咚暂时没有开放申请,所以如果有接入的需求,请将您应用的简介和公司或者个人信息通过邮件发送到
support@codoon.com
接入测试可以使用测试的AppKey和AppSecret:app_key 3d1602888d5111e29f42782bcb058632
, app_secret 3d1606d48d5111e29f42782bcb058632
第三方应用通过认证授权接口获取咕咚用户的授权令牌,从而得到通过API读写数据的权限。大体过程如下图
URL | https://openapi.codoon.com/authorize |
访问方式 | 浏览器Redirect |
参数 |
|
https://openapi.codoon.com/authorize?client_id=xxx&redirect_uri=http%3A%2F%2Fapi.yourdomain.com%2Fget_code&response_type=code&scope=user,sports
将参数urlencode后放在url的参数部分,然后转跳到这个地址上。如果用户在咕咚网已经登录,就会显示授权页面,点击确认后会转跳到参数redirect_uri
所指定的地址
AccessCode通过参数code返回,示例如下:
http://api.yourdomain.com/get_code?code=xxxxxxxxxxxxxxxxxxxx
AccessCode是一个很重要的返回值,你需要将其存储起来供下一次调用使用。
在获取到AccessCode之后,就可以通过这个code获取授权令牌(Access Token)了。获取Access Token需要用之前获取的Access Code作为参数发起一次Http请求, 由于客户端发起容易被截获,建议在服务端发起这个请求。
URL | https://openapi.codoon.com/token |
访问方式 | POST |
HTTP HEADER | Key:Authorization Value:"Basic "+base64("AppKey:AppSecret") |
参数 |
|
下面是一个Python的例子
>>>import requests
>>>import base64
>>>client_key = "xxxxx"
>>>client_secret = "xxxxx"
>>>params = dict(
client_id="xxxxx",
grant_type="authorization_code",
code="xxxxxxxxxxxxxxxxxxxxxx",
redirect_uri="http://api.yourdomain.com/get_code",
scope="user,sports",
)
>>>headers = {'Authorization': 'Basic %s' % base64.b64encode(client_key + ":" + client_secret)}
>>>response = requests.post("https://openapi.codoon.com/token",data=params, headers=headers)
>>>print response.text
{"access_token": {access_token}, "token_type": "bearer", "expire_in": 3600, "refresh_token": {refresh_token}, "scope": {scope}}
返回json对象的格式:
access_token | 授权令牌,用于访问API接口的时候使用 |
token_type | 恒为Bearer |
expire_in | 距过期还剩多少秒 |
refresh_token | 重新获取AccessToken的刷新授权码 |
scope | 授权允许访问的接口范围 |
在获取授权令牌的时候,API授权接口会返回一个Refresh Token(刷新令牌)的值,这个值需要存起来,当授权令牌过期后,可以通过这个值去获取一个新的授权令牌, 从而不必再重复第一步从获取Access Code开始。执行这个过程的方式和第二步类似,地址相同,只是参数有所区别。
URL | https://openapi.codoon.com/token |
访问方式 | POST |
HTTP HEADER | Key:Authorization Value:"Basic "+base64("AppKey:AppSecret") |
参数 |
|
下面是一个Python的例子
>>>import requests
>>>import base64
>>>client_key = "xxxxx"
>>>client_secret = "xxxxx"
>>>params = dict(
client_id="xxxxx",
grant_type="恒为refresh_token",
refresh_token="xxxxxxxxxxxxxxxxxxxxxx",
scope="user,sports",
)
>>>headers = {'Authorization': 'Basic %s' % base64.b64encode(client_key + ":" + client_secret)}
>>>response = requests.post("https://openapi.codoon.com/token",data=params, headers=headers)
>>>print response.text
{"access_token": {access_token}, "token_type": "bearer", "expire_in": 3600, "refresh_token": {refresh_token}, "scope": {scope}}
返回值格式同第二步
在获取到用户的授权令牌后,第三方应用就可以使用这个令牌来访问用户的数据了,咕咚开放API暂时只支持Bearer这一种方式, 只需要将Access Token放到Http Header的Authorization键中即可
URL | https://openapi.codoon.com/api/method_name |
访问方式 | POST/GET |
认证参数 | Http Header: Authorization:Bearer {Access Token} |
API参数 | 接口所需参数均为命名参数,需要将参数组合成一个json对象,放在body里 |
下面是一个Python的示例
>>>import requests
>>>headers = {"Authorization": "Bearer %s" % accesstoken}
>>>post_data = {...}
>>>response = requests.request('POST', "https://openapi.codoon.com/api/api_func", data=json.dumps(post_data), headers=headers)
>>>print response.content
{rs:True,...}
返回值是一个json对象,根据不同的接口,返回值有所区别,将在API部分详细说明
API可以通过Http协议的GET和POST方法访问,如果没有注明用GET,否则建议使用POST方法
Method Name | verify_credentials |
访问方法 | GET |
API参数(Body) | {} |
返回值说明
{
"id": "String", // ID
"domain": "String", // 域
"certificatename": "String", // 暂时没有使用的属性
"get_icon_large": "String", // 头像(大)
"get_icon_middle": "String", // 头像(中)
"get_icon_small": "String", // 头像(小)
"get_icon_tiny": "String", // 头像(超小)
"get_icon_xlarge": "String", // 头像(超大)
"mobile_portraits_l": ["String"...] // 手机头像,220x220
"mobile_portraits_x": ["String"...] // 手机头像,640x640
"nick": "String", // 姓名
"followings": Int, // 关注数
"followers": Int, // 粉丝数
"location": "String", // 地址
"weight": Int, // 体重
"height": Int, // 身高
"realname": "String", // 真实姓名
"birthday": {"y": Int, "m": Int, "d": Int}, // 生日
"address": "String", // 地址
"gender": Int, // 性别 0: 女, 1: 男
"hobby":"String" // 爱好
"descroption": "String", // 运动宣言
"routes_count": Int, // 上传过的路线条数
"week_goal_type": "String", // 周目标类型
"week_goal_value": Int // 周目标的值
}
Method Name | update_profile |
访问方法 | POST |
API参数(Body) |
|
返回值说明
{
"status": "OK", // 处理结果,恒为ok
"data": {
"portrait_l": "String", // 220的头像URL
"portrait_x": "String", // 640的头像URL
},
"description": "String" //
'error_code': code,//1: u'昵称重复', 2: u'更新成功', 3: u'设置一个合理的步长吧', 4: u'文件类型不支持', 5: u"昵称只能是2~12位中文、字母、数字、下划线或减号!", 6: u'昵称不能含有敏感词!', 7:u'签名不能含有敏感词!',
8: u'信息审核中,不可编辑'
'vipicon_l': '',
'vipicon_m': '',
'vipicon_s': '',
'viplabel_desc': ''
}
Method Name | get_tracker_goal |
访问方法 | POST |
API参数(Body) | {} |
返回值说明
{
"status": "OK", // 执行状态
"descroption": "", // 状态描述,status不为OK的时候是错误信息描述
"data": {
"type":"steps", // 运动目标类型,可选值范围steps, meters, calories
"value": Int // 每日运动目标的值
},
}
Method Name | change_tracker_goal |
访问方法 | POST |
API参数(Body) |
|
返回值说明
{
"status": "OK", // 执行状态
"descroption": "", // 状态描述,status不为OK的时候是错误信息描述
}
Method Name | get_body_log |
访问方法 | POST |
API参数(Body) | {} |
返回值说明
{
"status": "OK",
"data": [
[ // 节约传输数据,使用数组存储,需要按位置获取数据。如果无此数据则为null
"2012-3-07", // 对应身体数据的日期
"number", // 体重,公斤
"number", // 身高,厘米
"number", // 体脂率,百分比,最大100
"number", // 目标体重
]
]
}
Method Name | post_body_data |
访问方法 | POST |
API参数(Body) |
|
返回值说明
{
"status": "OK",
}
Method Name | get_tracker_summary |
访问方法 | POST |
API参数(Body) |
|
返回值说明
{
"status": "OK",
"data": [ // 多条
{
"status": "null", // 运动状态 null不动 low轻微 proper适量 over过于
"calories": 0, // 消耗卡路里
"meters": 0, // 运动距离
"activity": 0, // 运动量 (卡路里/体重)
"steps": 0, // 步数
"minutes": 0 // 运动时常
}
],
"description": ""
}
Method Name | get_tracker_data |
访问方法 | POST |
API参数(Body) |
|
返回值说明
{
"status": true, //返回状态
"data": {
"meters": [1,2,3, ...], //每二十分钟的运动距离
"sports_duration": 120, //运动持续时间
"steps": [1,2,3, ...], //每二十分钟运动的步数
"calories": [1,2,3, ...], //每二十分钟消耗的卡路里数
"sports_complete": Int //运动完成度
}
}
Method Name | api_tracker_oneday |
访问方法 | POST |
API参数(Body) |
|
返回值说明
{
"status": true, //返回状态
"data": {
"meters": [1,2,3, ...], //每十分钟的运动距离
"sports_duration": 120, //运动持续时间
"steps": [1,2,3, ...], //每十分钟运动的步数
"calories": [1,2,3, ...], //每十分钟消耗的卡路里数
"sports_complete": Int //运动完成度
}
}
Method Name | get_sleep_data |
访问方法 | POST |
API参数(Body) |
|
返回值说明
{
"status":"OK", //返回状态
"data":{
"deep_minutes":60, //深睡时间
"sleep_complete":0.75, //睡眠完成度
"total_minutes": 80, //总睡眠时间
"light_minutes": 20, //浅睡时间
"detail": [-1, -1, ...] //每二十分钟睡眠详细情况
},
"description":""
}
Method Name | get_sleep_data_oneday |
访问方法 | POST |
API参数(Body) |
|
返回值说明
{
"status":"OK", //返回状态
"data":{
"deep_minutes":60, //深睡时间
"sleep_complete":0.75, //睡眠完成度
"total_minutes": 80, //总睡眠时间
"light_minutes": 20, //浅睡时间
"detail": [-1, -1, ...] //每200秒睡眠详细情况 -1表示没有数据 , 深睡 3.3*3 以下 , 浅睡 3.3-16.6, 唤醒 16.6 以上
},
"description":""
}
Method Name | get_sport_complete_rate |
访问方法 | POST | 获取追踪器睡眠信息
API参数(Body) |
|
返回值说明
{
"status":"OK", //返回结果
"data":{
"sports_complete":0, //运动目标完成率
"sleep_complete":50 //睡眠目标完成率
},
"description":""
}
Method Name | get_route_by_id |
访问方法 | POST |
API参数(Body) |
|
返回值说明
{
"status": "OK", // OK表示请求成功
"data": {
"total_time": Int, // 运动持续时间,单位分钟
"upload_time": String, // 上传的时间,比如 "2013-09-21 18:02:58"
"total_calories": Float, // 消耗卡路里
"start_time": String, // 运动开始时间,比如 "2013-09-23 17:40:14"
"sports_type": String, // 运动方式 比如 走路、跑步、骑行
"route_image": String, // 线路图片地址
"activity_result": Int, // 是否达成目标 0 未完成, 1 完成
"end_time": String, // 完成运动时间,比如"2013-09-24 17:41:07"
"total_length": Float, // 运动距离
"activity_type": String, // 运动类型 比如:普通模式、目标模式、挑战模式、计划模式
"goal_type": String, // 运动目标类型 比如:距离、时间、卡路里
"goal_value": Float // 运动目标值
},
"description": ""
}
区分错误和正确的请求通过Http的状态码就ok了,如果API请求返回200,一般意义上认为是请求成功了的,但是有的业务是异步的,所以最好通过status字段再判断一次。
错误名称 | 错误码 | HTTP状态 | 描述 |
invalid_request | 1001 | 400 | 在HTTP的Header里没有找到认证信息 |
invalid_token | 1002 | 401 | 当Token失效的时候返回这个错误 |
insufficient_scope | 1003 | 403 | 当请求的scope不在允许的范围内时返回此错误 |
invalid_request | 2001 | N/A | 参数缺失,参数错误,访问方法错误的时候返回此错误 |
unauthorized_client | 2003 | N/A | client_ID不是有效的client_ID |
access_denied | 2004 | N/A | 授权发生异常时返回此错误 |
unsupported_responseType | 2005 | N/A | 发起请求的Method不支持的时候返回此错误 |
开发者在注册APP的时候,需要提供一个回调地址,当用户上传数据的时候,API会即时调用这个地址,将消息通知给开发者的系统。请在5秒内处理完成回调通知的逻辑,开发者系统如果发生超时或者系统错误的时候,API不会重发此通知
协议 | HTTP |
方法 | POST |
参数 |
|
返回 | 不判断内容,只判断返回的状态码,200即认为成功,其余状态均认为失败 |