Submit Form API
Overview
The /v2/submitform endpoint allows game studios to submit in-game forms (like feedback or bug reports) to the Oplix Engine using secure token-based authentication. This endpoint accepts multipart/form-data, allowing submissions to include structured form data, logs, device/game information, a screenshot (either as a file upload or a base64 string), and multiple additional file uploads (like crash logs or save files). Submissions are queued for asynchronous processing.
Note This endpoint utilizes a token exchange mechanism detailed in the authentication flow below.
URL:
- Base Endpoint:
https://backend.oplix.io/api/engine - Endpoint:
POST /v2/submitform - HTTP Method:
POST - Content-Type:
multipart/form-data
Headers:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Authorization: Bearer YOUR_ACCESS_TOKEN
Authorization: Must contain a valid Oplix access token prefixed withBearer.Content-Type: Must bemultipart/form-datato support the mix of text fields and potential file uploads. Ensure you include the correct boundary definition.
In-Game Authentication Flow
Here’s a clear flow you should follow to securely call the POST /v2/submitform endpoint:
1. Obtain Tokens (First Time Auth)
To retrieve your first Access Token and Refresh Token, call:
Endpoint: POST /auth/token
Request Body:
{
"appId": "YOUR_APP_ID",
"clientSecret": "YOUR_CLIENT_SECRET"
}
Response Example:
{
"accessToken": "ACCESS_TOKEN",
"refreshToken": "REFRESH_TOKEN",
"expiresIn": 900
}
Important: Your client secret is a sensitive credential gained in the
Team Settingspage on the Oplix Dashboard. It must be kept secure and never exposed to end users. Each client secret is tied to your team account and can be revoked independently from your app ID if compromised.
2. Check Access Token Validity
Before calling /v2/submitform, ensure your Access Token is still valid:
- Access Token expires in: 15 minutes
- You can check expiry using the
expiresInfield or by storing the expiry timestamp.
3. Refresh Token (When Access Token Expired)
If your Access Token has expired, use your stored Refresh Token to obtain a new one.
Endpoint: POST /auth/refresh
Request Body:
{
"refreshToken": "YOUR_REFRESH_TOKEN"
}
Response Example:
{
"accessToken": "NEW_ACCESS_TOKEN",
"refreshToken": "NEW_REFRESH_TOKEN",
"expiresIn": 900
}
Note: If the Refresh Token has expired (after 7 days) or is invalid, you must go back to Step 1 and re-authenticate. Implement safe retry logic with a max retry limit to prevent infinite loops and a potential IP block for excessive rate limit violations.
4. Make the API Call to Submit the Form
Once you have a valid Access Token, make a POST request to /v2/submitform using multipart/form-data.
HTTP Request Structure:
The request must be structured as multipart/form-data, containing various parts for the text fields and any files being uploaded.
POST /v2/submitform HTTP/1.1
Host: backend.oplix.io
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="appId"
YOUR_APP_ID
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="formData"
{"fields":[{"question":"What is your issue?","response":"Game crashes","exclude":false},{"question":"Email","response":"test@example.com","exclude":true}]}
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="logs"
["Log line 1", "Log line 2"]
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="formDescription"
Bug Report
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="device"
{"os_system":"Windows 11","cpu":"Intel Core i9","graphics_device_name":"NVIDIA RTX 4090","ram":"32GB"}
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="gameInfo"
{"quality_level":"Ultra","resolution":"3840x2160","fps":"120"}
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="templateType"
Bug Report
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="screenshot"; filename="screenshot.png"
Content-Type: image/png
<Binary data for screenshot.png>
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="files"; filename="crashlog.log"
Content-Type: text/plain
<Binary data for crashlog.log>
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="files"; filename="savegame.sav"
Content-Type: application/octet-stream
<Binary data for savegame.sav>
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Form Data Fields:
The following fields should be included as distinct parts in your multipart/form-data request:
Request Fields
| Field Name | Type | Required | Max Size | Notes |
|---|---|---|---|---|
appId | String | Required | — | The unique ID for the application submitting the form |
formData | JSON String | Required | — | Structured form data including questions, responses, and exclude flags |
logs | JSON String / Array | Optional | — | Array of log lines or single string containing log data |
formDescription | String | Required | — | Form category type (e.g., 'Bug Report', 'Feedback') |
device | JSON String | Optional | — | Detailed device info - mandatory fields required for hardware analytics |
gameInfo | JSON String | Optional | — | Game information - mandatory fields required for hardware analytics |
templateType | String | Required | — | Identifier for the form template being used |
screenshot | File / Base64 | Optional | 2MB | Binary file upload (recommended) or base64-encoded data URI string. File upload takes priority if both provided |
files | File Upload(s) | Optional | 2MB each | Up to 10 additional files (logs, save files, crash dumps). 5MB total ingress limit including screenshot |
Token Expiry Summary
- Access token expiration: 15 minutes
- Refresh token expiration: 7 days
Form Data Structure with Exclude Flags:
The formData field should be a JSON string containing an object with a fields array. Each element in the array represents a form question/response and supports an exclude flag. If a question’s response is sensitive or should be excluded from Oplix AI engine processing, set exclude to true.
Example of formData JSON String:
{
"fields": [
{
"question": "What is your issue?",
"response": "The game crashes randomly after level 5.",
"exclude": false
},
{
"question": "What is your email?",
"response": "hello@oplix.io",
"exclude": true
},
{
"question": "Additional comments",
"response": "This started after the latest patch update.",
"exclude": false
}
]
}
exclude: true: This question and response will not be automatically processed by certain AI features but will still be stored and viewable.exclude: false: The question and response will be processed as standard form data.
Device and Game Information Structure:
The device and gameInfo fields should be JSON strings containing key-value pairs. Certain keys are mandatory for hardware analytics (see below).
Example of device JSON String:
{
"os_system": "Windows 10",
"cpu": "Intel i7",
"graphics_device_name": "NVIDIA GTX 1080",
"ram": "16GB",
"storage": "512GB SSD"
}
Example of gameInfo JSON String:
{
"quality_level": "High",
"resolution": "1920x1080",
"fps": "60",
"game_mode": "Multiplayer"
}
Screenshot Handling
The /v2/submitform endpoint supports including one screenshot per submission.
Methods:
- File Upload (Recommended): Include the screenshot as a file part named
screenshotin yourmultipart/form-datarequest. - Base64 String: Include a base64-encoded data URI string as the value for the text field named
screenshot. Example:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA...".
Guidelines:
- Priority: If both a
screenshotfile and ascreenshotbase64 field are sent, the file upload will be prioritized and processed. - Size Limit: Each uploaded file (including the screenshot if sent as a file) has a maximum size limit of 2MB. Base64 strings contribute to the overall field size limit. Exceeding these will result in errors.
- Format: Common image formats like PNG or JPEG only
File Upload Handling
You can attach multiple additional files (up to 10) to your form submission, however the total allowable ingress for this endpoint is 5MB inclusive of the screenshot above.
Guidelines:
- Field Name: Each file must be sent as a file part named
filesin yourmultipart/form-datarequest. - Size Limit: Each individual file must not exceed 2MB.
- Total Files: A maximum of 10 files (in addition to the optional screenshot file) can be uploaded per submission using the
filesfield name. - Content Types: Include the appropriate
Content-Typefor each file (e.g.,text/plain,application/zip,application/octet-stream).
Required Device and Game Information Fields
NOTE - While the device and gameInfo fields allow for custom key-value pairs, certain keys are mandatory within their respective JSON strings to enable hardware analytics functionality in the Oplix Dashboard. These fields must be included with exact key names as specified below.
Mandatory Device Information Fields
The following fields must be included in the device JSON string:
Device Information Fields
| Field Name | Type | Required | Notes |
|---|---|---|---|
cpu | String | Required | CPU model name |
fps | String | Required | Current FPS value |
os_system | String | Required | Operating system version |
device_model | String | Required | Detailed device model |
memory_usage | Number | Required | Current memory usage (e.g., MB or GB as number) |
network_type | String | Required | Network connection type (e.g., 'WiFi', 'Ethernet', 'Cellular') |
battery_level | String | Required | Battery percentage (e.g., '95%') |
battery_status | String | Required | Charging status (e.g., 'Charging', 'Discharging', 'Full') |
device_orientation | String | Required | Device orientation (e.g., 'Landscape', 'Portrait') |
system_memory_size | String | Required | Total system memory (e.g., '16GB') |
graphics_device_name | String | Required | GPU name |
graphics_device_type | String | Required | Graphics API type (e.g., 'Direct3D11', 'Vulkan', 'Metal') |
graphics_memory_size | String | Required | GPU memory size (e.g., '8GB') |
graphics_device_vendor | String | Required | GPU manufacturer (e.g., 'NVIDIA', 'AMD', 'Intel') |
graphics_device_version | String | Required | Graphics driver version |
Mandatory Game Information Fields
The following fields must be included in the gameInfo JSON string:
Game Information Fields
| Field Name | Type | Required | Notes |
|---|---|---|---|
resolution | String | Required | Display resolution (e.g., '1920x1080') |
full_screen | String | Required | Screen mode (e.g., 'True', 'False', 'Borderless') |
render_path | String | Required | Rendering pipeline (e.g., 'Deferred', 'Forward') |
active_scene | String | Required | Current game scene or level name |
game_version | String | Required | Game build version (e.g., '1.2.3', 'Build 456') |
session_time | String | Required | Current session duration (e.g., '0h 15m 30s') |
shader_level | String | Required | Shader complexity level (e.g., 'High', 'SM5') |
quality_level | String | Required | Graphics quality setting (e.g., 'Low', 'Medium', 'High', 'Ultra') |
engine_version | String | Required | Game engine version (e.g., 'Unity 2022.3.1f1', 'Unreal 5.1') |
selected_language | String | Required | Game language selected by player (e.g., 'en', 'fr', 'de') |
player_preferences | String | Required | Any key user preferences as a string (can be JSON stringified if complex) |
Important Notes:
- All specified mandatory fields must be included in your submission’s
deviceandgameInfoJSON strings, even if some values are empty strings or placeholder values (e.g., “N/A”) if not applicable. - The key names must match exactly as shown above (case-sensitive).
- You may include additional custom fields beyond these required ones within the same JSON strings.
- Missing or incorrectly named mandatory fields will result in limited or unavailable functionality in the hardware analytics dashboard.
Response Structure:
The response indicates whether the submission was successfully accepted for processing. It does not wait for file uploads or backend processing to complete.
Success Response (200 OK):
Returned immediately after the submission is successfully added to the processing queue.
{
"message": "Form submitted successfully",
"submissionId": "c65b1ea0-362d-471a-b6e7-c8f853f160ea"
}
message: Confirms the submission was received.submissionId: A unique identifier for this submission, useful for tracking or support purposes.- Note: URLs for uploaded files are not included in this immediate response, as processing happens asynchronously.
Error Responses:
Error Response (401 Unauthorized):
Occurs due to authentication or authorization issues:
- Missing
Authorizationheader. - Invalid token format (e.g., not starting with
Bearer). - Token signature verification failed.
- Access token has expired (requires refresh).
- Token has been revoked.
- Incorrect token type used.
- The
appIdprovided in the body does not exist or is invalid.
{
"error": "Token expired",
"code": "TOKEN_EXPIRED"
}
{
"error": "Invalid token",
"code": "INVALID_TOKEN"
}
{
"error": "Invalid app ID. The specified application could not be found."
// Note: Status code will be 401 for this specific App ID lookup failure
}
Error Response (400 Bad Request):
- Missing required fields like
appId. - Invalid JSON format for
formData,logs,device, orgameInfofields. formDatastructure is invalid (e.g., not parsable into the expected array format).
{
"error": "Missing app_id parameter"
}
{
"error": "Invalid JSON format for field 'formData'"
}
{
"error": "Invalid formData format: Expected an array"
}
Error Response (413 Payload Too Large):
- May occur if the total request size, exceeds server limits. The specific error message might vary based on what limit was hit.
{
"error": "File too large"
}
Error Response (429 Too Many Requests):
- Rate limit exceeded.
{
"error": "Too many requests",
"retryAfter": 58, // Optional: Indicates seconds to wait
"message": "Rate limit exceeded. Please try again later."
}
Error Response (500 Internal Server Error):
- An unexpected error occurred on the server during initial request handling or queueing.
{
"error": "Internal server error during processing"
}
Suggested Player Experience
- Implement robust client-side handling for
multipart/form-datauploads, including progress indicators for larger files (screenshot, additional files). - Consider potential network interruptions or upload failures. Implement retry logic on the client-side if an upload fails before the API call is made, or if the API call itself fails due to network issues.
- Request timeouts should still be considered, especially for players on slower connections uploading large files, even though the server responds quickly. The upload itself still needs to complete.
Additional Information:
- CORS Support: The API includes CORS headers to allow cross-origin requests from web-based game clients.
- App ID Validation: Ensure that the
appIdis valid and corresponds to a registered application associated with your team. - Secret Keys: Revoked client secrets immediately invalidate all associated tokens. Each secret key is uniquely tied to your team within Oplix and can be used with any of your team’s apps.