Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

BUG: WebAPI Swagger Document is invalid

The WebAPI swagger document hosted here: https://dev.fitbit.com/reference/web-api/explore/fitbit-web-api.swagger.json

 

This JSON document is invalid JSON and thus is not valid Swagger document. Unfortunately this means I cannot generate client code from the Swagger JSON. One of the core benefits of Swagger is that I can take your Swagger file and generate a large bulk of the client interaction code using automated tools. As the Fitbit WebAPI is very large, I do not want to have to do this by hand!

 

Examples:

 

http://online.swagger.io/validator/debug?url=https://dev.fitbit.com/reference/web-api/explore/fitbit...

 

Results: 

{"schemaValidationMessages":[{"level":"error","message":"Unable to read content.  It may be invalid JSON or YAML"}]}

 

JSON Validator:

 

https://jsonformatter.curiousconcept.com

 

INVALID JSON (RFC 4627)
Validator Output
Best Answer
0 Votes
10 REPLIES 10

Hi @BenDavies

 

Thank you for bringing this problem to our attention.  We will investigate what the problem may be in the documentation.   If I use the posted URL, https://dev.fitbit.com/build/reference/web-api/explore/fitbit-web-api.swagger.json, in your suggested JSON validator tool, I do get an error about invalid JSON.  However, if I enter the raw JSON into the JSON validator tool, it does work.

 

Would you be able to use the raw JSON for your needs?

 

Gordon

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes

The JSON itself is invalid. I was having the same issue when I downloaded the JSON to a file and validated it. It is not the delivery method (HTTP vs. File) that is at fault; the JSON structure is invalid (e.g. there is a comma in the wrong place).

 

Because the JSON is an invalid structure, automated tools cannot process the JSON and cannot generate client code automatically. I could correct the invalid JSON and use tool to auto-generate client code that way, but I found that correcting the JSON opened up further issues i.e. the Swagger document itself is invalid (e.g. duplicate operationIds, invalid types such as Date), so I would have to correct large amounts of the Swagger document.

 

I'll try to look into it further this weekend and provide a "fixed" Swagger file if I can, however I can see that your Swagger file is auto-generated by a tool for your service so anything I provide will still need to be implemented correctly server-side.

Best Answer
0 Votes

Hi @BenDavies,

 

I started looking through the Swagger JSON yesterday and noticed the duplicated Operational IDs and the invalid datatypes.  I'm going to make those changes.  I haven't found the misplaced comma yet, but I'll keep any eye out for it.

 

I'll work on making those changes to the Swagger docs soon and will let you know when they are complete.

 

Thanks again for bringing this to our attention.

Gordon

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes

Once I fixed the invalid JSON, the swagger validate tool produced this list of validation errors:

 

Bens-MBP:~ bendavies$ swagger validate fitbit-web-api.swagger.json
2018/09/26 20:28:02
The swagger spec at "fitbit-web-api.swagger.json" showed up some valid but possibly unwanted constructs.
2018/09/26 20:28:02 See warnings below:
2018/09/26 20:28:02 - WARNING: resource-path in path has a default value and is required as parameter
2018/09/26 20:28:02 - WARNING: detail-level in path has a default value and is required as parameter
2018/09/26 20:28:02 - WARNING: offset in query has a default value and is required as parameter

