Portal API
The Developer Portal is a website over this API. Everything it does is a call to /api/v1/developer, and it is documented here so you know what the portal can do and what it records.
Who can call it
These endpoints act on your own applications and are reached as you: from a browser signed in to moymo.net, or with an access token carrying the first-party developer scope, which only Moymo's own portal is given. A bot token or an ordinary OAuth2 token cannot call them. There is not yet a way to manage applications from your own scripts; if you need one, say so.
Base: https://moymo.net/api/v1/developer. Every answer is Cache-Control: no-store.
Applications
| Method and path | Does |
|---|---|
GET /meta | The scopes, the permission bits and the limits the forms are drawn from. |
GET /apps | Your applications. |
POST /apps | Make one: {"name": "Dice Roller"}. Answers the whole application, as a draft. |
GET /apps/{id} | One application: everything the portal shows, including the live publish checklist. |
PATCH /apps/{id} | Change fields; fields you leave out stay as they were. |
DELETE /apps/{id} | Delete it: {"confirmName": "Dice Roller"} (the name, as a check). |
PUT /apps/{id}/redirects | Replace the redirect addresses: {"uris": ["https://..."]}. |
POST /apps/{id}/icon, POST /apps/{id}/banner | Upload a picture (multipart/form-data, field file, up to 5 MB). |
Secrets and the bot
| Method and path | Does |
|---|---|
POST /apps/{id}/secrets?replace=false | Make a client secret. The answer holds the secret, once. replace=true deletes every earlier one first. |
DELETE /apps/{id}/secrets/{secretId} | Delete one secret. |
POST /apps/{id}/bot | Give the application a bot; optional {"username": "dice_bot"}. The answer holds the token, once. |
PATCH /apps/{id}/bot | {"username", "displayName", "bio"}. |
POST /apps/{id}/bot/avatar | Upload the bot's picture. |
POST /apps/{id}/bot/token | Reset the token; the old one dies at once. The answer holds the new one, once. |
DELETE /apps/{id}/bot | Delete the bot. |
Domains, testers, publishing
| Method and path | Does |
|---|---|
POST /apps/{id}/domains | {"hostname": "example.com"}; answers the record to create. |
POST /apps/{id}/domains/{domainId}/check | Look for the record now. |
DELETE /apps/{id}/domains/{domainId} | Remove a domain. |
POST /apps/{id}/test-users | {"username": "someone"}. |
DELETE /apps/{id}/test-users/{userId} | Remove a tester. |
POST /apps/{id}/publish | {"visibility": "UNLISTED" | "PUBLIC" | "PRIVATE"}; refused with the first missing checklist line if it is not ready. |
POST /apps/{id}/unpublish | Back to a draft. |
GET /apps/{id}/audit | The last 100 things done to the application. |
An application that is not yours answers 404, as if it did not exist.
The application object
Fields with no value are left out, as everywhere in the API.
Example applicationJSON
json
{
"id": "0f6c1a52-3b9e-4c1c-9d1b-6e7d2a8f4b10",
"clientId": "0f6c1a52-3b9e-4c1c-9d1b-6e7d2a8f4b10",
"name": "Dice Roller",
"summary": "Rolls any dice you can name.",
"description": "...",
"translations": { "cs": { "name": "Kostky" } },
"tags": ["games", "dice"],
"accentColor": "#2bff6e",
"state": "DRAFT",
"visibility": "UNLISTED",
"installScopes": ["bot"],
"installPermissions": 7,
"botPublic": false,
"reviewNote": "",
"redirectUris": ["https://example.com/callback"],
"secrets": [{ "id": "...", "lastFour": "k2Zp", "createdAt": "..." }],
"bot": {
"userId": "...",
"username": "dice_roller",
"displayName": "Dice Roller",
"bio": "",
"tokenLastFour": "x7Qa",
"tokenRotatedAt": "..."
},
"domains": [],
"testUsers": [],
"checklist": [{ "code": "ICON", "ok": false, "message": "The app has an icon." }],
"publishable": false
}Secrets appear only as their last four characters, apart from the one answer that makes them.