Skip to content

Downloads API

The Downloads API allows you to generate secure, time-limited download tokens for plugin files. This is useful for automated deployment pipelines or custom download managers.

Generate Download Token

Create a secure, time-limited token for downloading a plugin.

Endpoint

POST https://store.gamedna.studio/api/downloads/token

Authentication

Authorization: Bearer YOUR_ACCESS_TOKEN

Request

{
"license_id": "lic_abc123",
"product_slug": "online-subsystem-blueprintable",
"version": "3.2.0",
"platform": "Win64"
}

Parameters

ParameterTypeRequiredDescription
license_idstringYour license ID
product_slugstringProduct to download
versionstringSpecific version (default: latest)
platformstringTarget platform (default: all)

Available Platforms

PlatformDescription
Win64Windows 64-bit
MacmacOS (Universal)
LinuxLinux x86_64
AndroidAndroid (ARM64)
iOSiOS
AllAll platforms (default)

Success Response (200 OK)

{
"download_token": "dlt_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"download_url": "https://store.gamedna.studio/api/downloads/dlt_eyJhbGciOiJI...",
"expires_at": "2026-01-22T11:00:00Z",
"file": {
"name": "OnlineSubsystemBlueprintable-3.2.0-Win64.zip",
"size_bytes": 15728640,
"checksum_sha256": "a1b2c3d4e5f6..."
},
"product": {
"name": "Online Subsystem Blueprintable",
"version": "3.2.0"
}
}

Error Responses

License Not Valid (403)

{
"error": {
"code": "LICENSE_NOT_VALID",
"message": "Your license is not valid for downloads.",
"details": {
"reason": "expired",
"expired_at": "2025-12-31T23:59:59Z"
}
}
}

Version Not Found (404)

{
"error": {
"code": "VERSION_NOT_FOUND",
"message": "The requested version is not available.",
"details": {
"requested": "4.0.0",
"available": ["3.2.0", "3.1.0", "3.0.0"]
}
}
}

Download File

Use the generated token to download the plugin file.

Endpoint

GET https://store.gamedna.studio/api/downloads/{download_token}

Response

  • Success (200): Binary file stream with appropriate headers
  • Expired (410): Token has expired
  • Invalid (400): Token is malformed or invalid

Headers on Success

Content-Type: application/zip
Content-Disposition: attachment; filename="OnlineSubsystemBlueprintable-3.2.0-Win64.zip"
Content-Length: 15728640
X-Checksum-SHA256: a1b2c3d4e5f6...

List Available Versions

Get all available versions for a product.

Endpoint

GET https://store.gamedna.studio/api/products/{product_slug}/versions

Authentication

Authorization: Bearer YOUR_ACCESS_TOKEN

Response (200 OK)

{
"product": {
"slug": "online-subsystem-blueprintable",
"name": "Online Subsystem Blueprintable"
},
"versions": [
{
"version": "3.2.0",
"release_date": "2026-01-15T00:00:00Z",
"unreal_versions": ["5.3", "5.4", "5.5"],
"platforms": ["Win64", "Mac", "Linux"],
"changelog": "Added EOS SDK 1.16 support...",
"is_latest": true
},
{
"version": "3.1.0",
"release_date": "2025-12-01T00:00:00Z",
"unreal_versions": ["5.3", "5.4"],
"platforms": ["Win64", "Mac", "Linux"],
"changelog": "Added Nintendo Switch support...",
"is_latest": false
},
{
"version": "3.0.0",
"release_date": "2025-10-15T00:00:00Z",
"unreal_versions": ["5.3", "5.4"],
"platforms": ["Win64", "Mac", "Linux"],
"changelog": "Major rewrite for UE 5.4...",
"is_latest": false
}
]
}

Examples

cURL - Generate Token and Download

