This is an attempt to document the API used by OUYA gaming consoles to
speak with devs.ouya.tv.
The following HTTP headers are sent with nearly every HTTP request from the OUYA console to the servers.
Accept-Encodinggzip
The OUYA understands gzip compression
Accept-Languageen-US,en
User-AgentOUYA 0 1.00 1.2.1427_r1
X-OUYA-AuthToken96bfeaae-212d-447b-b4bf-caa5e86c0502
Authentication token one got from logging in.
Only sent when logged in.
X-OUYA-Console-Id015d4b33bc64141b
Serial number you see when running $ adb devices
X-OUYA-Console-Wifi-MAC-AddressB8:5A:F7:82:3C:C8
X-OUYA-Deviceouya_1_1
Probably hardware revision
X-OUYA-Firmware-Version1.2.1427_r1
X-OUYA-VersionCode16
X-Token96bfeaae-212d-447b-b4bf-caa5e86c0502
Only sent when logged in.
Same as X-OUYA-AuthToken.
FIXME: Why two token headers?
FIXME: Why auth_token GET parameter when there are headers?
Cookie__cfduid=da019d762142461c19f162c0ee443f9c71434577887
Comes from the cloudflare error page. Can be ignored.
Cookie2$Version=1
??? FIXME
Not on the cloudflare error page.
POST https://ott9.wpstn.com/live/Store credit card data.
Called after fetching a one time token from POST https://devs.ouya.tv/api/v1/credit_card.
https
POST
ott9.wpstn.com
/live/
Content-Typeapplication/x-www-form-urlencoded
User-AgentOUYA 0 1.00 1.2.1427_r1
Action:Add
OTT:Random one-time token from credit card POST request.
AcctName:Credit card account holder name
AcctNumber:4111111111111111
Credit card number
ExpDate:012017
Month & year
CVN:777
Secret code
Email:E-mail address
ZipCode:Postal code
303 See Other
Redirects to wpsuccess URL on devs.ouya.tv with the OTT parameter:
https://devs.ouya.tv/wpsuccess?OTT=C187D8AE8970...
The redirect location header seems to be ignored; it does not get called. Instead, PUT https://devs.ouya.tv/api/v1/credit_card is fetched.
GET http://status.ouya.tv/api/v1/statusCheck if the internet connection is working by fetching an empty file.
http
GET
status.ouya.tv
/api/v1/status
None of the standard headers.
User-AgentOuya-Connection-Test
204 No Content
Empty body.
GET https://devs.ouya.tv/api/firmware_buildsList the latest available firmware version.
During the OUYA setup (Parameter oobe=true is set)
During bootup
Every 3 minutes unless an "Expires" header is set
https
GET
devs.ouya.tv
/api/firmware_builds
Standard headers
Token parameters not required.
auth_tokenMay be empty.
Does not seem to have any influence on the response.
oobetrue
Optional.
Is set once during the OUYA setup (Out Of Box Experience).
200 OK
application/json; charset=utf-8
{
"result": [
{
"incremental": false,
"filename": "OUYA-1.2.1427-r1.zip",
"timestamp": "1418407476",
"md5sum": "3a95be82b4c33bd68353dc314346f39f",
"channel": "stable",
"url": "http://cds.t2z5c2q6.hwcdn.net/ota/RC-OUYA-1.2.1427-r1_ota.zip",
"requiredUpto": "1.2.995",
"changes": "https://devs.ouya.tv/api/changelog/3a95be82b4c33bd68353dc314346f39f.txt",
"changesLocalized": {
"de": " <!doctype html>\r\n<html>\r\n...",
"it": "<!doctype html>\r\n<html>\r\n..",
"fr": "<!doctype html>\r\n<html>\r\n..",
"es": "<!doctype html>\r\n<html>\r\n..",
"en": "<!doctype html>\r\n<html>\r\n.."
}
}
]
}POST https://devs.ouya.tv/api/razer/gamerRegister a new account on a Razer Forge TV.
Similar to POST https://devs.ouya.tv/api/v1/gamers, but uses different POST data.
emailE-mail address
passwordPassword
email_opt_outInverted checkbox "Opt-in for emails from Razer".
Value: true or false
See POST https://devs.ouya.tv/api/v1/gamers.
Validation error for e-mail is in the email property.
PUT https://devs.ouya.tv/api/razer/gamerUpdate the gamer profile (store the nickname during login).
FIXME: Undocumented.
POST https://devs.ouya.tv/api/razer/sessionLogin to the Razer Cortex store on the Razer Forge TV.
Similar to the OUYA login POST https://devs.ouya.tv/api/v1/sessions, but with e-mail instead of username.
https
POST
devs.ouya.tv
/api/razer/session
User-AgentDalvik/2.1.0 (Linux; U; Android 6.0.1; Forge Build/M-MMB29M-rzs-us-sf-bld2-19HP-08.02.AM)
Accept-Languagede
X-OUYA-Devicepearlyn
X-OUYA-Firmware-Version:(empty)
X-OUYA-Console-IdBuild serial number
171256710321511
X-OUYA-Console-Wifi-MAC-AddressC4:8E:8F:82:29:B1
X-OUYA-VersionCode10202320
Content-Typeapplication/x-www-form-urlencoded
emailUser e-mail address
passwordUser password
200 OK
application/json; charset=utf-8
After the initial login, GET https://devs.ouya.tv/api/v1/gamers/me is fetched.
If its reponse does not contain nickname, the nickname input screen is shown.
The nickname is then stored via PUT https://devs.ouya.tv/api/razer/gamer.
The CortexFramework code also parses properties
razerToken, nickname and avatar
but they do not seem to be used.
{
"token": "00702342-0000-1111-2222-c3e1500cafe1"
}GET https://devs.ouya.tv/api/v1/apps/xxxFetch the details for an app/game.
When the user enters the detail page in the discover store.
Sometimes the OUYA refreshes details of all installed apps while running.
Related to api/v1/details, which is used for already installed apps.
https
GET
devs.ouya.tv
/api/v1/apps/xxx
xxxPackage name of an app
Also UUID of a package release.
Example: /api/v1/apps/com.toa.tetrisFusionOuya
Standard headers
console_idSame as X-OUYA-Console-Id
auth_tokenSame as X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
{
"app": {
"videoUrl": null,
"publishedAt": "2014-12-05T20:30:48Z",
"firstPublishedAt": "2014-08-25T03:35:11Z",
"latestVersion": "0fba3bba-83e0-4e3e-9f29-409258429757",
"promotedProduct": {
"originalPrice": 4.49,
"localPrice": 4.49,
"percentOff": 0,
"description": "Play head-to-head against another opponent. If you don't have a second controller connected, you can play against a CPU-controlled opponent.",
"currency": "EUR",
"name": "2P VS Battle Mode",
"identifier": "TBOE_Mode2P_1-50"
},
"genres": [
"Puzzle/Trivia",
"Arcade/Pinball",
"Retro"
],
"premium": false,
"description": "Tetris® Battle: Fusion is now available on OUYA! Based on Tetris Battle, the hugely popular multiplayer game on Facebook that has been downloaded over 60 million times, Tetris Battle: Fusion introduces an all-new interactive adventure where you can battle your way through a series of challenging opponents and goals to become a Tetris Master! Collect special Amulets that can be used to give you an added boost as you progress your way to victory. Over 50 Amulets are ready to collect, and more will be added periodically. With the help of Amulets, don't change the way you play ... change the way you WIN! The game also features a 1v1 local co-op mode that enables friends in the same room to go head-to-head using previously earned Amulets.\r\n\r\nPLEASE NOTE: This app contains in-app purchasing, which allows you to buy items within the app using actual money.",
"developer": "Tetris Online, Inc.",
"gamerNumbers": [
1
],
"ratingCount": 861,
"ratingAverage": 3.73,
"apkFileSize": 41125055,
"founder": false,
"mainImageFullUrl": "https://devs-ouya-tv-prod.s3.amazonaws.com/apps/a137f31c-ad28-47e6-ae43-0a346ebe249a/com.toa.tetrisFusionOuya/0fba3bba-83e0-4e3e-9f29-409258429757/ouya_icon.png",
"website": "www.tetrisonline.com",
"supportPhone": null,
"supportEmailAddress": "support@tetrisonline.com",
"title": "Tetris Battle Fusion",
"uuid": "0fba3bba-83e0-4e3e-9f29-409258429757",
"versionNumber": "2.0.1r",
"likeCount": 0,
"overview": "Released in December 2014 by Tetris Online, Inc..",
"filepickerScreenshots": [
"https://www.filepicker.io/api/file/fio2PmJQQla1fZdVEZxl",
"https://www.filepicker.io/api/file/VESfV97VTSn4uRp5lY9A",
"https://www.filepicker.io/api/file/To75Tn2Tw6J7nvPG4nBk",
"https://www.filepicker.io/api/file/bjzlwTjvQe6HA4awlHTw",
"https://www.filepicker.io/api/file/qcQEibHxT9Wa1PCoMpX2",
"https://www.filepicker.io/api/file/kQKVJ2xyRnCnmysUjZkD",
"https://www.filepicker.io/api/file/8zJEBwIBTmoFNiJyLKoY",
"https://www.filepicker.io/api/file/zTnyJklUSYOlpJ1E04fH"
],
"contentRating": "Everyone",
"md5sum": "ad1f58f365859e5bc0db8c237b4c4514",
"publicSize": 258150,
"nativeSize": 5607144
}
}GET https://devs.ouya.tv/api/v1/apps/xxx/downloadFetch the download link for a specific version of an app.
When the user clicks "download"
https
GET
devs.ouya.tv
/api/v1/apps/xxx/download
xxxlatestVersion string from the apps details page
Example: /api/v1/apps/0fba3bba-83e0-4e3e-9f29-409258429757/download
Standard headers
auth_tokenSame as X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
{
"app": {
"downloadLink": "http://cds.t2z5c2q6.hwcdn.net/apps/a137f31c-ad28-47e6-ae43-0a346ebe249a/com.toa.tetrisFusionOuya/0fba3bba-83e0-4e3e-9f29-409258429757/Gx9cZz0KTRCNstv78Mq5_ToaFusionOuya-2.0.1r.apk",
"contentRating": "Everyone",
"version": "0fba3bba-83e0-4e3e-9f29-409258429757",
"fileSize": 41125055
}
}GET https://devs.ouya.tv/api/v1/console_configurationSets Android system properties. Allows to enable debug or kiosk mode remotely.
This file is downloaded every hour.
https
GET
devs.ouya.tv
/api/v1/console_configuration
Standard headers
auth_tokenMay be empty.
Does not seem to have any influence on the response.
200 OK
{"BTC_LAUNCHER_PACKAGES":"tv.ouya.xbmc,tunein.player,tv.twitch.android.viewer,com.plexapp.android,tv.ouya.bbciplayer,tv.ouya.hulu,tv.ouya.minecrafttv,tv.ouya.ouyabrowser,tv.ouya.pandora,tv.ouya.visiomgo,tv.ouya.youtube,tv.ouya.tubitv"}POST https://devs.ouya.tv/api/v1/crash_reportWhen the OUYA launcher crashed, it saves a crash log. When the OUYA reboots, it tries to send the crash log data to this URL.
FIXME
POST https://devs.ouya.tv/api/v1/credit_cardPrepare the credit card registration process and fetch a one-time token for the wpstn.com (world pay) credit card processor.
https
POST
devs.ouya.tv
/api/v1/credit_card
Standard headers
Content-Typeapplication/x-www-form-urlencoded
auth_tokenSame data as in standard header X-OUYA-AuthToken
zipcodePostal code entered on the credit card form.
auth_token:Same data as in standard header X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
Example:
{
"one_time_token": "C187D8AE8970435C9638C58C8351E2DEF975680B737A4B55A3D314BF0C477F2A",
"redirect_url": "https://ott9.wpstn.com/live/"
}The one_time_token is used in the following POST request to
the URL determined in redirect_url.
PUT https://devs.ouya.tv/api/v1/credit_cardStore the result of the credit card storage request.
Called after POST https://ott9.wpstn.com/live/.
https
PUT
devs.ouya.tv
/api/v1/credit_card
Standard headers
Content-Typeapplication/x-www-form-urlencoded
auth_tokenSame data as in standard header X-OUYA-AuthToken
body:Complete response including headers
zipcode:Postal code
auth_tokenSame data as in standard header X-OUYA-AuthToken
Example body parameter:
HTTP/1.1 303 See Otherlocation: https://devs.ouya.tv/wpsuccess?OTT=C187D8AE8970435C9638C58C8351E2DEF975680B737A4B55A3D314BF0C477F2A
Content-Length: 9
Via: 1.1 localhost (Apache-HttpClient/UNAVAILABLE (cache))
Date: Wed, 17 Jun 2015 21:51:23 GMT
See Other200 OK
application/json; charset=utf-8
Example:
{
"country": null,
"success": true
}GET https://devs.ouya.tv/api/v1/detailsDetail page for an app bundle.
Also used as detail page for installed games when opened through the "Play" section.
If there are no details available, the error code 2005 needs to be returned. Otherwise opening the details for an installed but unlisted game will fail on the OUYA.
https
GET
devs.ouya.tv
/api/v1/details
Standard headers
auth_tokenSame as X-OUYA-AuthToken
pageUUID of the bundle page to show
Example: be239ca4-10fd-42dd-89cd-1806e80b1362
appPackage name of an app.
Example: org.blockinger.game
developerUUID of the developer
Example: 5b015434-8a78-4274-aa5d-0cb2e330e50e
community_contentUUID of a community content module
Only one of app, developer or page is provided.
200 OK
application/json; charset=utf-8
ccUrlShow community content for this game
developer.urlNot set for everyone. If set, a "Developer page" button is shown on the game details screen.
Example when set: ouya://launcher/details?developer=92345f8d-ddbd-43f2-afcf-2628b1234713
metaDataArray of strings that determine which data are shown in the top row.
Allowed values:
key:rating.average: Shows the rating stars from rating.average
key:apk.fileSize: Shows the apk.fileSize as readable size with unit.
key:twitterHandle: Shows the twitterHandle property, automatically prefixes an "@".
Any string value beginning with "key:" fetches the key path from JSON, e.g. developer.name.
Any string value that does not begin with key: is shown as-is.
promotedProductWhen set, the "Buy" button is shown on the details screen.
{
"type": "Game",
"title": "BombSquad",
"description": "8 Player Party Game Madness!\nBlow up your friends in mini-games ranging from capture-the-flag to hockey.\nFeaturing gratuitous explosions, advanced ragdoll face-plant physics, pirates, ninjas, barbarians, insane chefs, and more.\nSupports PS3 controllers, XBox 360 controllers, most USB/Bluetooth gamepads, and even iOS and Android devices as controllers via the free 'BombSquad Remote' app.\nBombs Away!\n\nVersion history:\n1.4.123 - Account unlinking & bug fixes\n1.4.116 - Bug fixes\n1.4.113 - Bug fixes\n1.4.105 - Shields now lose health over time and spinning too long causes you to pass out\n1.4.99 - Better language support in net-games\n1.4.98 - New netplay features such as kick votes\n1.4.94 - More netplay performance improvements\n1.4.93 - Netplay performance improvements\n1.4.88 - Public internet parties\n1.4.69 - Bug fixes and polishing\n1.4.66 - Easter edition!\n1.4.62 - new characters and bug fixes\n1.4.47 - bug fixes\n1.4.38 - bug fixes\n1.4.32 - more icons, bug fixes, and UI improvements\n1.4.17 - new global player profiles and custom icons\n1.4.16 - added continues and polishing\n1.4.14 - bug fixes\n1.4.11 - New tournament and league functionality\n1.4.9 - Santa and Frosty are back for the holidays! Also a new map and new tournament.\n1.4.8 - added Bernard the Bear and new tournament types",
"mediaTiles": [
{
"type": "video",
"url": "http://vimeo.com/81224217"
},
{
"type": "image",
"urls": {
"thumbnail": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/thumbnail20170911-3-4r3lgn.png",
"full": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/ouya-image20170911-3-1ja1uwj"
},
"fp_url": "https://www.filepicker.io/api/file/75dSamHkQiuKpg7o3DXF"
},
{
"type": "image",
"urls": {
"thumbnail": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/thumbnail20170911-3-14kztkg.png",
"full": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/ouya-image20170911-3-jg5ypv"
},
"fp_url": "https://www.filepicker.io/api/file/g0sFFV1Tc2gidAYkaQPU"
},
{
"type": "image",
"urls": {
"thumbnail": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/thumbnail20170911-3-csiwp7.png",
"full": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/ouya-image20170911-3-s0jlzk"
},
"fp_url": "https://www.filepicker.io/api/file/zswgv6FOQcqZWt7oyV00"
},
{
"type": "image",
"urls": {
"thumbnail": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/thumbnail20170911-3-1615w0d.png",
"full": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/ouya-image20170911-3-jcvr8g"
},
"fp_url": "https://www.filepicker.io/api/file/51a1JNYKRaeQAAVeNedw"
},
{
"type": "image",
"urls": {
"thumbnail": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/thumbnail20170911-3-1ryqwq9.png",
"full": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/ouya-image20170911-3-pom01u"
},
"fp_url": "https://www.filepicker.io/api/file/0dnBNiw2Sser5X8kpezG"
}
],
"heroImage": {
"url": "https://s3.amazonaws.com/ouya-screenshots/b9fea1c7-c0d9-445f-b424-471c1d9446d8/ouya-image20161126-3-1x3bs88"
},
"mobileAppIcon": "https://s3.amazonaws.com/ouya-screenshots/3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd/ouya-image20170911-3-v6tjz1",
"premium": false,
"promotedProduct": {
"identifier": "FullGameBombSquad",
"name": "BombSquad Pro",
"localPrice": 4.99,
"originalPrice": 4.99,
"percentOff": 0,
"currency": "USD",
"description": "Doubles tickets earned in-game, gives a power-ranking bonus, and more..",
"type": "entitlement"
},
"inAppPurchases": true,
"rating": {
"count": 3706,
"average": 4.36
},
"developer": {
"name": "Eric Froemling",
"founder": false
},
"suggestedAge": "9+",
"apk": {
"fileSize": 58535084,
"nativeSize": 9511196,
"publicSize": 571122,
"md5sum": "54d5d03855add2b824040e39a9380f48",
"filename": "1zbYKRSS1elKIYI9eseH_BombSquad-ouya-release.apk",
"errors": "",
"package": "net.froemling.bombsquad",
"versionCode": 14304,
"state": "complete"
},
"firstPublishedAt": 1367356207,
"version": {
"number": "1.4.123",
"publishedAt": 1506379060,
"uuid": "3ae8fc67-f7f5-4f97-a48c-8ea2d31460fd"
},
"metaData": [
"key:rating.average",
"key:developer.name",
"key:suggestedAge",
"56.12 MiB"
],
"tileImage": "https://d3e4aumcqn8cw3.cloudfront.net/api/file/0xrPYAcTUCYpjTUPbqSV",
"ccUrl": null,
"gamerNumbers": [
1,
2,
3,
4
],
"genres": [
"Fight!",
"Multiplayer",
"Sports"
]
}{
"bundle": {
"apps": [
{
"gamerNumbers": [
1
],
"genres": [
"Adventure",
"Kids List",
"Puzzle/Trivia"
],
"url": "ouya://launcher/details?app=com.GoldenTricycle.Clark",
"latestVersion": {
"apk": {
"md5sum": "a674b6c205502d9b4a907ade90307ba0"
},
"versionNumber": "1.24",
"uuid": "7230ac05-d24c-4347-a990-7ac283c17063"
},
"inAppPurchases": true,
"promotedProduct": {
"type": "entitlement",
"developerName": "GoldenTricycle / Hahn Film AG",
"identifier": "clark_full_license_test",
"name": "Clarc Full Version",
"localPrice": 3.99,
"originalPrice": 3.99,
"percentOff": 0,
"currency": "USD",
"description": "This item unlocks the full game with 25 levels, more than 100 puzzles and more than 10 hours of gameplay."
},
"premium": false,
"type": "app",
"package": "com.GoldenTricycle.Clark",
"updated_at": 1384854785,
"updatedAt": "2013-11-19T09:53:05Z",
"title": "CLARC",
"image": "https://www.filepicker.io/api/file/VzCsgc3BTx2RiGpTr4Uw",
"contentRating": "Everyone",
"rating": {
"count": 716,
"average": 4.25
}
},
{
"gamerNumbers": [
1
],
[...]
}
],
"currency": "EUR",
"price": 6.99,
"contentRating": "9+",
"purchased": false,
"games": [
"com.GoldenTricycle.Clark",
"com.Tripleslash.MagneticByNature",
"com.Thinice.TwinRobots",
"com.scaryrobot.badbadbots"
],
"purchaseUrl": "ouya://launcher/purchase?developer=ec1a9ccd-373f-4047-bd07-36466ab7e25d&product=ROBOBUNDLE"
},
"buttons": [],
"apps": [],
"muted": true,
"metaData": [
"Golden Tricycle",
"Team Tripleslash",
"Scary Robot",
"Thinice"
],
"mediaTiles": [
{
"url": "https://vimeo.com/84689664",
"type": "video"
},
{
"urls": {
"thumbnail": "https://s3.amazonaws.com/ouya-screenshots/be239ca4-10fd-42dd-89cd-1806e80b1362/thumbnails/thumbnail20150202-3-6hikjv.jpeg",
"full": "https://s3.amazonaws.com/ouya-screenshots/be239ca4-10fd-42dd-89cd-1806e80b1362/oivu9a_RackMultipart20150202-15-1sg3fmt"
},
"type": "image"
}
],
"description": "CLARC, Magnetic By Nature\r\n\r\nAbout CLARC\r\n",
"title": "ROBO GAME BUNDLE!"
}A full version of that response data is available in git at
api/devs.ouya.tv/api-v1-details.response-bundle-full.json
{
"error": {
"message": "Unknown application",
"code": 2005
}
}GET https://devs.ouya.tv/api/v1/developers/xxx/current_gamerFetch gamer information from within a game.
At the startup of Knightmare Tower and Towerfall (when bought)
https
GET
devs.ouya.tv
/api/v1/developers/xxx/current_gamer
xxxDeveloper UUID
Standard headers
auth_tokenSame data as in standard header X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
Same data as in gamers/me.
{
"gamer": {
"username": "cwdev3",
"uuid": "0a6f5fc0-bf9b-42b2-a4d0-69f2c8e4d5da"
}
}GET https://devs.ouya.tv/api/v1/developers/xxx/products/Use in-game when purchasing a feature, sometimes already at game startup.
Some games rely on this to check if the game is purchasable at all.
If the product list does not contain the product identifier they
expect, buying is not possible. (Example: com.sega.sonic4epi)
When the user starts a game and pressed "Sync" in the store (at "Babylonian Twins")
https
GET
devs.ouya.tv
/api/v1/developers/xxx/products/
xxxDeveloper UUID
Example: /api/v1/developers/c4e46efe-05fd-4be9-9d7e-1f7607eabd49/products/
Standard headers
auth_tokenSame as X-OUYA-AuthToken
onlyProduct key (same as Identifier in promotedProduct of app details)
Example: &only=unlock_pro
200 OK
application/json; charset=utf-8
{
"developerName": "AppBarbecue Inc.",
"currency": "USD",
"products": [
{
"type": "entitlement",
"description": "Instantly unlock full game with all Pro Levels. The challenging puzzles will take days to solve. Explore Assyria, Hanging Gardens & more. ",
"percentOff": 0,
"originalPrice": 4.99,
"localPrice": 4.99,
"priceInCents": 499,
"name": "Unlock All Pro Levels",
"identifier": "unlock_pro"
}
]
}GET https://devs.ouya.tv/api/v1/discoverFetch the categories and games in the OUYA store.
https
GET
devs.ouya.tv
/api/v1/discover
Standard headers
auth_tokenSame as X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
HTTP redirects (e.g. 302) are supported.
JSON object with two properties: rows and tiles.
rows contains the layout of the "discover" store main view, while
tiles contains the list of games/apps available in the store with
details.
rowsArray with objects that have with several properties:
showPricetrue or false
rankedtrue or false
If the games are sorted by the internal ranking factor, or in order
of appearance in tiles.
tilesarray
List of integer game IDs ([0, 1, 2])
titlestring
Title of the category
tilesArray of objects that each describe a single application.
The position in the tiles array is the ID used by rows/tiles.
bundleOnly there when it's not a single game but a bundle of games that can be bought.
Object with the following properties:
appsarray
Array of package strings
currencyEUR
pricefloat
contentRatingSee contentRating description below.
purchaseUrlstring
URL where to initiate buying the bundle
ouya://launcher/purchase?developer=ec1a9ccd-373f-4047-bd07-36466ab7e25d&product=ROBOBUNDLE
contentRatingFor which audiences the game is meant
Seen values:
Everyone
9+
12+
17+
gamerNumbersarray
List of integers describing how many players can play the game
genresarray
Array of strings with genre titles.
["Fight!", "Multiplayer", "Platformer"]
Known genres:
Adventure
App
Arcade/Pinball
Card/Casino
Dual Stick
Entertainment
Fight!
FPS/Shooter
Kids List
Meditative
Multiplayer
Music
Platformer
Puzzle/Trivia
Racing
Retro
Role-Playing
Short on Time?
Sim/Strategy
Sports
Utility
Video
imageURL to an image displayed in store view.
Size should be 732x412.
.jpg and .png files work.
inAppPurchasestrue or false
If you can/have to pay within the game
latestVersionobject
apkmd5sumMD5 hash of the apk file. Used for verification after download.
versionNumberstring with current version, e.g. 1.11
uuidUUID of the release.
packagestring
java package name prefix, e.g. evil.corptron.DuckGame
premiumtrue or false
When true, the game has no demo version and has to be bought before
it can be downloaded.
promotedProductobject
Bundles do not have this property set.
The "buy" button buys this product.
currencystring
EUR
descriptionstring
developerNamestring
Name of the developer or company who made the game
identifierstring
???
localPricefloat
Current price
namestring
Title of the game
originalPricefloat
Price it did once cost
percentOffinteger
Percent difference between originalPrice and localPrice
typestring
entitlement is the only type seen within promotedProduct.
ratingObject with two properties: count and average.
countinteger
Number of votes for this game
averagefloat
Average rating (1-5)
titleName of the app/game
typeapp or discover or details_page
Bundles always have details_page.
updated_atinteger
Unix timestamp of last update date
updatedAtstring
ISO 8601-date, e.g. 2014-12-04T22:16:30Z
urlstring
URL for the game details page
ouya://launcher/details?app=evil.corptron.DuckGame
ouya://launcher/details?page=be239ca4-10fd-42dd-89cd-1806e80b1362
titlestring
Always DISCOVER.
{
"rows": [
{
"showPrice": true,
"ranked": true,
"tiles": [ 0, 1, 2, 3 ],
"title": "TRENDING NOW"
},
{
"showPrice": true,
"ranked": false,
"tiles": [ 94, 95, 96 ],
"title": "NEW RELEASES"
},
{
"showPrice": true,
"ranked": false,
"tiles": [ 94, 62 ],
"title": "OUR FOUNDERS"
}
],
"tiles": [
{
"gamerNumbers": [
1
],
"genres": [
"Fight!",
"Multiplayer",
"Platformer",
"Retro",
"Sports"
],
"url": "ouya://launcher/details?app=evil.corptron.DuckGame",
"latestVersion": {
"apk": {
"md5sum": "ac4e1ddefe383f8314fe5914edcf8705"
},
"versionNumber": "1.11",
"uuid": "7cbd8b8b-e9df-4c30-9e0f-5a777c5e4eb4"
},
"inAppPurchases": true,
"promotedProduct": {
"type": "entitlement",
"developerName": "Landon Podbielski",
"identifier": "DUCKGAME",
"name": "Duck Game",
"localPrice": 8.99,
"originalPrice": 8.99,
"percentOff": 0,
"currency": "EUR",
"description": "You are buying Duck Game you lucky person. "
},
"premium": false,
"type": "app",
"package": "evil.corptron.DuckGame",
"updated_at": 1417731390,
"updatedAt": "2014-12-04T22:16:30Z",
"title": "DUCK GAME",
"image": "https://www.filepicker.io/api/file/iESEZs3fSUafrXuNpagi",
"contentRating": "Everyone",
"rating": {
"count": 1155,
"average": 4.31
}
},
{
"gamerNumbers": [
1,
2
],
"genres": [
"Adventure",
"Arcade/Pinball",
"Dual Stick",
"FPS/Shooter",
"Fight!",
"Kids List",
"Multiplayer",
"Racing",
"Short on Time?"
],
"url": "ouya://launcher/details?app=com.media.playcast.OUYA.BAA",
"latestVersion": {
"apk": {
"md5sum": "39931a3179e6c984771f0f1f49b59e87"
},
"versionNumber": "1.6.35707.8",
"uuid": "abe8eeb3-4fd9-45bb-ba6b-50eb9d60478b"
},
"inAppPurchases": true,
"promotedProduct": null,
"premium": false,
"type": "app",
"package": "com.media.playcast.OUYA.BAA",
"updated_at": 1433234808,
"updatedAt": "2015-06-02T08:46:48Z",
"title": "GameFly Packful Of Fun",
"image": "https://www.filepicker.io/api/file/05y2T8cKTY6cUfX7RYFR",
"contentRating": "17+",
"rating": {
"count": 394,
"average": 4.09
}
},
{
"url": "ouya://launcher/details?page=08db29bd-c2f0-41d7-9e5d-d842f1bf34d2",
"image": "https://s3.amazonaws.com/ouya-screenshots/08db29bd-c2f0-41d7-9e5d-d842f1bf34d2/thumbnails/thumbnail20150512-3-1gigg1x.jpeg",
"uuid": "08db29bd-c2f0-41d7-9e5d-d842f1bf34d2",
"title": "OUYA PRESENTS: JOE DANGER",
"type": "details_page"
},
{
"url": "ouya://launcher/details?page=3bdbe05a-201f-40c0-bb58-5aa4d6ea79dc",
"image": "https://s3.amazonaws.com/ouya-screenshots/3bdbe05a-201f-40c0-bb58-5aa4d6ea79dc/thumbnails/thumbnail20150220-3-1p5bhh7.jpeg",
"uuid": "3bdbe05a-201f-40c0-bb58-5aa4d6ea79dc",
"title": "OUYA PRESENTS: THE JACKBOX PARTY PACK",
"type": "details_page"
},
{
"url": "ouya://launcher/discover/Adventure",
"image": "",
"title": "Adventure",
"type": "discover"
},
],
"title": "DISCOVER"
}The API git repository contains a full copy of the "discover" response
at api/devs.ouya.tv/api-v1-discover.response-full.json.
GET https://devs.ouya.tv/api/v1/discover/homeProbably the list of games to be featured on the main menu.
More than the 4 displayed because it could be that a player already bought some of them - they would not be shown then.
https
GET
devs.ouya.tv
/api/v1/discover/home
Standard headers
auth_tokenSame as X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
Same as GET https://devs.ouya.tv/api/v1/discover with some limitations:
Only one entry in the rows array
Title of this row is FEATURED, price is shown, not ranked.
title attribute value is home.
GET https://devs.ouya.tv/api/v1/discover/tutorialsLoaded then the user enters the "develop" menu.
FIXME
POST https://devs.ouya.tv/api/v1/eventsSend information about the last events on the OUYA console to the logging/tracking server.
Every now and then when enough events have been collected
FIXME: determine exact behavior
https
POST
devs.ouya.tv
/api/v1/events
Standard headers
Content-Typeapplication/x-www-form-urlencoded
current_time1434577856574
Unix timestamp, milliseconds.
console_idSame data as in standard header X-OUYA-Console-Id
eventsJSON-encoded array of event objects
auth_tokenSame data as in standard header X-OUYA-AuthToken
Example event JSON data:
[
{
"data": "num_connected_controllers=1 controller_names=\"OUYA Game Controller\" controller_versions=\"104\"",
"timestamp": 1434577827864,
"name": "connected_controllers",
"uuid": "47ebb367-ce5f-4249-88f1-312bfac9efa2"
},
{
"data": "num_apps_sideloaded=0 sideloaded_packages=none",
"timestamp": 1434577827849,
"name": "sideloaded_apps",
"uuid": "7ab19279-0308-4a65-93d2-bc83f3bc518b"
},
{
"data": "hardware_version=0 ouya_version=1.2.1427_r1 system_language=eng age_gate=null pin_code=false num_apps_ouya=0 num_apps_sideloaded=0 num_buried_packages=0 hd_space_used=0 hd_space_free=0 mem_free=436621312 mem_total=1018093568 tv_resolution=1920x1080 network_device=ethernet adb_enabled=true",
"timestamp": 1434577827834,
"name": "console_snapshot",
"uuid": "308b7829-a357-4d0d-a79b-2456c40dc678"
},
{
"data": "app_session_uuid=a963561b-a6e8-49f5-bcfa-218bc5a1d6c8 app_session_ouya_uuid=e0eef5de-624c-42f8-9b1b-a0968a27eb03 app_session_package=tv.ouya.oobe app_session_current_activity=tv.ouya.console.launcher.agreements.AgreementsActivity app_session_start_tick=37 app_session_current_tick=605 app_session_active_ticks=568 app_session_last_analog_tick=597 app_session_last_digital_tick=32",
"timestamp": 1434577800458,
"name": "app_session_update",
"uuid": "161d3457-4469-42e3-bbc5-4c8e4a45743f"
},
{
"data": "app_session_uuid=a963561b-a6e8-49f5-bcfa-218bc5a1d6c8 app_session_ouya_uuid=e0eef5de-624c-42f8-9b1b-a0968a27eb03 app_session_package=tv.ouya.oobe app_session_current_activity=tv.ouya.console.launcher.agreements.AgreementsActivity app_session_start_tick=37 app_session_current_tick=605 app_session_active_ticks=568 app_session_last_analog_tick=597 app_session_last_digital_tick=32",
"timestamp": 1434577800331,
"name": "app_session_update",
"uuid": "ce209f8e-c564-4264-afdd-9e139b4d99fd"200 OK
application/json; charset=utf-8
{}
POST https://devs.ouya.tv/api/v1/gamersRegister a new user and/or verify new user registration data.
This method is both used as verification during input, as well as the final registration.
Razer Forge TV uses POST https://devs.ouya.tv/api/razer/gamer instead.
During registration to check if data are valid
During registration to finish new user sign up and create the account
https
GET
devs.ouya.tv
/api/v1/gamers
Standard headers except token parameters.
Content-Typeapplication/x-www-form-urlencoded
gamer[username]User name used to log in
gamer[password]User password
gamer[password_confirmation]User password, a second time
gamer[email]User e-mail address for marketing e-mails
gamer[gender]unknown | male | female
gamer[email_opt_out]false | true
Opt out from marketing e-mails
dryruntrue
If set, the user data are not registered - only verified. The response then tells which fields are deemed invalid.
Not set when the user clicks "register".
..note:: Does not support HTTP redirects!
When everything is ok and the user has been registered
(or the data were valid when dryrun was set)
200 OK
application/json; charset=utf-8
{}
When some of the data are deemed to be invalid.
400 Bad Request
application/json; charset=utf-8
Example:
{
"error": {
"data": {
"username": [
"can't be blank",
"is too short (minimum is 3 characters)",
"is invalid"
],
"password": [
"can't be blank",
"cannot contain username"
]
},
"message": "Validation errors occurred",
"code": 2006
}
}PUT https://devs.ouya.tv/api/v1/gamers/keyStore the user's public key on the server.
Receipts/purchases are encryptd by the server with the user's public key, so that only that user can decrypt it.
Once per bootup just before purchases are checked the first time. That can be when opening "Play" that contains purchasable games, or "Discover" showing purchasable games.
https
PUT
devs.ouya.tv
/api/v1/gamers/key
Standard headers
Content-Typeapplication/x-www-form-urlencoded
auth_tokenSame data as in standard header X-OUYA-AuthToken
auth_tokenSame data as in standard header X-OUYA-AuthToken
gamer[key]string
FIXME encryption key
gamer[password]string
User account password
gamer[username]string
User account name
Example key:
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvf3MvvZui5shNGbt2O0zveXrtfHZNivowNKiO UagJARKCJmjOJVtZ1srCe95Eul/xBDPDEaH8vJetn5Pl99QwhdYL1ps9mUhmocx90LavQsipr2Dw B7XshwN/EpW0uR/R84a3yXozpk7dgXi4+y//A+XT+MqgxsY6cdSGrBMsCQIDAQAB -----END PUBLIC KEY-----
201 Created
application/json; charset=utf-8
{}
GET https://devs.ouya.tv/api/v1/gamers/meFetch username, e-mail and other data about the user currently logged in.
https
GET
devs.ouya.tv
/api/v1/gamers/me
Standard headers
auth_tokenSame data as in standard header X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
Example:
{
"gamer": {
"uuid": "0a6f5fc0-bf9b-42b2-a4d0-69f2c8e4d5da",
"settings": {},
"founder": false,
"email": "cwdev3@example.org",
"username": "cwdev3"
}
}Razer Forge TV want this additional properties:
nicknameSame as username on the OUYA.
When not set, the Forge asks to enter the nickname during login.
avatarURL of a custom avatar image
GET https://devs.ouya.tv/api/v1/gamers/me/agreementsCheck which legal agreements have been confirmed by the user, and if there are updates that have to be confirmed.
https
GET
devs.ouya.tv
/api/v1/gamers/me/agreements
Standard headers
auth_tokenSame data as in standard header X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
Example:
{
"marketplace_required_version": 2,
"marketplace": 0,
"privacy_required_version": 0,
"privacy": 0
}Each agreement has an associated HTML file with the same name
at https://devs.ouya.tv/agreements/, e.g.
https://devs.ouya.tv/agreements/marketplace.html for the
marketplace agreement.
PUT https://devs.ouya.tv/api/v1/gamers/me/agreementsStore that a legal agreement has been confirmed by the user.
After setting up a factory-reset OUYA.
After logging in with an existing account.
After booting up the OUYA.
https
PUT
devs.ouya.tv
/api/v1/gamers/me/agreements
Standard headers
Content-Typeapplication/x-www-form-urlencoded
auth_tokenSame data as in standard header X-OUYA-AuthToken
marketplace:2
Version of the marketplace agreement
auth_token:Same data as in standard header X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
{}
GET https://devs.ouya.tv/api/v1/gamers/me/apps/developedLoaded then the user enters the "develop" menu and activates the "builds" menu item.
FIXME
POST https://devs.ouya.tv/api/v1/gamers/me/consolesAssociate a console ID with the account.
After logging in with an existing account
(Probably after registering a new account)
https
POST
devs.ouya.tv
/api/v1/gamers/me/consoles
Standard headers
Content-Typeapplication/x-www-form-urlencoded
auth_tokenSame data as in standard header X-OUYA-AuthToken
console_id:015d4b33bc64141b
Same data as in standard header X-OUYA-Console-Id
auth_token:Same data as in standard header X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
{}
GET https://devs.ouya.tv/api/v1/gamers/me/user_messagesSend messages to users.
The API returns a list of URLs that get displayed to the user in a popup in the main menu.
https
GET
devs.ouya.tv
/api/v1/gamers/me/user_messages
Standard headers
auth_tokenSame as X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
Example (empty):
{
"messages": [
null
]
}Example (one URL):
{
"messages": [
"https://www.ouya.tv/message_to_all_users.txt"
]
}GET https://devs.ouya.tv/api/v1/games/xxx/purchasesCheck which features have been bought in an app (if the app has been bought).
Each game may have multiple products that can be bought. One of them may be the "promotedProduct" in the discover section, and that one can be bought in the discover store / play menu app details.
When an app/game is featured and shown on the main menu ("home"), it is checked if the app has already been purchased.
When opening the game details the "buy" button is shown if the "promotedProduct" is in the list of purchases
When a game starts it checks if it has been bought.
https
GET
devs.ouya.tv
/api/v1/games/xxx/purchases
xxxapp package name
Example: /api/v1/games/com.ChrisChung.CatlateralDamage/purchases
Standard headers
auth_tokenSame as X-OUYA-AuthToken
app_idcom.ChrisChung.CatlateralDamage
Same as the one in the path.
user_agentlauncher
200 OK
application/json; charset=utf-8
The response is a JSON objec containing three properties:
ivBase 64 encoded initialization vector for encryption
keyBase 64 encoded FIXME. Must be 128/192/256 bits long.
blobBase64 encoded encrypted data
The decrypted blob contains again a JSON object with three properties:
iv
key
blob
This blob is again base64-encoded JSON and contains the actual data: A JSON with a single property "purchases" whose value is an array of receipts/purchases.
Each receipt has the following properties:
purchaseDateRequired. Milliseconds.
generateDateOptional. Milliseconds.
identifierProduct key. Required. Alternative name: sku.
gamerUser UUID. Required.
uuidTransaction UUID. Required.
priceInCentsInteger. Required.
localPriceFloat. Optional.
currencyOptional. Default USD.
Encrypted response:
{
"blob": "0F/7D3gtCgLNJ6pZsy8M5LOLMlNsKPouBlY2VvYeTSF+k5LZQR0Otbp8vZXV\nS8Ad/hlQAuqrVgnLYEO1gxadfWQnQE1ZEoOnGcxBiNL2svOftt1uonvyTqBt\nKz5qLrd2oNI8V65dX+0ydZ7IwT5TOglC4B/YHKjA32GYNaw7GaNMmu3zJVfF\nJblVT4bZDOeyxTLanp3Fan7fZ6AkMlWy81T5RMf9vB/PBkUWlpIUZeUToXBT\n6HSRV1Ke4kfkyvmY2WisxJ0dApkcgS+bdbWhH7JsdMTT+zwUISxav5iJLkVt\n1fA1g5WN8NwVzb2OKPZcAQm1d/TnsqUnMQBfDAFaji7ADZ0Ukd0xxsirYQTW\nWpNJbFVtAJpkLNjEqVSVWqr0\n",
"iv": "t3jir1LHpICunvhlM76edQ==\n",
"key": "CqREllniR2CZsTdqGlSHq+b1n/ludDCPV8AAaR3aF4va8lckIRONsvQmndJS\niccb/UeYHXQOf2o06/oR8rGJvrAf598K7a7QQSSY1u6Btd8op/nOzCn+F7Q5\n4tqu7qvlVRrIMDIQtms/SfQTE2XEyKvEQVm2N/PhbdjXmXmgJHU=\n"
}Decrypted receipt list:
{
"purchases": [
{
"purchaseDate": 1576845859000,
"generateDate": 1576845859000,
"identifier": "blookid2_full",
"gamer": "00702342-0000-1111-2222-c3e1500cafe2",
"uuid": "0dc813a0-37d5-11ea-9ea4-075f44abe85b",
"priceInCents": 399,
"localPrice": 3.99,
"currency": "EUR"
}
]
}POST https://devs.ouya.tv/api/v1/games/xxx/purchasesBuy a game.
After buying the game shows up in GET https://devs.ouya.tv/api/v1/premium_purchases.
When the user buys an app/game.
https
POST
devs.ouya.tv
/api/v1/games/xxx/purchases
xxxapp package name
Example: /api/v1/games/com.ChrisChung.CatlateralDamage/purchases
Standard headers
Content-Typeapplication/x-www-form-urlencoded
auth_tokenSame as X-OUYA-AuthToken
user_agentlauncher (at least when bought through the OUYA UI)
blobBase64-encoded encrypted data
ivBase64-encoded initialization vector for the cryptographic function
keyBase64-encoded key used to encrypt the blob.
Encrypted with FIXME: gamer key or developer key.
auth_tokenSame as X-OUYA-AuthToken
The decrypted blob again contains blob, key and iv.
The decrypted inner blob contains a JSON object:
identifierProduct key
testingUnknown. Always "true".
uuidRandom number that is used by the game for this purchase request. Must be returned in the response to this request.
Raw request (without encryption):
blob=eyAia2V5IiA6ICJHcnl0dnRSYjY5TDh6L3pIT3RTdGFnPT0iLCAiaXYiIDogIjZzMDd3OGo3VFNleVhQdzBsMXdvRUE9PSIsICJibG9iIiA6ICJleUpwWkdWdWRHbG1hV1Z5SWpvaVoyOWlYMloxYkd4ZloyRnRaVjkxYm14dlkyc2lMQ0owWlhOMGFXNW5Jam9pZEhKMVpTSXNJblYxYVdRaU9pSTNOak0xTjJFME9XRm1NVFk0WWpJNUluMD0iIH0%3D&iv=QHpnmyEf7BGZhTnK37NggQ%3D%3D&key=bdR0jZ22clKqJwOsyYdn8w%3D%3D&auth_token=00702342-0000-1111-2222-c3e1500cafe1Decrypted:
{
"identifier":"SONIC4EP1FULL_001",
"testing":"true",
"uuid":"2ba72281837f0df3"
}200 OK
application/json; charset=utf-8
Again the base-64 encoded keys: iv, key and blob.
blob is a JSON object that needs to contain the uuid property.
Most games do not want any other properties.
"God of Blades" requires:
identifier
name
priceInCents
{
"blob": "YKNolqKuaDcQnqQH8yncS+0hVl/YnajMgnojfMaO2IzUpfVg4lBVrz5NF30N\nXUkgpBTnXdcPUalv7YvWsqT9b8Tdm5PYgoduqi2zLyXF+bSWY+bBigDX+MDG\nyvgxjfpYcWeyYaNLn2vhsj0rVNVorT5CggAXrry2eeUIFOX+9IUzbHmxfiqP\nlglVtrudwzQO1PS5n3KNJnHfp+r7vgBG5DzErUK4YHUYBe4/9li313tEIwnK\nX4kDZXSzKiZ2SPfyYTaVgIr82x9GDaIa1ZXIBuFlQSUo55A5Gy7Wy9rTDzMb\n80LdsNlbHeOiSIBN7Rj7CuOu7Uz5btuWLCpmCHZ2xgyhN6I9y2/KTNYa2JIA\n/9fsBGcrdkiu4f3aKdiZlI8bh07npp10KpQEMszz59xr5V6h0Xjjcgw95SaE\nDmxxz3LSRVtNpjGsTlqsb4Jnc/fKcMrJcmzoDLAodfgnSev8hrNUmgs6f/df\neXKQ0J6JuiWAgKXUZ9g5GEkUn0uIo3RzIyVqRIJL9zM6oeaZ487zG1X2e5Xy\noCc1x6GKQpGr9Qp+hRp6HSp8NUyR2ZziD+DSHbZeDaZdu3bbWrzIDEVJLpwU\noVROZR2nqyR9i3eQlpvSJGUPBM9pi8KdYTvOuBKB9hrz1XYe8852bFsbn0G/\np8nmKKPM0xDc0gHuScLfUZQ=\n",
"iv": "wV8mnhuGz7YaxNSP1QWfVQ==\n",
"key": "hxvgGjQWJJ8vSidCF5eP4JC1VqUjZxL+ZLq9p6BrbuhSMqvtFU/YZxinKTeD\nMkCnK3Ie0lP8OoKGFl21F+/5rOuybD+FKfVJdXwIsA1ryjkFi8KBMq2G+YWo\nxMM9T0zdkOKiidK1GYHqJyLlVLrEC+qaLSqSPEoL9R0ovZhy64c=\n"
}GET https://devs.ouya.tv/api/v1/partner_buildsFetch commands for the "OUYA Everywhere" installer.
The OUYA Everywhere installer tv.ouya.oe.installer fetches this URL
from the server, installs package updates (framework, console UI)
and then starts the actual console UI.
Used on the Mad Catz Mojo and Razer Forge TV.
https
GET
devs.ouya.tv
/api/v1/partner_builds
The Razer Forge TV seems to prefix all custom headers with X-OUYA-
while the Mojo version only uses X-.
User-AgentKnown values:
ouya-everywhere-installer (MadCatz/mojo-TS/mojo:4.2.2/JDQ39/MO0205-TS:user/release-keys)
ouya-everywhere-installer (razer/pearlyn/pearlyn:6.0.1/M-MMB29M-rzs-us-sf-bld2-19HP-08.02.AM/144:user/release-keys)
Accept-Languagede
en-US,en
X-InstallerVersionCodeRazer Forge TV: 8
X-InstallerVersionNameRazer Forge TV: 1.08
X-InstallerPackageNametv.ouya.oe.installer
X-OUYA-Console-IdBuild serial number
Razer Forge TV: 171256710321511
X-Device??
X-OUYA-DeviceRazer Forge TV: pearlyn
X-Product??
X-OUYA-ProductRazer Forge TV: pearlyn
X-Model??
X-OUYA-ModelRazer Forge TV: Forge
X-Brand??
X-OUYA-BrandRazer Forge TV:razer
X-Display??
X-OUYA-DisplayRazer Forge TV: M-MMB29M-rzs-us-sf-bld2-19HP-08.02.AM.144
X-BuildId??
X-OUYA-BuildIdRazer Forge TV: M-MMB29M-rzs-us-sf-bld2-19HP-08.02.AM
X-Manufacturer??
X-OUYA-ManufacturerRazer Forge TV: razer
OUYAUsernameWhen logged in.
X-OUYA-AuthTokenOnly when logged in already
00702342-0000-1111-2222-c3e1500cafe1
200 OK
application/json; charset=utf-8
The response is a list of commands that the OUYA Everywhere installer will execute one after another.
The top-level object contains a key actions, which is an array of
action objects.
Each action has a action property that defines its type.
Just stop the installer.
No additional properties.
{
"actions": [
{
"action": "exit"
}
]
}Install the given .apk file if it has not yet been installed.
actioninstallFile
packageNameName of package to install. Example: de.ouya.cweiske.foo
friendlyNameName shown on screen during installation
md5Example: d3b07384d113edec49eaa6238ad5ff00
filesize12345
downloadUrlhttp://example.org/app.apk
versionCodeOptional property. Example: 23.
Only install when the current version is lower than this number.
Start the given application
actionlaunch
packageNameApplication to start. Example: de.ouya.cweiske.foo
Show a message that the user has to confirm.
actionshowDialog
titleMessage dialog title string
messageActual text
verticalMarginOptional. Example: 1.0
Remove a package
actionuninstallFile
packageNameExample: de.ouya.cweiske.foo
keepDataOptional boolean. Example: false
ifLessThanVersionCodeOptional integer. Example: 12
ifGreaterThanVersionCodeOptional integer. Example: 42
{
"actions": [
{
"action": "installFile",
"packageName": "tv.ouya.oobe",
"friendlyName": "OUYA OOBE",
"md5": "41d50891225591fdd32045ed0821a3bf",
"filesize": 7725861,
"downloadUrl": "http://ouya.cweiske.de/apks/ouya-everywhere/tv.ouya.oobe-1.2.897.apk",
"versionCode": 10200897
},
{
"action": "installFile",
"packageName": "tv.ouya",
"friendlyName": "OUYA Framework",
"md5": "95d987e7b100c2c72bdac37a8eda2647",
"filesize": 3123639,
"downloadUrl": "http://ouya.cweiske.de/apks/ouya-everywhere/tv.ouya-1.2.897.apk",
"versionCode": 10200897
},
{
"action": "installFile",
"packageName": "tv.ouya.console",
"friendlyName": "OUYA launcher",
"md5": "97da25989c64a90c60070978077fff55",
"filesize": 18953944,
"downloadUrl": "http://ouya.cweiske.de/apks/ouya-everywhere/tv.ouya.console-1.2.897.apk",
"versionCode": 10200897
},
{
"action": "launch",
"packageName": "tv.ouya.console"
}
]
}GET https://devs.ouya.tv/api/v1/partner_builds/release_notesReturn the changelog for the latest OUYA everywhere installer.
Used by the Razer Forge TV only (Manage > Razer Cortex > "Update Notes").
https
GET
devs.ouya.tv
/api/v1/partner_builds/release_notes
User-AgentDalvik/2.1.0 (Linux; U; Android 6.0.1; Forge Build/M-MMB29M-rzs-us-sf-bld2-19HP-08.02.AM)
Accept-Languagede
X-OUYA-Devicepearlyn
X-OUYA-Firmware-Version:(empty)
X-OUYA-Console-IdBuild serial number
171256710321511
X-OUYA-Console-Wifi-MAC-AddressC4:8E:8F:82:29:B1
X-OUYA-VersionCode10202320
X-OUYA-AuthToken00702342-0000-1111-2222-c3e1500cafe1
200 OK
application/json; charset=utf-8
{
"releaseNotes": "This is the latest firmware for the Razer Forge TV."
}GET https://devs.ouya.tv/api/v1/queued_downloadsFetch a list of apps/games that shall get installed automatically on the OUYA.
The OUYA checks the download queue exactly every 5 minutes.
More information: http://cweiske.de/tagebuch/push-to-ouya.htm
https
GET
devs.ouya.tv
/api/v1/queued_downloads
Standard headers
auth_tokenSame as X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
Known source options:
gamerThe user clicked onto "push to my ouya" on the OUYA website
game-of-the-monthThe game gets automatically installed because the OUYA people awarded it the "game of the month" trophy.
new-userYou are a freshly registered user and should have this game on your OUYA.
Automatically pushed onto a fresh account:
{
"queue": [
{
"versionUuid": "",
"title": "Tetris Battle Fusion",
"source": "new-user",
"uuid": "com.toa.tetrisFusionOuya"
},
{
"versionUuid": "",
"title": "BombSquad",
"source": "new-user",
"uuid": "net.froemling.bombsquad"
}
]
}Manually pushed via the web site:
{
"queue": [
{
"versionUuid": "",
"title": "Sonic The Hedgehog 4 Episode I",
"source": "gamer",
"uuid": "com.sega.sonic4epi"
}
]
}DELETE https://devs.ouya.tv/api/v1/queued_downloads/xxxRemove an app from the list of queued downloads.
After the app has been installed automatically on the OUYA.
https
DELETE
devs.ouya.tv
/api/v1/queued_downloads/xxx
xxxPackage name. The uuid value from the queued downloads list.
Example: /api/v1/queued_downloads/net.froemling.bombsquad
Standard headers
uuidThe uuid value from the queued downloads list, which is actually
a package name and not an UUID.
Same as the xxx in the path.
auth_tokenSame as X-OUYA-AuthToken
204 No Content
GET https://devs.ouya.tv/api/v1/ratingsGet a list of games and the ratings the user made for them.
https
GET
devs.ouya.tv
/api/v1/ratings
Standard headers
auth_tokenSame as X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
{
"ratings": [
{
"score": 4,
"game": "com.grahamweldon.games.puzzle2048"
},
{
"score": 2,
"game": "com.baKno.Motorbike"
},
{
"score": 4,
"game": "org.jfedor.frozenbubble"
}
]
}POST https://devs.ouya.tv/api/v1/ratingsStore the rating of a single game
Directly after a user rated a game on the exit screen.
https
POST
devs.ouya.tv
/api/v1/ratings
Standard headers
auth_tokenSame as X-OUYA-AuthToken
auth_tokenSame as X-OUYA-AuthToken
gamePackage name of the game
E.g. com.littleguy77.filepwn
scoreinteger
1 to 5:
Hate it
Don't like it
Like it
Really like it
Love it
200 OK
application/json; charset=utf-8
Example:
{
"success": true
}GET https://devs.ouya.tv/api/v1/recommendationsGet a list of games for the "you may also like" section.
Games already installed on the OUYA will be shown, too - with a checkmark.
When the user tries to exit a game (double-pressing U)
https
GET
devs.ouya.tv
/api/v1/recommendations
Standard headers
auth_tokenSame as X-OUYA-AuthToken
uuidPackage name of the game that is being exited
Example: net.sourceforge.clonekeenplus
200 OK
application/json; charset=utf-8
{
"games": [
{
"rating": {
"count": 716,
"average": 4.25
},
"image": "https://www.filepicker.io/api/file/VzCsgc3BTx2RiGpTr4Uw",
"content_rating": "Everyone",
"version": "7230ac05-d24c-4347-a990-7ac283c17063",
"uuid": "com.GoldenTricycle.Clark",
"title": "CLARC"
},
{
"rating": {
"count": 1108,
"average": 3.49
},
"image": "https://www.filepicker.io/api/file/ej3IxeX8SwKZW5uFOw9g",
"content_rating": "Everyone",
"version": "544236ed-6dde-4b9e-8c4f-ac6e8b91bcd3",
"uuid": "com.sega.sonic4epi",
"title": "Sonic The Hedgehog 4 Episode I"
},
{
"rating": {
"count": 522,
"average": 4.38
},
"image": "https://www.filepicker.io/api/file/s8HCRKaSB8wF2hSKbBzQ",
"content_rating": "Everyone",
"version": "29457560-1669-45ce-bb19-88c1651c7552",
"uuid": "com.x10studio.SoManyMe",
"title": "So Many Me"
}
]
}GET https://devs.ouya.tv/api/v1/searchSearch for games in the discover store.
https
GET
devs.ouya.tv
/api/v1/search
Standard headers
auth_tokenSame as X-OUYA-AuthToken
qSearch word(s)
200 OK
application/json; charset=utf-8
The count property contains the number of games that matched the search
string, even if they are not all returned in the result list.
The search result list is limited to 20 or 40 games.
When the count is higher than the number of items in results,
the OUYA will send a new search request to the API when another letter is added
to the search word.
If the count and results are the same, the OUYA will use the current
response and filter it for itself without asking the server again.
{
"count": 1,
"results": [
{
"title": "Frightfight",
"url": "ouya://launcher/details?app=com.appsolutegames.frightfight",
"contentRating": "Everyone"
}
]
}POST https://devs.ouya.tv/api/v1/sessionsLog in and obtain a session token.
This token is stored in the console and used in the
X-OUYA-AuthToken and X-Token headers as well as the
auth_token GET parameter.
The Razer Forge TV uses POST https://devs.ouya.tv/api/razer/session instead.
After logging with an existing account
After new user registration
When visiting Manage > Accounts
https
POST
devs.ouya.tv
/api/v1/sessions
Accept-Encoding
User-Agent
X-OUYA-Console-Id
X-OUYA-Device
Content-Typeapplication/x-www-form-urlencoded
usernameUser name used to log in
passwordUser password
When the user logged in successfully.
200 OK
application/json; charset=utf-8
Response body example:
{
"token": "96bfeaae-212d-447b-b4bf-caa5e86c0502"
}When the login data are invalid.
Also seen when the data were not available yet (e.g. user freshly registered) but the processes on the server were not finished yet. The OUYA simply tried the request a second time.
400 Bad Request
application/json; charset=utf-8
Response body example:
{
"error": {
"message": "Invalid authentication data",
"code": 2001
}
}GET https://devs.ouya.tv/api/v1/themesLoad the main menu background image/video.
During startup before loading the main menu
Every three hours
https
GET
devs.ouya.tv
/api/v1/themes
Standard headers.
auth_tokenMay be empty.
Does not seem to have any influence on the response.
200 OK
application/json; charset=utf-8
background_styleSupported until at least ODK 1.0.12. Latest firmware 1.2.1427 does not support it anymore.
static meant that the image would be scaled.
Any value other than static would make the image pan around.
backgroundFull URL to a backgroud image
videoSupported until at least ODK 1.0.12. Latest firmware 1.2.1427 does not support it anymore.
Video URL had preference over background image URL.
{
"background_style": "static",
"background": "",
"video": ""
}FIXME: get response with video/image set.
GET https://devs.ouya.tv/api/v1/walletGet the account balance and currency.
After user registration, before the credit card input form is shown.
https
GET
devs.ouya.tv
/api/v1/wallet
Standard headers
auth_tokenSame data as in standard header X-OUYA-AuthToken
200 OK
application/json; charset=utf-8
{
"requiresPaymentMethod": true,
"balance": 0,
"credit_card": null,
"currency": "EUR"
}FIXME: Find out if we get that response when giving a dummy number during registration (4111 1111 1111 1111).
{
"balance": 0.0,
"credit_card": {
"expires_at": "09/30/2016",
"last_four": "1234",
"provider": "MasterCard"
},
"currency": "USD",
"requiresPaymentMethod": true
}FIXME: Find out if we can disable credit card input by setting
requiresPaymentMethod to false.
GET https://devs.ouya.tv/agreements/marketplace.htmlTerms of services you have to accept during registration.
Fetched by the browser / web view.
https
GET
devs.ouya.tv
/agreements/marketplace.rst
None of the standard headers required.
None
HTML file
GET https://devs.ouya.tv/update_strings.txtLabels to show when updating the firmware.
https
GET
devs.ouya.tv
/update_strings.txt
None of the standard headers required.
None
Plain text file with one string per line
Preparing to televise the Revolution…
Downloading awesome sauce…
Maximizing fun level…
Shifting bits…
Tasting rainbows…GET http://ouya-updates.s3.amazonaws.com/updates-ouya_1_1.jsonInformation about the latest firmware.
Only used by old firmware versions like 1.0.138 and 1.0.158.
Firmware 1.0.248 and later do not check this URL anymore and
use GET https://devs.ouya.tv/api/firmware_builds instead.
http
GET
ouya-updates.s3.amazonaws.com
/updates-ouya_1_1.json
200 OK
{
"result": [
{
"filename": "OUYA-1.2.1084-r1.zip",
"timestamp": "1400714704",
"md5sum": "ed9f1712988c5ec2033f44fabe8e6297",
"channel": "stable",
"url": "http://devs-ouya-tv-prod.s3.amazonaws.com/ota/RC-OUYA-1.2.1084-r1_ota.zip",
"requiredUpto": "1.2.995",
"changes": "https://devs.ouya.tv/api/changelog/ed9f1712988c5ec2033f44fabe8e6297.txt",
"changesLocalized": {
"en": "<!doctype html>\r\n<html>\r\n <head>\r\n...",
"es": "<!doctype html>\r\n<html>\r\n <head>\r\n...",
"fr": "<!doctype html>\r\n<html>\r\n <head>\r\n...",
"it": "<!doctype html>\r\n<html>\r\n <head>\r\n...",
"de": "<!doctype html>\r\n<html>\r\n <head>\r\n..."
},
"incremental": false
}
]
}GET https://www.ouya.tv/system_messageUnknown
After storing credit card result in PUT https://devs.ouya.tv/api/v1/credit_card.
https
GET
www.ouya.tv
//system_message
User-AgentOUYA 0 1.00 1.2.1427_r1
build:1.2.1427_r1
OUYA firmware version
403 Forbidden
This was probably once used, but now does only return an error.
It is possible to modify the behavior of the OUYA console by setting config options.
They can be set in two ways:
In an ini-style file ouya_config.properties in the root OUYA directory
when attached via USB to a PC (/sdcard/ on the OUYA itself).
On the server, via the GET https://devs.ouya.tv/api/v1/console_configuration JSON file.
ATTRACT_LOOP_FILENAMEFull path to the not-in-use-autoplay video in kiosk mode.
Default: /sdcard/ouya_attract_loop.mp4
CCTESTWhen set to 1, the "Manage" menu shows a "[DEBUG] Test CC signup" entry.
CRASH_REPORTSWhen set to 1, the "Manage" menu shows a "[DEBUG] Send crash reports" entry.
It immediately sends stored crash reports to the server.
DEBUGWhen set to 1, additional output is shown in adb logcat.
You will see the remote server URLs that the OUYA is trying to fetch.
DELETE_ACCOUNTSWhen set to 1, the "Manage" menu shows a "[DEBUG] Delete user accounts" entry
that immediately deletes the user account.
DONT_DELETE_OTAWhen an over-the-air update has been downloaded, it gets moved to
/cache/update.zip.
After moving, the original file gets deleted.
This option disabled this deletion.
Default: 0
(in ouya-framework.jar)
DUMP_DISCOVER_PAGESStore the downloaded API responses for discover category pages on
/sdcard/.
ENABLE_AGREEMENTSWhen disabled, the regular fetch of /api/v1/gamers/me/agreements will not happen.
Also does not show the agreements during user registration in OOBE.
Default: 1
ENABLE_BUY_NOWWhen set to 1, the store details view shows a "buy now" button
for games that have the "premium" flag set and a promoted product.
Default: 1
ENABLE_BUY_NOW_PRICEWhen set to 1, the store details view shows the product price on
the "buy now" button (see ENABLE_BUY_NOW).
Default: 1
ENABLE_BUY_NOW_PRICE_GUIDEWhen set to 1, the guide menu
(that appears when double-clicking the ouya logo button)
shows the price of the promoted product.
ENABLE_UPLOAD_LOGSAutomatically update system logs. Needs super user access for uploading.
Default: 1
FORCE_OTAWhen set to 1: Force the OUYA to install an over-the-air update.
Default: 0
FORCE_VIDEO_ERRORWhen set to 1: Show an error whenever a video shall be played.
Default: 0
KIOSK_MODEWhen set to 1, the OUYA is set to a read-only mode.
Only the "play" menu is visible, and it only allows to start games - not even see their details.
Upon inactivity after some minutes, a video
/storage/sdcard0/ouya_attract_loop.mp4 is being played.
(See ATTRACT_LOOP_FILENAME)
LOC_MULTIPLIERFloat value between 1.0 and 3.0
Increases the string length by the given factor by repeating the letters in translatable strings.
LOC_XXXWhen set to 1, all letters in translatable strings are replaced with X.
Needs a reboot.
METRIC_APP_DETAILSWhen set to 1: Send a tracking notification whenever a details page
in the store is shown, along with the app UUID.
OE_MAX_DOWNLOADSNumber of maximum downloads in the queue for non-ouya devices.
Default: 10
OUYA_MAX_DOWNLOADSNumber of maximum downloads in the queue for original OUYA devices.
Default: 5
OUYA_SERVER_URLBase URL of the API server to connect. By modifying this value, you can switch the OUYA to another server.
Default: https://devs.ouya.tv
OUYA_STATUS_SERVER_URLUsed to check if the OUYA can reach the internet.
This URL needs to return a "204" HTTP status code.
Default: http://status.ouya.tv/api/v1/status
QUERY_GENDER_DOBShow the gender and birthday input fields during registration in OOBE.
Default: 1
RATING_PROMPT_DELAYNumber of game launches until the "rate this game" prompt is shown.
Default: 0 (after the first launch)
RATING_PROMPT_FREQWhen rating a game has been skipped, it will be tried again after X launches.
0 to disable rating popups.
Default: 5
RATING_PROMPT_MAXMaximum number of "Rate this game" popups per game.
Default: 0 (infinite)
SAFE_ZONEShow a grey border around the OOBE screen.
Default: 0
UPDATE_TEXT_URLWhen installing an update, funny messages are shown. They are downloaded from this URL.
Default: https://devs.ouya.tv/update_strings.txt
USER_MESSAGESComma-separated list of URLs to show to the user. See GET https://devs.ouya.tv/api/v1/gamers/me/user_messages.
Default: empty
WIFI_STATUS_DISPLAYWhen set to 1:
Shows the current wifi status on the top right of all screens.
Example:
Wifi: INTERFACE_DISABLED, Strenght (0-8): 0
Only the name of this variables is known:
BTC_LAUNCHER_PACKAGES BTC_PARAMS_APP BTC_PARAMS_LAUNCHER COMPARE_OTA_SETTINGS UPDATE_READY_UI_TIMEOUT UPLOAD_LOGS_SEQ_NUM
They are defined in the code, but not used anywhere in OUYALauncher.apk:
APP_UPDATE_CHECK_INTERVAL ATTRACT_LOOP_TIMEOUT COMMUNITY_CONTENT_ENABLED DEBUG_PICASSO DISCOVER_HEADER_TEXT ENABLE_REMOTES ENABLE_TRACES INPUT_REMAPPING_JSON_FILE LOCALE METRIC_EXIT_GENRE METRIC_EXIT_STORE METRICS_SPEW NUM_RECENT_DOWNLOADS_IN_DISCOVER OUYA_RENAME_CONTROLLER SESSION_UPDATE_DELAY_SEC SHOW_DISCOUNTS SYSTEM_MESSAGE_URL THEME_CHECK_INTERVAL USE_FAKE_VIDEOS
This documentation has been written by Christian Weiske, cweiske+ouya@cweiske.de.
Last update: 2023-10-08T10:24:43+02:00
It is licensed under the GNU Free Documentation License.
The documentation sources are available at http://git.cweiske.de/ouya-store-api.git/ and mirrored at https://github.com/cweiske/ouya-store-api
A rendered version of this documentation is available at http://cweiske.de/ouya-store-api-docs.htm
You need to install rst2html5 before:
$ pip install rst2html5-tools
Rendering the docs is done via a build script:
$ ./build.sh