{
  "openapi": "3.1.0",
  "info": {
    "title": "Veyra API",
    "version": "1.0.0",
    "description": "REST API for tracked Veyra Discord users and service health.\n\n**Authentication:** None required. All endpoints are public.\n\n**Rate limiting:** 200 requests per minute per IP, applied globally to all `/api/*` routes. Exceeding this returns `429 RATE_LIMITED`. Standard `RateLimit-*` headers are included on every response.",
    "x-logo": {
      "url": "/favicon.svg"
    }
  },
  "servers": [
    {
      "url": "https://veyra-db3d.onbelmo.uk"
    }
  ],
  "paths": {
    "/api/user/{userId}": {
      "get": {
        "summary": "Get tracked user",
        "description": "Returns the current serialized profile and presence snapshot for a tracked Discord user. No authentication required. Subject to the global rate limit (200 req/min per IP).",
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{17,20}$"
            },
            "description": "Discord user snowflake."
          }
        ],
        "responses": {
          "200": {
            "description": "User is tracked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserSuccess"
                },
                "example": {
                  "success": true,
                  "data": {
                    "kv": {},
                    "discord_user": {
                      "id": "123456789012345678",
                      "username": "lorb",
                      "global_name": "Lorb",
                      "display_name": "Lorb",
                      "discriminator": "0",
                      "avatar": "a_1234567890abcdef1234567890abcdef",
                      "avatar_url": "https://cdn.discordapp.com/avatars/123456789012345678/a_1234567890abcdef1234567890abcdef.png",
                      "avatar_decoration_data": null,
                      "banner": null,
                      "banner_url": null,
                      "accent_color": null,
                      "public_flags": 4194432,
                      "badges": [
                        "early_supporter",
                        "active_developer"
                      ],
                      "primary_guild": null
                    },
                    "activities": [
                      {
                        "id": "spotify:1",
                        "name": "Spotify",
                        "type": 2,
                        "state": "Radiohead",
                        "details": "Everything In Its Right Place",
                        "application_id": "123456789012345678",
                        "timestamps": {
                          "start": 1735689600000,
                          "end": 1735689780000
                        },
                        "assets": {
                          "large_image": "spotify:ab67616d0000b273",
                          "large_text": "Kid A"
                        },
                        "party": null,
                        "sync_id": "4Jz6E3Ie3sYGQ7lHhY0Zz3",
                        "flags": null,
                        "created_at": 1735689600000,
                        "buttons": []
                      }
                    ],
                    "discord_status": "online",
                    "active_on_discord_web": false,
                    "active_on_discord_desktop": true,
                    "active_on_discord_mobile": false,
                    "active_on_discord_embedded": false,
                    "active_on_discord_vr": false,
                    "listening_to_spotify": true,
                    "spotify": {
                      "track_id": "4Jz6E3Ie3sYGQ7lHhY0Zz3",
                      "timestamps": {
                        "start": 1735689600000,
                        "end": 1735689780000
                      },
                      "song": "Everything In Its Right Place",
                      "artist": "Radiohead",
                      "album": "Kid A",
                      "album_art_url": "https://i.scdn.co/image/ab67616d0000b273"
                    },
                    "custom_status": {
                      "text": "shipping veyra",
                      "emoji": null,
                      "expires_at": null
                    },
                    "guild": {
                      "id": "987654321098765432",
                      "name": "Veyra HQ"
                    },
                    "last_updated": "2026-09-03T12:00:00.000Z",
                    "tracked_since": "2026-01-15T09:30:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid Discord user ID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": {
                    "code": "INVALID_ID",
                    "message": "Invalid Discord user ID."
                  }
                }
              }
            }
          },
          "404": {
            "description": "User is not tracked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": {
                    "code": "USER_NOT_TRACKED",
                    "message": "This user is not currently tracked by Veyra."
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limited.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Too many requests."
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "error": {
                    "code": "SERVER_ERROR",
                    "message": "Internal server error."
                  }
                }
              }
            }
          }
        },
        "x-rateLimit": "200 requests / minute per IP (shared across all /api routes)",
        "x-auth": "None"
      }
    },
    "/health/json": {
      "get": {
        "summary": "Get service health",
        "description": "Returns live service health fields. No authentication required. Not subject to the /api rate limit.",
        "responses": {
          "200": {
            "description": "Health state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                },
                "example": {
                  "status": "ok",
                  "service": "Veyra",
                  "discord": true,
                  "database": true,
                  "badge_api": true,
                  "uptime": 184320,
                  "tracked_users": 42,
                  "ws_connections": 7,
                  "timestamp": "2026-09-03T12:00:00.000Z"
                }
              }
            }
          }
        },
        "x-rateLimit": "None",
        "x-auth": "None"
      }
    }
  },
  "components": {
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "INVALID_ID",
                  "BAD_REQUEST",
                  "FORBIDDEN",
                  "USER_NOT_TRACKED",
                  "NOT_FOUND",
                  "RATE_LIMITED",
                  "SERVER_ERROR"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "UserSuccess": {
        "type": "object",
        "required": [
          "success",
          "data"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "data": {
            "$ref": "#/components/schemas/User"
          }
        }
      },
      "User": {
        "type": "object",
        "required": [
          "kv",
          "discord_user",
          "activities",
          "discord_status",
          "listening_to_spotify",
          "guild"
        ],
        "properties": {
          "kv": {
            "type": "object"
          },
          "discord_user": {
            "$ref": "#/components/schemas/DiscordUser"
          },
          "activities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Activity"
            }
          },
          "discord_status": {
            "type": "string",
            "enum": [
              "online",
              "idle",
              "dnd",
              "offline"
            ]
          },
          "active_on_discord_web": {
            "type": "boolean"
          },
          "active_on_discord_desktop": {
            "type": "boolean"
          },
          "active_on_discord_mobile": {
            "type": "boolean"
          },
          "active_on_discord_embedded": {
            "type": "boolean"
          },
          "active_on_discord_vr": {
            "type": "boolean"
          },
          "listening_to_spotify": {
            "type": "boolean"
          },
          "spotify": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Spotify"
              },
              {
                "type": "null"
              }
            ]
          },
          "custom_status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CustomStatus"
              },
              {
                "type": "null"
              }
            ]
          },
          "guild": {
            "$ref": "#/components/schemas/Guild"
          },
          "last_updated": {
            "type": "string",
            "format": "date-time"
          },
          "tracked_since": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DiscordUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "username": {
            "type": "string"
          },
          "global_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "discriminator": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_decoration_data": {
            "type": [
              "object",
              "null"
            ]
          },
          "banner": {
            "type": [
              "string",
              "null"
            ]
          },
          "banner_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "accent_color": {
            "type": [
              "integer",
              "null"
            ]
          },
          "public_flags": {
            "type": "integer"
          },
          "badges": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "primary_guild": {
            "type": [
              "object",
              "null"
            ]
          }
        }
      },
      "Activity": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "type": [
              "integer",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "details": {
            "type": [
              "string",
              "null"
            ]
          },
          "application_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "timestamps": {
            "type": [
              "object",
              "null"
            ]
          },
          "assets": {
            "type": [
              "object",
              "null"
            ]
          },
          "party": {
            "type": [
              "object",
              "null"
            ]
          },
          "sync_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "flags": {
            "type": [
              "integer",
              "null"
            ]
          },
          "created_at": {
            "type": [
              "integer",
              "null"
            ]
          },
          "buttons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Spotify": {
        "type": "object",
        "properties": {
          "track_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "timestamps": {
            "type": "object"
          },
          "song": {
            "type": [
              "string",
              "null"
            ]
          },
          "artist": {
            "type": [
              "string",
              "null"
            ]
          },
          "album": {
            "type": [
              "string",
              "null"
            ]
          },
          "album_art_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "CustomStatus": {
        "type": "object",
        "properties": {
          "text": {
            "type": [
              "string",
              "null"
            ]
          },
          "emoji": {
            "type": [
              "string",
              "null"
            ]
          },
          "emoji_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "emoji_name": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Guild": {
        "type": "object",
        "properties": {
          "id": {
            "type": [
              "string",
              "null"
            ]
          },
          "nickname": {
            "type": [
              "string",
              "null"
            ]
          },
          "joined_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Health": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "degraded"
            ]
          },
          "service": {
            "type": "string"
          },
          "discord": {
            "type": "boolean"
          },
          "database": {
            "type": "boolean"
          },
          "badge_api": {
            "type": "boolean"
          },
          "uptime": {
            "type": "integer"
          },
          "tracked_users": {
            "type": [
              "integer",
              "null"
            ]
          },
          "ws_connections": {
            "type": [
              "integer",
              "null"
            ]
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    "securitySchemes": {}
  }
}