Terminal window
# Step 1: Generate download token
TOKEN_RESPONSE=$(curl -s -X POST \
https://store.gamedna.studio/api/downloads/token \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"license_id": "lic_abc123",
"product_slug": "online-subsystem-blueprintable",
"version": "3.2.0",
"platform": "Win64"
}')
# Extract download URL
DOWNLOAD_URL=$(echo $TOKEN_RESPONSE | jq -r '.download_url')
# Step 2: Download file
curl -o plugin.zip "$DOWNLOAD_URL"
# Step 3: Verify checksum
EXPECTED_SHA=$(echo $TOKEN_RESPONSE | jq -r '.file.checksum_sha256')
ACTUAL_SHA=$(shasum -a 256 plugin.zip | cut -d' ' -f1)
if [ "$EXPECTED_SHA" = "$ACTUAL_SHA" ]; then
echo "Download verified successfully!"
else
echo "Checksum mismatch! Download may be corrupted."
fi

JavaScript/TypeScript

interface DownloadToken {
download_token: string;
download_url: string;
expires_at: string;
file: {
name: string;
size_bytes: number;
checksum_sha256: string;
};
}
async function downloadPlugin(
accessToken: string,
licenseId: string,
productSlug: string,
version?: string
): Promise<Blob> {
// Generate token
const tokenResponse = await fetch(
'https://store.gamedna.studio/api/downloads/token',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
license_id: licenseId,
product_slug: productSlug,
version: version || 'latest',
}),
}
);
if (!tokenResponse.ok) {
throw new Error('Failed to generate download token');
}
const tokenData: DownloadToken = await tokenResponse.json();
// Download file
const fileResponse = await fetch(tokenData.download_url);
if (!fileResponse.ok) {
throw new Error('Failed to download file');
}
return fileResponse.blob();
}
// Usage
const pluginFile = await downloadPlugin(
'your-access-token',
'lic_abc123',
'online-subsystem-blueprintable',
'3.2.0'
);
// Save to file (Node.js)
import { writeFileSync } from 'fs';
const buffer = Buffer.from(await pluginFile.arrayBuffer());
writeFileSync('plugin.zip', buffer);

CI/CD Integration (GitHub Actions)

name: Update Plugin
on:
schedule:
- cron: '0 0 * * 1' # Weekly on Monday
jobs:
update-plugin:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download Latest Plugin
env:
GAMEDNA_TOKEN: ${{ secrets.GAMEDNA_ACCESS_TOKEN }}
LICENSE_ID: ${{ secrets.GAMEDNA_LICENSE_ID }}
run: |
# Get download token
RESPONSE=$(curl -s -X POST \
https://store.gamedna.studio/api/downloads/token \
-H "Authorization: Bearer $GAMEDNA_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"license_id\": \"$LICENSE_ID\",
\"product_slug\": \"online-subsystem-blueprintable\",
\"platform\": \"Win64\"
}")
DOWNLOAD_URL=$(echo $RESPONSE | jq -r '.download_url')
FILENAME=$(echo $RESPONSE | jq -r '.file.name')
# Download
curl -o "$FILENAME" "$DOWNLOAD_URL"
# Extract to Plugins folder
unzip -o "$FILENAME" -d Plugins/
- name: Commit Update
run: |
git config user.name github-actions
git config user.email github-actions@github.com
git add Plugins/
git commit -m "Update plugin to latest version" || exit 0
git push

Error Codes

CodeHTTP StatusDescription
LICENSE_NOT_VALID403License expired or suspended
VERSION_NOT_FOUND404Requested version doesn’t exist
PLATFORM_NOT_AVAILABLE404Plugin not available for platform
TOKEN_EXPIRED410Download token has expired
TOKEN_INVALID400Token is malformed
DOWNLOAD_LIMIT_EXCEEDED429Too many downloads

Rate Limits

EndpointLimitWindow
POST /downloads/token30 requests1 hour
GET /downloads/{token}10 requests1 hour
GET /products/*/versions60 requests1 minute