Backend API Specification¶
This document defines the REST API endpoints used by the Modding SDK (for creators) and the Game Client (for athletes).
🛡️ Security & Mitigation Strategy¶
To protect the platform from abuse, we implement strict security measures for all User Generated Content (UGC).
| Risk | Mitigation Strategy |
|---|---|
| DDoS / Bandwidth Exhaustion | Pre-Signed URLs. Uploads go directly to Cloud Storage (S3), bypassing API servers. |
| Storage Exhaustion | User Quotas. Strict limits per user (e.g., 2GB total). |
| Zip Bombs | Stream Inspection. Validators check uncompressed size before extraction. |
| RCE (Remote Code Execution) | Sandboxing. Validation runs in ephemeral, network-isolated containers. |
| Scraping / Leeching | Guest Rate Limits. Unverified users have strict download caps (e.g., 20 items/day). |
📦 Data Integrity & Versioning¶
To prevent Dependency Rot (where a Playlist breaks because a referenced Song or Skin was deleted or changed), the API enforces strict immutability rules.
1. Immutable Versioning¶
- Policy: Once an asset (Skin, Song, Environment) is published, its binary content (
.pck) is Immutable. It can never be overwritten. - Updates: When a creator updates a mod, the API generates a new version (e.g.,
v2). - References: Playlists and other dependent assets reference specific versions (e.g.,
mod_id@v1). This ensures that even ifv2changes the art style completely, the original playlist usingv1remains visually consistent.
2. Soft Delete Policy¶
- Risk: If a creator deletes a popular Song, every Playlist using that song would break.
- Policy: The API does not support "Hard Deletes" for public content.
- Action: When a creator "deletes" a mod:
- Unlisted: It is removed from Search and the "New Releases" feed.
- Archived: It remains on the CDN.
- Available: Existing playlists referencing the ID can still download and play it.
- Exception: DMCA Takedowns or Illegal Content result in a "Hard Delete" (or replacement with a placeholder), which will break dependencies. This is unavoidable for legal compliance.
🔐 Authentication & Guest Access¶
We support two tiers of access to balance friction vs. security.
- Verified Athlete: Signed in. Full access (Upload, Rate, Sync). High rate limits.
-
Guest Athlete: No account. Read-only access. Strict rate limits.
-
Header:
Authorization: Bearer <token>(Required for ALL requests, including Guests).
Guest Handshake¶
To access the API as a guest, the client must first request a temporary session.
- Endpoint:
POST /api/v1/auth/guest - Body:
{"device_id": "uuid"}(Used for fingerprinting abuse). - Response: Returns a short-lived JWT (e.g., 24 hours) with
scope: guest.
📤 Creator Endpoints (Modding SDK)¶
These endpoints are used by the specialized SDKs (aerobeat-skins-*, aerobeat-avatars-*, etc.) to publish content.
1. Check Quota¶
- Endpoint:
GET /api/v1/user/quota - Response:
used_bytes: Total bytes used by this user.limit_bytes: Maximum allowed storage.remaining_bytes: Available space.
2. Request Upload (Pre-Signed URL)¶
- Endpoint:
POST /api/v1/mods/upload-request - Body:
filename: "my_skin.pck"size_bytes: 10485760checksum: SHA256 hash of the file.type:SKIN(orSONG,COACHING,PLAYLIST,AVATAR,COSMETIC,ENVIRONMENT)
- Response:
upload_url: The S3 Pre-Signed URL (PUT).upload_id: Temporary transaction ID.expires_in: Seconds until URL expires (e.g., 900).
- Errors:
403 Forbidden: User not verified.413 Payload Too Large: File exceeds type limit (e.g., Skin > 50MB).429 Too Many Requests: Rate limit exceeded.507 Insufficient Storage: User quota exceeded.
3. Complete Upload¶
- Endpoint:
POST /api/v1/mods/upload-complete - Body:
upload_id: The ID from step 2.manifest: JSON representation ofAeroModManifest(for indexing).
- Response:
202 Accepted: Validation job queued.mod_id: The permanent ID of the new mod.
4. Check Validation Status¶
- Endpoint:
GET /api/v1/mods/{mod_id}/status - Response:
status:PENDING,VALIDATING,APPROVED,REJECTED.errors: List of validation errors (e.g., "Script detected in resource X").
5. Search Assets (SDK Browser)¶
- Endpoint:
GET /api/v1/assets/search - Query Params:
q: Search query string (Title, Artist, Tag).type:SONG,PLAYLIST(Filter by asset type).page: Pagination cursor.
- Response: JSON list of Asset Summaries (ID, Title, Author, Metadata).
📥 Athlete Endpoints (In-Game Browser)¶
These endpoints are used by the Game Client (aerobeat-assembly-*) to discover and download content.
1. Browse Content¶
- Endpoint:
GET /api/v1/mods - Query Params:
type:SKIN,SONG,ENVIRONMENT,COACHING,PLAYLIST,AVATAR,COSMETICfeature:boxing,flow(Filter by gameplay mode)sort:popular,newest,ratingpage: Pagination cursor.
- Response: JSON list of Mod Summaries (Thumbnail URL, Title, Author).
2. Download Mod¶
- Endpoint:
GET /api/v1/mods/{mod_id}/download - Response:
429 Too Many Requests: Guest quota exceeded (Prompt user to Sign Up).302 Redirect: Redirects to CDN URL (S3/CloudFront) for the.pckfile.- Headers:
Content-Disposition: attachment; filename="mod_id_v1.pck"
3. Sync Library¶
- Endpoint:
GET /api/v1/user/library - Purpose: Returns a list of all mods the user has "subscribed" to, allowing the game to auto-download them on a new device.
💳 Billing & Supporter Endpoints¶
These endpoints handle the "Supporter" status transactions. We use a Merchant of Record (e.g., Stripe) to handle actual credit card processing.
1. Create Checkout Session¶
- Endpoint:
POST /api/v1/billing/checkout - Auth: Verified User Only.
- Body:
tier_id: Enum (1_month,1_year, etc.) matching the pricing plan.
- Response:
checkout_url: The URL to redirect the user's browser to (Stripe Hosted Page).session_id: The transaction ID.
2. Webhook Handler (Server-to-Server)¶
- Endpoint:
POST /api/v1/billing/webhook - Auth: Webhook Signature Verification (Stripe-Signature header).
- Purpose: Receives asynchronous payment confirmation from the provider.
- Action:
- Verifies signature.
- Finds user associated with the session.
- Updates
supporter_expirytimestamp in the database (handling stacking logic).
3. Get Supporter Status¶
- Endpoint:
GET /api/v1/user/status - Auth: Verified User.
- Response:
is_supporter: Boolean.supporter_expiry: ISO 8601 Timestamp (or null).active_perks: List of strings (e.g.,["crew_creation", "extended_history"]).
📊 Sequence Diagrams¶
Guest Download Flow¶
sequenceDiagram
participant Client as Game Client (Guest)
participant API as AeroBeat API
participant DB as Database (Redis)
participant CDN as Cloud Storage (S3)
Note over Client, API: 1. Guest Handshake
Client->>API: POST /api/v1/auth/guest {device_id}
API->>DB: Check Device Fingerprint
DB-->>API: OK (Not Banned)
API-->>Client: 200 OK { token: "guest_jwt" }
Note over Client, API: 2. Download Attempt
Client->>API: GET /api/v1/mods/{id}/download (Auth: guest_jwt)
API->>DB: Check Guest Quota (Rate Limit)
alt Quota Exceeded
DB-->>API: Limit Reached (e.g. 20/20)
API-->>Client: 429 Too Many Requests
Note right of Client: UI Prompts "Sign Up to Continue"
else Quota Available
DB-->>API: OK (Increment Count)
API-->>Client: 302 Redirect (Signed CDN URL)
Client->>CDN: GET /content/{id}.pck
CDN-->>Client: Download Stream
end
🛠️ Client Implementation¶
The Game Client interacts with these endpoints via the aerobeat-tool-api service. This tool handles:
- Authentication: Automatically injects the Bearer Token into headers.
- Resilience: Implements exponential backoff for failed requests (429/5xx).
- Type Safety: Parses JSON responses into strict GDScript Dictionary or Resource objects. ```