Widget API Reference
The Widget API allows you to submit bug reports programmatically.
Submit Report
Submit a new bug report.
POST /api/widget/submit
Authentication
Provide the API key via query parameter or header:
# Query parameter
POST /api/widget/submit?apiKey=your-api-key
# Header
POST /api/widget/submit
X-Api-Key: your-api-key
Request Body (JSON)
{
"title": "Button not working on checkout page",
"description": "When I click the submit button, nothing happens.",
"priority": "high",
"reporterName": "John Doe",
"reporterEmail": "john@example.com",
"metadata": {
"url": "https://example.com/checkout",
"title": "Checkout - Example Store",
"referrer": "https://example.com/cart",
"browser": {
"name": "Chrome",
"version": "120.0.0",
"userAgent": "Mozilla/5.0..."
},
"device": {
"type": "desktop",
"os": "macOS",
"osVersion": "14.0"
},
"viewport": {
"width": 1920,
"height": 1080,
"devicePixelRatio": 2,
"orientation": "landscape"
},
"timestamp": "2024-01-15T10:30:00.000Z",
"timezone": "America/New_York",
"pageLoadTime": 1234,
"consoleErrors": [
{
"type": "error",
"message": "Uncaught TypeError: Cannot read property 'submit' of null",
"source": "checkout.js",
"line": 42,
"timestamp": "2024-01-15T10:29:55.000Z"
}
]
}
}
Request Body (Multipart Form Data)
For requests with screenshots:
curl -X POST "https://bugs.example.com/api/widget/submit?apiKey=your-api-key" \
-F 'data={"title":"Bug report","description":"Description here","priority":"medium","metadata":{...}}' \
-F "media=@screenshot.png"
Fields
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Report title (4-200 characters) |
description | string | No | Detailed description |
priority | string | No | lowest, low, medium (default), high, highest |
reporterName | string | No | Name of the person reporting |
reporterEmail | string | No | Email of the reporter |
metadata | object | Yes | Browser and page context |
annotations | object | No | Annotation data from the editor |
Metadata Object
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Current page URL |
title | string | No | Page title |
referrer | string | No | Referring page URL |
browser | object | Yes | Browser information |
device | object | Yes | Device information |
viewport | object | Yes | Viewport dimensions |
timestamp | string | Yes | ISO 8601 timestamp |
timezone | string | No | User's timezone |
pageLoadTime | number | No | Page load time in ms |
consoleErrors | array | No | Captured console errors |
Browser Object
| Field | Type | Description |
|---|---|---|
name | string | Browser name (Chrome, Firefox, Safari, etc.) |
version | string | Browser version |
userAgent | string | Full user agent string |
Device Object
| Field | Type | Description |
|---|---|---|
type | string | desktop, tablet, or mobile |
os | string | Operating system name |
osVersion | string | OS version (optional) |
Viewport Object
| Field | Type | Description |
|---|---|---|
width | number | Viewport width in pixels |
height | number | Viewport height in pixels |
devicePixelRatio | number | Device pixel ratio |
orientation | string | landscape or portrait (optional) |
Console Error Object
| Field | Type | Description |
|---|---|---|
type | string | error, warn, or log |
message | string | Error message |
source | string | Source file (optional) |
line | number | Line number (optional) |
timestamp | string | When the error occurred |
Success Response
{
"success": true,
"reportId": "rpt_abc123def456",
"message": "Bug report submitted successfully"
}
Error Responses
401 Unauthorized - Missing or invalid API key:
{
"success": false,
"error": "UNAUTHORIZED",
"message": "API key is required"
}
403 Forbidden - Origin not allowed:
{
"success": false,
"error": "FORBIDDEN",
"message": "Origin not allowed"
}
400 Bad Request - Validation error:
{
"success": false,
"error": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "title",
"message": "Title must be at least 4 characters"
}
]
}
429 Too Many Requests - Rate limited:
{
"success": false,
"error": "RATE_LIMITED",
"message": "Too many requests"
}
Get Widget Configuration
Retrieve widget configuration for a project.
GET /api/widget/config/:apiKey
Parameters
| Parameter | Location | Description |
|---|---|---|
apiKey | path | Project API key |
Success Response
{
"success": true,
"config": {
"projectName": "My Project",
"branding": {},
"brandingPrimaryColor": "#6366f1",
"features": {
"screenshot": true,
"annotation": true,
"attachments": false,
"consoleCapture": true
},
"theme": "auto",
"position": "bottom-right",
"buttonText": null,
"buttonShape": "rectangle",
"buttonIcon": "bug",
"buttonIconSize": 18,
"buttonIconStroke": 2,
"lightButtonColor": "#6366f1",
"lightTextColor": "#ffffff",
"lightButtonHoverColor": "#4f46e5",
"lightTextHoverColor": "#ffffff",
"darkButtonColor": "#818cf8",
"darkTextColor": "#1e1b4b",
"darkButtonHoverColor": "#a5b4fc",
"darkTextHoverColor": "#1e1b4b",
"dialogLightButtonColor": "#ebebeb",
"dialogLightTextColor": "#575757",
"dialogLightButtonHoverColor": "#ebebeb",
"dialogLightTextHoverColor": "#575757",
"dialogDarkButtonColor": "#3c3c3c",
"dialogDarkTextColor": "#c3c3c3",
"dialogDarkButtonHoverColor": "#3c3c3c",
"dialogDarkTextHoverColor": "#c3c3c3",
"enableHoverScaleEffect": true,
"tooltipEnabled": false,
"tooltipText": null,
"captureMethod": "visible",
"useScreenCaptureAPI": false
}
}
Error Response
404 Not Found - Invalid API key:
{
"success": false,
"error": "NOT_FOUND",
"message": "Project not found"
}
Example: Custom Integration
Here's a complete example of submitting a bug report from a custom form:
async function submitBugReport(formData) {
const metadata = {
url: window.location.href,
title: document.title,
referrer: document.referrer,
browser: {
name: getBrowserName(),
version: getBrowserVersion(),
userAgent: navigator.userAgent
},
device: {
type: getDeviceType(),
os: getOS()
},
viewport: {
width: window.innerWidth,
height: window.innerHeight,
devicePixelRatio: window.devicePixelRatio
},
timestamp: new Date().toISOString(),
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
};
const response = await fetch('https://bugs.example.com/api/widget/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'your-api-key'
},
body: JSON.stringify({
title: formData.title,
description: formData.description,
priority: formData.priority || 'medium',
reporterName: formData.name,
reporterEmail: formData.email,
metadata
})
});
const result = await response.json();
if (result.success) {
console.log('Report submitted:', result.reportId);
} else {
console.error('Submission failed:', result.message);
}
return result;
}
With Screenshot Upload
async function submitWithScreenshot(formData, screenshotBlob) {
const metadata = { /* ... same as above ... */ };
const body = new FormData();
body.append('data', JSON.stringify({
title: formData.title,
description: formData.description,
priority: formData.priority || 'medium',
metadata
}));
body.append('media', screenshotBlob, 'screenshot.png');
const response = await fetch(
'https://bugs.example.com/api/widget/submit?apiKey=your-api-key',
{
method: 'POST',
body
}
);
return response.json();
}