The swagger spec at "fitbit-web-api.swagger.json" is invalid against swagger specification 2.0.
See errors below:
- "paths./1/user/-/activities/heart/date/{date}/1d/{detail-level}/time/{start-time}/{end-time}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/heart/date/{date}/1d/{detail-level}/time/{start-time}/{end-time}.json.get.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/activities/heart/date/{date}/1d/{detail-level}/time/{start-time}/{end-time}.json.get.parameters.in in body should be one of [header]
- "paths./1/user/-/foods/log/water/date/{date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/foods/log/water/date/{date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/foods/log/water/date/{date}.json.get.parameters.in in body should be one of [header]
- "paths./1/user/-/foods/log/water.json.post.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/foods/log/water.json.post.parameters.in in body should be one of [header]
- paths./1/user/-/foods/log/water.json.post.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/{resource-path}/date/{base-date}/{end-date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/{resource-path}/date/{date}/1d/{detail-level}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/{resource-path}/date/{date}/1d/{detail-level}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/{resource-path}/date/{date}/1d/{detail-level}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/foods/log/{resource-path}/date/{date}/{period}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/foods/log/{resource-path}/date/{date}/{period}.json.get.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/foods/log/{resource-path}/date/{date}/{period}.json.get.parameters.in in body should be one of [header]
- "paths./1/user/-/sleep/{resource-path}/date/{date}/{period}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/sleep/{resource-path}/date/{date}/{period}.json.get.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/sleep/{resource-path}/date/{date}/{period}.json.get.parameters.in in body should be one of [header]
- "paths./1.2/user/-/sleep.json.post.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1.2/user/-/sleep.json.post.parameters.in in body should be one of [header]
- paths./1.2/user/-/sleep.json.post.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/body/log/weight/date/{date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/log/weight/date/{date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/body/log/weight/date/{date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/heart/date/{date}/{end-date}/{detail-level}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/heart/date/{date}/{end-date}/{detail-level}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/heart/date/{date}/{end-date}/{detail-level}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/body/log/weight/date/{date}/{period}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/log/weight/date/{date}/{period}.json.get.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/body/log/weight/date/{date}/{period}.json.get.parameters.in in body should be one of [header]
- "paths./1/user/-/activities/heart/date/{base-date}/{end-date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/heart/date/{base-date}/{end-date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/heart/date/{base-date}/{end-date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/heart/date/{date}/{end-date}/{detail-level}/time/{start-time}/{end-time}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/heart/date/{date}/{end-date}/{detail-level}/time/{start-time}/{end-time}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/heart/date/{date}/{end-date}/{detail-level}/time/{start-time}/{end-time}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/tracker/{resource-path}/date/{date}/{period}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/tracker/{resource-path}/date/{date}/{period}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/tracker/{resource-path}/date/{date}/{period}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/{resource-path}/date/{base-date}/{end-date}/{detail-level}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/{resource-path}/date/{base-date}/{end-date}/{detail-level}.json.get.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/activities/{resource-path}/date/{base-date}/{end-date}/{detail-level}.json.get.parameters.in in body should be one of [header]
- "paths./1/user/-/activities/list.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/list.json.get.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/activities/list.json.get.parameters.in in body should be one of [header]
- "paths./1/user/-/activities.json.post.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities.json.post.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/activities.json.post.parameters.in in body should be one of [header]
- "paths./1/user/-/body/log/fat/date/{date}/{period}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/log/fat/date/{date}/{period}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/body/log/fat/date/{date}/{period}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/foods/log.json.post.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/foods/log.json.post.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/foods/log.json.post.parameters.in in body should be one of [header]
- "paths./1/user/-/activities/{resource-path}/date/{date}/{period}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/{resource-path}/date/{date}/{period}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/{resource-path}/date/{date}/{period}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/foods/log/date/{date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/foods/log/date/{date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/foods/log/date/{date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/sleep/{resource-path}/date/{base-date}/{end-date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/sleep/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/sleep/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.in in body should be one of [header]
- "paths./1/user/-/body/log/fat/date/{date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/log/fat/date/{date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/body/log/fat/date/{date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/body/log/fat.json.post.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/log/fat.json.post.parameters.in in body should be one of [header]
- paths./1/user/-/body/log/fat.json.post.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/body/{resource-path}/date/{date}/{period}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/{resource-path}/date/{date}/{period}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/body/{resource-path}/date/{date}/{period}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/{resource-path}/date/{date}/{end-date}/{detail-level}/time/{start-time}/{end-time}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/{resource-path}/date/{date}/{end-date}/{detail-level}/time/{start-time}/{end-time}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/{resource-path}/date/{date}/{end-date}/{detail-level}/time/{start-time}/{end-time}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/profile.json.post.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/profile.json.post.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/profile.json.post.parameters.in in body should be one of [header]
- "paths./1/user/-/body/log/weight.json.post.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/log/weight.json.post.parameters.in in body should be one of [header]
- paths./1/user/-/body/log/weight.json.post.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/body/log/weight/date/{base-date}/{end-date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/log/weight/date/{base-date}/{end-date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/body/log/weight/date/{base-date}/{end-date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/foods/log/{resource-path}/date/{base-date}/{end-date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/foods/log/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/foods/log/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/body/log/fat/date/{base-date}/{end-date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/log/fat/date/{base-date}/{end-date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/body/log/fat/date/{base-date}/{end-date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/heart/date/{date}/1d/{detail-level}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/heart/date/{date}/1d/{detail-level}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/heart/date/{date}/1d/{detail-level}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/body/{resource-path}/date/{base-date}/{end-date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/body/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/body/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/heart/date/{date}/{period}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/heart/date/{date}/{period}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/heart/date/{date}/{period}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1.2/user/-/sleep/date/{date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1.2/user/-/sleep/date/{date}.json.get.parameters.in in body should be one of [header]
- paths./1.2/user/-/sleep/date/{date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/tracker/{resource-path}/date/{base-date}/{end-date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/tracker/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- paths./1/user/-/activities/tracker/{resource-path}/date/{base-date}/{end-date}.json.get.parameters.in in body should be one of [header]
- "paths./1.2/user/-/sleep/list.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1.2/user/-/sleep/list.json.get.parameters.in in body should be one of [header]
- paths./1.2/user/-/sleep/list.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1.2/user/-/sleep/date/{base-date}/{end-date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1.2/user/-/sleep/date/{base-date}/{end-date}.json.get.parameters.in in body should be one of [header]
- paths./1.2/user/-/sleep/date/{base-date}/{end-date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/date/{date}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/date/{date}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/date/{date}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "paths./1/user/-/activities/{resource-path}/date/{date}/1d/{detail-level}/time/{start-time}/{end-time}.json.get.parameters" must validate one and only one schema (oneOf). Found none valid
- paths./1/user/-/activities/{resource-path}/date/{date}/1d/{detail-level}/time/{start-time}/{end-time}.json.get.parameters.in in body should be one of [header]
- paths./1/user/-/activities/{resource-path}/date/{date}/1d/{detail-level}/time/{start-time}/{end-time}.json.get.parameters.type in body should be one of [string number boolean integer array]
- "water" is defined 5 times
- "alarms" is defined 4 times
- "food" is defined 20 times
- "activity" is defined 14 times
- "weight" is defined 13 times
- "profile" is defined 2 times
- "intraday" is defined 17 times
- "subscription" is defined 3 times
- "sleep" is defined 7 times
- "friends" is defined 4 times
- path /1/user/-/activities/tracker/{resource-path}/date/{base-date}/{end-date}.json overlaps with /1/user/-/activities/tracker/{resource-path}/date/{date}/{period}.json
- path /1/user/-/activities/heart/date/{base-date}/{end-date}.json overlaps with /1/user/-/activities/heart/date/{date}/{period}.json
- path /1/user/-/body/log/fat/date/{base-date}/{end-date}.json overlaps with /1/user/-/body/log/fat/date/{date}/{period}.json
- path /1/user/-/activities/{resource-path}/date/{base-date}/{end-date}.json overlaps with /1/user/-/activities/{resource-path}/date/{date}/{period}.json
- path /1/user/-/body/log/weight/date/{base-date}/{end-date}.json overlaps with /1/user/-/body/log/weight/date/{date}/{period}.json
- path /1/user/-/body/{resource-path}/date/{base-date}/{end-date}.json overlaps with /1/user/-/body/{resource-path}/date/{date}/{period}.json
- path /1/user/-/sleep/{resource-path}/date/{base-date}/{end-date}.json overlaps with /1/user/-/sleep/{resource-path}/date/{date}/{period}.json
- path /1/user/-/foods/log/{resource-path}/date/{base-date}/{end-date}.json overlaps with /1/user/-/foods/log/{resource-path}/date/{date}/{period}.json
- default value for offset in query does not validate its schema
- offset in query must be of type integer: "string"
Best Answer
0 Votes

Hi @BenDavies,

 

Would you send me a link to the validation tool you're using?   We're working on publishing some changes that I want to confirm will address most of these issues.

 

Gordon

 

 

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes

Hass there been any progress on this issue, or should I find an alternative solution?

Best Answer
0 Votes

We should have fixed all issues that were allowed by the specification and we validated it using the Swagger Editor (https://swagger.io/tools/swagger-editor/).  Please let us know if you have any further problems.

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes

Hi Gordon,

 

Revisiting this issue I found that there still exists issues with the JSON structure (invalid) and Swagger document itself:

 

https://jsonformatter.curiousconcept.com

Paste the following URL into the text area and press "Process"

https://dev.fitbit.com/reference/web-api/explore/fitbit-web-api.swagger.json

 

 

Error:Invalid encoding, expecting UTF-8, UTF-16 or UTF-32.[Code 29, Structure 0]

Error:Invalid comma, expecting }.[Code 141, Structure 572]

Error:Expecting string, not }.[Code 8, Structure 573]

 

It doesn't look like I can generate client code from the Swagger document still.

Best Answer
0 Votes

Hi @BenDavies ... The correct URL is https://dev.fitbit.com/build/reference/web-api/explore/fitbit-web-api-swagger.json.   This URL only returns the "Invalid encoding" error message.  I'll investigate it.

 

 

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes

Hi @BenDavies,

 

When I process the JSON URL, I do receive the "Invalid encoding" error message. 

 

Screen Shot 2019-03-12 at 3.21.32 PM.png

 

However, if I cut/paste the actual json into the field, the json validator states the json is valid.  Do you see the same?

 

jsonvalidator.png

Gordon Crenshaw
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google
Best Answer
0 Votes