1<!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <!-- Google Tag Manager --> 6
6<script>
vendor: 335 bytes, lines 6-10
6(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 7 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 8 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 9 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 10 })(window,document,'script','dataLayer','
10GTM-NPKKMXK
vendor: 3 bytes, line 10
10');
10</script>
10 11 <!-- End Google Tag Manager --> 12 13 <meta charset="utf-8"> 14 <meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,user-scalable=0" /> 15 16 17 <!-- Meta --> 18 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 19 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 20 21 22 <link rel="shortcut icon" href="favicon.ico"> 23 24 25 <!-- Begin Inspectlet Asynchronous Code --> 26
26<script type="text/javascript"> 27 (function() { 28 window.__insp = window.__insp || []; 29 __insp.push(['wid', 251291645]); 30 var ldinsp = function(){ 31 if(typeof window.__inspld != "undefined") return; window.__inspld = 1; var insp = document.createElement('script'); insp.type = 'text/javascript'; insp.async = true; insp.id = "inspsync"; insp.src = ('https:' == document.location.protocol ? 'https' : 'http') + '://cdn.inspectlet.com/inspectlet.js?wid=251291645&r=' + Math.floor(new Date().getTime()/3600000); var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(insp, x); }; 32 setTimeout(ldinsp, 0); 33 })(); 34 </script>
34 35 <!-- End Inspectlet Asynchronous Code --> 36 37 38 39
39<script src="https://www.shakebug.com/assets/js/html5.js"></script>
39 40 41 42 <link rel="shortcut icon" href="https://www.shakebug.com/assets/images/favicon.ico" type="image/x-icon"> 43 <link href="https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@300;400;600;700;800;900&display=swap" rel="stylesheet"> 44 <link rel="stylesheet" type="text/css" href="https://www.shakebug.com/assets/css/bootstrap.min_old.css"> 45 46 <!-- <link rel="stylesheet" type="text/css" href="https://www.shakebug.com/assets/css/bootstrap-select.css"> --> 47 <link rel="stylesheet" type="text/css" href="https://www.shakebug.com/assets/css/style_new.css"> 48 <link rel="stylesheet" type="text/css" href="https://www.shakebug.com/assets/css/media.css"> 49 <link rel="stylesheet" type="text/css" href="https://www.shakebug.com/assets/css/media_new.css"> 50 <link rel="stylesheet" type="text/css" href="https://www.shakebug.com/assets/css/custom.css"> 51 <link rel="stylesheet" type="text/css" href="https://www.shakebug.com/assets/css/my.css"> 52 <!-- <link rel="stylesheet" type="text/css" href="https://www.shakebug.com/css/font-awesome.min.css"> --> 53 <!--ALL SCRIPT--> 54
54<script src="https://www.shakebug.com/assets/js/jquery-1.11.2.min.js"></script>
54 55 <!--
55<script src="https://www.shakebug.com/assets/js/bootstrap.min.js"></script>
55 --> 56
56<script src="https://www.shakebug.com/assets/js/bootstrap-datepicker.js"></script>
56 57
57<script src="https://www.shakebug.com/assets/js/bootstrap-select.js"></script>
57 58
58<script src="https://www.shakebug.com/assets/js/all-style.js"></script>
58 59 <!--
59<script src="https://www.shakebug.com/assets/js/jquery-3.6.0.min.js"></script>
59 --> 60
60<script src="https://www.shakebug.com/assets/js/jquery.easing.min.js"></script>
60 61
61<script src="https://www.shakebug.com/assets/js/owl.carousel.js"></script>
61 62
62<script src="https://www.shakebug.com/assets/js/TweenMax.min.js"></script>
62 63 64 65 <link rel="stylesheet" href="https://www.shakebug.com/assets/css/atom-one-dark.min.css"> 66 <link rel="stylesheet" href="https://www.shakebug.com/assets/css/simple-lightbox.min.css"> 67 68 <!-- Theme CSS --> 69 <link rel="stylesheet" href="https://www.shakebug.com/assets/css/documentation/theme.css"> 70 71 <style> 72 /* The global `header{margin-top:30px}` (style_new.css) was meant to sit the 73 header below the old promo "topsticky" bar. That bar is gone, and on docs 74 pages the header is position:fixed, so the margin only leaves an empty bar 75 at the very top. Neutralise it here (scoped to docs pages). */ 76 body.docs-page header.fixed-top { margin-top: 0 !important; } 77 </style> 78 79 80 <link rel="stylesheet" type="text/css" href="https://www.shakebug.com/assets/css/documentation/material-icon.css"> 81 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous"> 82 <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'> 83
83<script src="https://www.shakebug.com/assets/plugins/popper.min.js"></script>
83 84
84<script src="https://www.shakebug.com/assets/plugins/bootstrap/js/bootstrap.min.js"></script>
84 85
85<script src="https://www.shakebug.com/assets/plugins/smoothscroll.min.js"></script>
85 86
86<script src="https://www.shakebug.com/assets/plugins/simplelightbox/simple-lightbox.min.js"></script>
86 87
87<script src="https://www.shakebug.com/assets/plugins/gumshoe/gumshoe.polyfills.min.js"></script>
87 88 <!--
88<script src="https://www.shakebug.com/assets/js/documentation/docs.js"></script>
88 --> 89 90 <title>Shakebug API Guide</title> 91 92 93 </head> 94 95 <body class="docs-page"> 96 <!-- Google Tag Manager (noscript) -->
vendor: 70 bytes, lines 96-97
96 97 <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
97GTM-NPKKMXK
vendor: 87 bytes, lines 97-99
97" 98 height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> 99
99<!-- End Google Tag Manager (noscript) --> 100 <!-- cookie --> 101 102 <div class="bottomfixed" id="bottomfixed"> 103 <div class="container"> 104 <p>We use cookies to ensure you get the best user experience on our website.<a href="https://www.shakebug.com/cookie-policy" title="Find out more about cookie policy">Find Out More</a></p> 105 <button onclick="acceptCookieConsent();" class="cbtn">Got It</a> 106 </div> 107 </div> 108 109 <!--
109<script> 110 $(document).ready(function() { 111 $("#elementID").on("click", function(event) { 112 event.preventDefault(); 113 var element = $(this); 114 $("html, body").animate({ 115 scrollTop: element.offset().top, 116 }, 117 1000 118 ); 119 }); 120 }) 121 </script>
121 --> 122
122<script> 123 let cookie_consent = getCookie("shakebug_cookie"); 124 if(cookie_consent != ""){ 125 document.getElementById("bottomfixed").style.display = "none"; 126 }else{ 127 document.getElementById("bottomfixed").style.display = "block"; 128 } 129 // Create cookie 130 function setCookie(cname, cvalue, exdays) { 131 const d = new Date(); 132 d.setTime(d.getTime() + (exdays*24*60*60*1000)); 133 let expires = "expires="+ d.toUTCString(); 134 document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; 135 } 136 137 // Delete cookie 138 function deleteCookie(cname) { 139 const d = new Date(); 140 d.setTime(d.getTime() + (24*60*60*1000)); 141 let expires = "expires="+ d.toUTCString(); 142 document.cookie = cname + "=;" + expires + ";path=/"; 143 } 144 145 // Read cookie 146 function getCookie(cname) { 147 let name = cname + "="; 148 let decodedCookie = decodeURIComponent(document.cookie); 149 let ca = decodedCookie.split(';'); 150 for(let i = 0; i <ca.length; i++) { 151 let c = ca[i]; 152 while (c.charAt(0) == ' ') { 153 c = c.substring(1); 154 } 155 if (c.indexOf(name) == 0) { 156 return c.substring(name.length, c.length); 157 } 158 } 159 return ""; 160 } 161 162 // Set cookie consent 163 function acceptCookieConsent(){ 164 deleteCookie('shakebug_cookie'); 165 setCookie('shakebug_cookie', "www.shakebug.com", 30); 166 document.getElementById("bottomfixed").style.display = "none"; 167 } 168</script>
168 169<!-- START TOP STICKY PART --> 170<!-- <section class="topsticky"> 171 <div class="container"> 172 <div class="sticky"> 173 <p>Join Our Thriving Community on Slack for Cutting-Edge Bug Reporting Insights!<a href="https://discord.gg/e7wAku8e"><img src="https://www.shakebug.com/assets/images/pointing.svg" class="pointerimg" alt=""/>Join Now</a></p> 174 </div> 175 </div> 176</section> --> 177<!-- END TOP STICKY PART --> 178 179<header class="fixed-top"> 180 <div class="logo"><a href="https://www.shakebug.com/"><img src="https://www.shakebug.com/assets/images/logo.png" 181 alt="Shakebug" /></a></div> 182 <div id="mobilemenu"></div> 183 <div class="headright"> 184 <nav class="custnav"> 185 <ul class="menus"> 186 <li><a href="https://www.shakebug.com/how-it-works" class="jump" title="How shakebug works">How It Works</a></li> 187 <li><a href="https://www.shakebug.com/installation" class="jump" title="How to Installation">Installation</a></li> 188 <li><a href="https://www.shakebug.com/pricing" class="jump" title="Pricing">Pricing</a></li> 189 <li><a href="https://www.shakebug.com/api-docs" class="jump" title="API Documentation">API Docs</a></li> 190 <li><a href="https://www.shakebug.com/faqs" class="jump" title="FAQ">FAQ</a></li> 191 <li><a href="https://www.shakebug.com/requestdemo" class="jump" title="Request Demo">Request a Demo</a></li> 192 </ul> 193 </nav> 194 <div class="rheader"> 195 <a href="https://www.shakebug.com/app/login" class="bbtn" title="Login">Log In</a> 196 <a href="https://www.shakebug.com/app/registration" class="cbtn" title="Signup">Sign up free</a> 197 </div> 198 199 </div> 200</header> 201<div class="docs-wrapper"> 202 <div id="docs-sidebar" class="docs-sidebar"> 203 <div class="top-search-box d-lg-none p-3"> 204 205 </div> 206 207 <nav id="docs-nav" class="docs-nav navbar"> 208 <ul class="section-items list-unstyled nav flex-column pb-3" style="padding-top: 20px;"> 209 <li class="nav-item section-title"><a class="nav-link scrollto" href="#section-1">Get Started</a></li> 210 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_api">About the Shakebug API</a></li> 211 212 <li class="nav-item section-title mt-3"><a class="nav-link scrollto" href="#v1.0_oauth_flow">Authentication</a></li> 213 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_oauth_flow">OAuth 2.0 Flow</a></li> 214 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_request-authorization">Authorization Request</a></li> 215 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_exchange-token">Exchange Authorization Code</a></li> 216 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_pat">Personal Access Tokens</a></li> 217 218 <li class="nav-item section-title mt-3"><a class="nav-link scrollto" href="#v1.0_get_project">API Reference</a></li> 219 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_get_project">Get Projects</a></li> 220 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_add_bug">Add Bug</a></li> 221 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_add_attachment">Add Attachment</a></li> 222 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_get_bugs">Get Bugs (list & filters)</a></li> 223 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_get_crashes">Get Crashes</a></li> 224 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_bug_detail">Bug Detail</a></li> 225 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_crash_groups">Crash Groups</a></li> 226 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_analytics_summary">Analytics Summary</a></li> 227 228 <li class="nav-item section-title mt-3"><a class="nav-link scrollto" href="#v1.0_webhook">Webhooks</a></li> 229 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_webhook_prereq">Who am I (/me)</a></li> 230 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_webhook_subscribe">Subscribe to Webhook</a></li> 231 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_webhook_unsubscribe">Unsubscribe from Webhook</a></li> 232 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_webhook_payload">Webhook Payload</a></li> 233 234 <li class="nav-item section-title mt-3"><a class="nav-link scrollto" href="#v1.0_automation">Automation</a></li> 235 <li class="nav-item"><a class="nav-link scrollto" href="#v1.0_automation">Zapier & n8n</a></li> 236 </ul> 237 238 </nav> 239 <!--//docs-nav--> 240 </div> 241 <!--//docs-sidebar--> 242 <div class="docs-content"> 243 <div class="container"> 244 <article class="docs-article" id="section-1"> 245 <header class="docs-header"> 246 <!-- <h1 class="docs-heading">Get Started<span class="docs-time"></span> 247 </h1> --> 248 <section class="docs-intro"> 249 <p> Shakebug is a mobile application bug reporting and feedback platform. It allows mobile app 250 developers to easily gather feedback and bug reports from their testers and users, Also 251 includes a suite of tools for analyzing crash reports. The platform supports iOS, Android 252 and React-Native platforms.</p> 253 254 <p>Some of the features offered by Shakebug:</p> 255 256 <p><strong>Bug Reporting:</strong> Allows users reports bug and crash directly from within the 257 app which include a screenshot, screen recording, and device information.</p> 258 <p><strong>Crash reporting:</strong> Automatically captures and reports crashes as they happen, 259 with detailed stack traces and device information using our AI.</p> 260 <p><strong>User sessions:</strong> Records and replays user sessions to help developers 261 understand how users are interacting with their app.</p> 262 <p><strong>Analytics:</strong> Along with bugs and crash reporting, Shakebug analyzes the 263 application usage in different ways like session, language, countries etc. It also allows 264 users to check analytics in the form of graphical representation over the selection period 265 of time. </p> 266 <p><strong>Events:</strong> Developers can add custom events and values for each action of the 267 application easily where they want. In addition to this, users can also check the session of 268 each event and value in graphical form as well.</p> 269 <p><strong>Integrations:</strong>
269 Shakebug can be integrated with other tools such as Trello, 270 Asana, Slack, Wrike, Monday and Jira to help streamline the workflow for any software 271 company.</p> 272 <p><strong>Collaboration:</strong> Allows team members to communicate and collaborate in 273 real-time through comments and notifications via email.</p> 274 <p><strong>SDK:</strong> Shakebug also provides a SDK that can be integrated with the app, which 275 can be used to enable the above-mentioned features. Once Shakebug is integrated, it can be 276 easily triggered by users by shaking their device, hence the name Shake to send bug report. 277 </p> 278 <p></p> 279 <p>Shakebugâs goal is to provide developers with all the information they need to understand and 280 fix bugs and crashes, it aims to make the debugging process faster and more efficient by 281 providing detailed information and context on the events leading up to the crash.</p> 282 <p></p> 283 284 </section> 285 <div class="version-v1"> 286 <h2 id="v1.0_api" class="docs-heading">API Version v1.0</h2> 287 <!-- <h4 id="v1.0_api">v1.0 API</h4> --> 288 289 <p>Shakebug provides a RESTful API that allows developers to access and manipulate data on the 290 platform, such as adding bug and crashes. The Shakebug API is a powerful tool that can be used 291 to automate and integrate Shakebug with other applications and services, and to build custom 292 tools and integrations.</p> 293 <p>First step is to generate Client ID and Client Secret using next section.</p> 294 295 296 <h4 id="v1.0_manage_api_key">Managing your Client ID and Client Secret</h4> 297 <p>Shakebug uses OAuth 2.0 for authentication. To access the Shakebug API, developers will need to 298 obtain a Client ID and Client Secret. The process of generating these credentials requires 299 several steps:</p> 300 301 302 <p>1. <a href="https://app.shakebug.com/login" target="_blank">Login</a> to your shakebug account. 303 </p> 304 <p>2. Find the "Developer" menu by clicking on user icon on right-top icon.</p> 305 <p>3. Click "CREATE A NEW APP" and create your first app.</p> 306 <p>4. Give appropriate name and redirect URI</p> 307 <p>5. Click Generate</p> 308 <p>6. It will generate your Client ID and Client Secret.</p> 309 310 <p>Save your Client ID and Client Secret in a safe place.</p> 311 <div class="callout-block callout-block-info"> 312 <div class="content"> 313 <h4 class="callout-title"> 314 <span class="callout-icon-holder me-1"> 315 <i class="fas fa-info-circle"></i> 316 </span> 317 Note 318 </h4> 319 <p>These "Client ID" and "Client Secret" will be used for OAuth 2.0 authentication flow. 320 Keep your Client Secret secure and never expose it in client-side code.</p> 321 </div> 322 </div> 323 <h4 id="v1.0_oauth_flow">OAuth 2.0 Flow</h4> 324 <p>To access the Shakebug API, developers will need to use OAuth 2 325 .0 for authentication. OAuth 2.0 is an open standard for token-based authentication and 326 authorization. This method allows your users to grant your application access to their Shakebug 327 accounts, so you can perform actions on their behalf.</p> 328 <p>Here's an overview of the OAuth 2.0 flow:</p> 329 330 <ol> 331 <li>Redirect user to Shakebug authorization server</li> 332 <li>User grants permission to your application</li> 333 <li>Shakebug redirects back to your app with an authorization code</li> 334 <li>Exchange the authorization code for an access token</li> 335 <li>Use the access token to make API requests</li> 336 </ol> 337 <h5 id="v1.0_request-authorization"><strong>Step 1: Authorization Request</strong></h5> 338 <p>Direct the user to the following URL to start the authorization process:</p> 339 340 <div class="docs-code-block"> 341 <pre><code><span id="v1-auth-url">https://app.shakebug.com/v1.0/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&state=RANDOM_STATE&scope=read write</span><button id="v1-copy" class="btn btn-light code-copy"><i class="fa fa-copy"></i></button></code></pre> 342 </div> 343 <p id="v1-toast-body" class="text-muted"></p> 344 345 <div class="table-responsive my-4"> 346 <table class="table table-bordered"> 347 <thead> 348 <tr> 349 <th>PARAMETER</th> 350 <th>REQUIRED</th> 351 <th>DESCRIPTION</th> 352 </tr> 353 </thead> 354 <tbody> 355 <tr> 356 <td><strong>client_id</strong></td> 357 <td>Required</td> 358 <td>The Client ID you obtained from the Developer section in your Shakebug account. 359 </td> 360 </tr> 361 <tr> 362 <td><strong>redirect_uri</strong></td> 363 <td>Required</td> 364 <td>URL where the response will be redirected. Must match the URI registered with 365 your application.</td> 366 </tr> 367 <tr> 368 <td><strong>response_type</strong></td> 369 <td>Required</td> 370 <td>
370Must be set to "code" for authorization code flow.</td> 371 </tr> 372 <tr> 373 <td><strong>state</strong></td> 374 <td>Recommended</td> 375 <td>A random string to prevent CSRF attacks. You should verify this value matches 376 when the user returns.</td> 377 </tr> 378 <tr> 379 <td><strong>scope</strong></td> 380 <td>Optional</td> 381 <td>Space-separated list of scopes. Default: "read write"</td> 382 </tr> 383 </tbody> 384 </table> 385 </div> 386 387 <h5 id="v1.0_exchange-token"><strong>Step 2: Exchange Authorization Code for Access Token</strong></h5> 388 <p>After the user grants permission, they will be redirected to your redirect_uri with an 389 authorization code. Exchange this code for an access token:</p> 390 391 <div class="docs-code-block"> 392 <pre><code class="json hljs"> 393<span class="hljs-attr">POST</span> <span>https://app.shakebug.com/v1.0/authorize/token</span> 394<span class="hljs-attr">Content-Type</span> <span>application/x-www-form-urlencoded</span> 395</code></pre> 396 </div> 397 398 <div class="table-responsive my-4"> 399 <table class="table table-bordered"> 400 <thead> 401 <tr> 402 <th>PARAMETER</th> 403 <th>REQUIRED</th> 404 <th>DESCRIPTION</th> 405 </tr> 406 </thead> 407 <tbody> 408 <tr> 409 <td><strong>grant_type</strong></td> 410 <td>Required</td> 411 <td>Must be "authorization_code"</td> 412 </tr> 413 <tr> 414 <td><strong>code</strong></td> 415 <td>Required</td> 416 <td>The authorization code received from the authorization server</td> 417 </tr> 418 <tr> 419 <td><strong>redirect_uri</strong></td> 420 <td>Required</td> 421 <td>Must match the redirect_uri used in the authorization request</td> 422 </tr> 423 <tr> 424 <td><strong>client_id</strong></td> 425 <td>Required</td> 426 <td>Your application's Client ID</td> 427 </tr> 428 <tr> 429 <td><strong>client_secret</strong></td> 430 <td>Required</td> 431 <td>Your application's Client Secret</td> 432 </tr> 433 </tbody> 434 </table> 435 </div> 436 <div class="docs-code-block"> 437 <pre><code class="php"> 438<button id="token-copy" class="btn btn-light code-copy">Copy</button> 439<span id="token-code"><?php 440 441$curl = curl_init(); 442 443curl_setopt_array($curl, [ 444 CURLOPT_URL => "https://app.shakebug.com/v1.0/authorize/token", 445 CURLOPT_RETURNTRANSFER => true, 446 CURLOPT_ENCODING => "", 447 CURLOPT_MAXREDIRS => 10, 448 CURLOPT_TIMEOUT => 30, 449 CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 450 CURLOPT_CUSTOMREQUEST => "POST", 451 CURLOPT_POSTFIELDS => http_build_query([ 452 'grant_type' => 'authorization_code', 453 'code' => 'YOUR_AUTHORIZATION_CODE', 454 'redirect_uri' => 'YOUR_REDIRECT_URI', 455 'client_id' => 'YOUR_CLIENT_ID', 456 'client_secret' => 'YOUR_CLIENT_SECRET' 457 ]), 458 CURLOPT_HTTPHEADER => [ 459 "Content-Type: application/x-www-form-urlencoded" 460 ], 461]); 462 463$response = curl_exec($curl); 464$err = curl_error($curl); 465curl_close($curl); 466 467if ($err) { 468 echo "cURL Error #:" . $err;
469} else { 470 echo $response; 471} 472 473?></span> 474</code></pre> 475 </div> 476 477 <h5>Token Response</h5> 478 <div class="docs-code-block"> 479 <pre><code class="json hljs">{ 480 "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", 481 "token_type": "Bearer", 482 "expires_in": 3600, 483 "refresh_token": "def502004a8b7e42...", 484 "scope": "read write" 485}</code></pre> 486 </div> 487 488 <h5><strong>Refreshing Access Tokens</strong></h5> 489 <p>When your access token expires, use the refresh token to get a new one:</p> 490 491 <div class="docs-code-block"> 492 <pre><code class="php"> 493<button id="refresh-copy" class="btn btn-light code-copy">Copy</button> 494<span id="refresh-code"><?php 495 496$curl = curl_init(); 497 498curl_setopt_array($curl, [ 499 CURLOPT_URL => "https://app.shakebug.com/v1.0/authorize/token", 500 CURLOPT_RETURNTRANSFER => true, 501 CURLOPT_CUSTOMREQUEST => "POST", 502 CURLOPT_POSTFIELDS => http_build_query([ 503 'grant_type' => 'refresh_token', 504 'refresh_token' => 'YOUR_REFRESH_TOKEN', 505 'client_id' => 'YOUR_CLIENT_ID', 506 'client_secret' => 'YOUR_CLIENT_SECRET' 507 ]), 508 CURLOPT_HTTPHEADER => [ 509 "Content-Type: application/x-www-form-urlencoded" 510 ], 511]); 512 513$response = curl_exec($curl); 514echo $response; 515 516?></span> 517</code></pre> 518 </div> 519 520 <h4 id="v1.0_pat">Personal Access Tokens</h4> 521 <p>For scripts, cron jobs, and automation tools (Zapier, n8n, MCP servers) the interactive 522 OAuth 2.0 flow is often overkill. A <strong>Personal Access Token (PAT)</strong> is a 523 long-lived key tied to your account that you send exactly like an OAuth access token:</p> 524 <div class="docs-code-block"> 525 <pre><code class="json hljs"> 526<span class="hljs-attr">Authorization</span> <span>Bearer skb_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</span> 527</code></pre> 528 </div> 529 <p>Every endpoint in this reference (Projects, Bugs, Crashes, Analytics, Webhooks) accepts a PAT 530 anywhere it accepts an OAuth Bearer token â no code changes needed.</p> 531 <h5>Creating a token</h5> 532 <ol> 533 <li><a href="https://app.shakebug.com/login" target="_blank">Log in</a> to your Shakebug account.</li> 534 <li>Open <strong>Developer â Personal Access Tokens</strong> (<code>app.shakebug.com/shakebug_public_api/tokens</code>).</li> 535 <li>Click <strong>Generate New Token</strong>, give it a name (e.g. "Zapier production"), and copy the token.</li> 536 </ol> 537 <div class="callout-block callout-block-info"> 538 <div class="content"> 539 <h4 class="callout-title"> 540 <span class="callout-icon-holder me-1"><i class="fas fa-info-circle"></i></span> 541 Keep it secret 542 </h4> 543 <p>The token is shown <strong>once</strong> at creation â Shakebug stores only a hash and can 544 never display it again. Treat it like a password; if leaked, revoke it from the same screen 545 and generate a new one. Tokens do not expire but can be revoked at any time.</p> 546 </div> 547 </div> 548 <h5>Example request with a PAT</h5> 549 <div class="docs-code-block"> 550 <pre><code class="php"><?php 551 552$curl = curl_init(); 553curl_setopt_array($curl, [ 554 CURLOPT_URL => "https://app.shakebug.com/v1.0/projects", 555 CURLOPT_RETURNTRANSFER => true, 556 CURLOPT_HTTPHEADER => [ 557 "Authorization: Bearer skb_YOUR_PERSONAL_ACCESS_TOKEN" 558 ], 559]); 560echo curl_exec($curl); 561 562?></code></pre> 563 </div> 564 565 <h4 id="v1.0_get_project">GET Projects (v1.0)</h4> 566 <p>Return list of projects using your access token.</p> 567 <div class="docs-code-block"> 568 <pre><code class="json hljs"> 569<span class="hljs-attr">
569GET</span> <span>https://app.shakebug.com/v1.0/projects</span> 570<span class="hljs-attr">Authorization</span> <span>Bearer YOUR_ACCESS_TOKEN</span> 571</code></pre> 572 </div> 573 574 <div class="docs-code-block"> 575 <pre><code class="php"> 576<button id="v1-project-copy" class="btn btn-light code-copy">Copy</button> 577<span id="v1-project-code"><?php 578 579$curl = curl_init(); 580 581curl_setopt_array($curl, [ 582 CURLOPT_URL => "https://app.shakebug.com/v1.0/projects", 583 CURLOPT_RETURNTRANSFER => true, 584 CURLOPT_ENCODING => "", 585 CURLOPT_MAXREDIRS => 10, 586 CURLOPT_TIMEOUT => 30, 587 CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 588 CURLOPT_CUSTOMREQUEST => "GET", 589 CURLOPT_HTTPHEADER => [ 590 "Authorization: Bearer YOUR_ACCESS_TOKEN" 591 ], 592]); 593 594$response = curl_exec($curl); 595$err = curl_error($curl); 596curl_close($curl); 597 598if ($err) { 599 echo "cURL Error #:" . $err; 600} else { 601 echo $response; 602} 603 604?></span> 605</code></pre> 606 </div> 607 608 <h5>Response</h5> 609 <div class="docs-code-block"> 610<pre><code class="json hljs">{ 611"status": 200, 612"data": { 613 "projects": [ 614 { 615 "id": "ZOqPZJpasBxK5c8MRr5px9rtfg", 616 "name": "test", 617 "platform": "iOS" 618 } 619 ] 620} 621}</code></pre> 622 </div> 623 624 625 <h4 id="v1.0_add_bug">Add Bug (v1.0)</h4> 626 <p>Add bug in specific project.</p> 627 <pre><code class="json hljs"> 628<span class="hljs-attr">POST</span> <span>https://app.shakebug.com/v1.0/bug</span> 629<span class="hljs-attr">Authorization</span> <span>Bearer YOUR_ACCESS_TOKEN</span> 630<span class="hljs-attr">Content-Type</span> <span>application/json</span> 631</code></pre> 632<p><strong>Below are the input parameters to be sent in the request body:</strong></p> 633 634 <div class="table-responsive my-4"> 635 <table class="table table-bordered"> 636 <tbody> 637 <tr> 638 <th class="param-th">PARAMETER</th> 639 <th class="type-th">TYPE</th> 640 <th class="platform-th">PLATFORM</th> 641 <th class="platform-th">REQUIRED</th> 642 <th>DESCRIPTION</th> 643 </tr> 644 645 <tr> 646 <td>project</td> 647 <td>String</td> 648 <td>All</td> 649 <td>Required</td> 650 <td>The ID of the Projet.</td> 651 </tr> 652 <tr> 653 <td>description</td> 654 <td>String</td> 655 <td>All</td> 656 <td>Required</td> 657 <td>The Description of bug.</td> 658 </tr> 659 <tr> 660 <td>bugtypes</td> 661 <td>String</td> 662 <td>All</td> 663 <td>Required</td> 664 <td>Type of bug(either <strong>bug</strong> or <strong>crashed</strong>)</td> 665 </tr> 666 <tr> 667 <td>email</td> 668 <td>String</td> 669 <td>All</td> 670 <td>Optional</td> 671 <td>Email of user that you want attach with this bug.</td> 672 </tr> 673 <tr> 674 <td>batteryLevel</td> 675 <td>String</td> 676 <td>Ios, Android</td> 677 <td>Optional</td> 678 <td>Battery level of device from which bug is reported.</td> 679 </tr> 680 <tr> 681 <td>memory</td> 682 <td>String</td> 683 <td>Ios, Android</td> 684 <td>Optional</td> 685 <td>Memory of device from which bug is reported.</td> 686 </tr> 687 <tr> 688 <td>devicemodel</td> 689 <td>String</td> 690 <td>Ios, Android</td> 691 <td>Optional</td> 692 <td>Device model of device from which bug is reported.</td> 693 </tr> 694 <tr> 695 <td>osversion</td> 696 <td>String</td> 697 <td>Ios, Android</td> 698 <td>Optional</td> 699 <td>Os version of device from which bug is reported.</td> 700 </tr> 701 <tr> 702 <td>internettype</td> 703 <td>String</td> 704 <td>Ios, Android</td> 705 <td>Optional</td> 706 <td>Type of Mobile network.</td> 707 </tr> 708 <tr> 709 <td>browser_name</td> 710 <td>String</td> 711 <td>Web</td> 712 <td>Optional</td> 713 <td>Name of browser from which bug is reported.</td> 714 </tr> 715 <tr> 716 <td>browser_full_version</td> 717 <td>String</td> 718 <td>Web</td> 719 <td>Optional</td> 720 <td>Full version of browser.</td> 721 </tr> 722 <tr> 723 <td>browser_user_agent</td> 724 <td>String</td> 725 <td>Web</td> 726 <td>Optional</td> 727 <td>User agent of browser.</td> 728 </tr> 729 <tr> 730 <td>browser_language</td> 731 <td>String</td> 732 <td>Web</td> 733 <td>Optional</td> 734 <td>Name of browser from which bug is reported.</td> 735 </tr> 736 <tr> 737 <td>browser_platform</td> 738 <td>String</td> 739 <td>Web</td> 740 <td>Optional</td> 741 <td>Browserâs platform.</td> 742 </tr> 743 <tr> 744 <td>browser_height</td> 745 <td>String</td> 746 <td>Web</td> 747 <td>Optional</td> 748 <td>Height of browser.</td> 749 </tr> 750 751 <tr> 752 <td>browser_width</td> 753 <td>String</td> 754 <td>Web</td> 755 <td>Optional</td> 756 <td>Width of browser.</td> 757 </tr> 758 759 <tr> 760 <td>is_web</td> 761 <td>Int</td> 762 <td>ALL</td> 763 <td>Required</td> 764 <td>Possible value 1 or 0. If your projectâs platform is web then value of is_web 765 parameter will be 1 otherwise 0.</td> 766 </tr> 767 </tbody> 768 </table> 769 </div> 770 771 772 <div class="docs-code-block"> 773 <pre class="shadow-lg rounded"><code class="json hljs"> 774 <button id="v1-bug-copy" class="btn btn-light code-copy">Copy</button>
775 <span id="v1-bug-code"> 776<?php 777 778 $curl = curl_init();<br> 779 curl_setopt_array($curl, [ 780 <span class="">CURLOPT_URL => "https://app.shakebug.com/v1.0/bug",</span> 781 <span class="">CURLOPT_RETURNTRANSFER => true,</span> 782 <span class="">CURLOPT_ENCODING => "",</span> 783 <span class="">CURLOPT_MAXREDIRS => 10,</span> 784 <span class="">CURLOPT_TIMEOUT => 30,</span> 785 <span class="">CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,</span> 786 <span class="">CURLOPT_CUSTOMREQUEST => "POST",</span> 787 <span>CURLOPT_POSTFIELDS => "{\n \"project\" : \"YWjbqL7xzhFIVBMYvwMJzR-NaQ\",\n \"description\" : \"test bug\",\n \"bugtypes\" : \"bug\"\n}",</span> 788 <span class="">CURLOPT_HTTPHEADER => [ </span> 789 <span>"Authorization: Bearer <your access token>"</span> 790 <span>"content-type: application/json"</span> 791 <span class="">],</span> 792 ]); 793 <span>$response = curl_exec($curl);</span> 794 <span>$err = curl_error($curl);</span><br> 795 <span>curl_close($curl);</span><br> 796 <span>if ($err) { </span> 797 <span> echo "cURL Error #:" . $err;</span> 798 <span>} else {</span> 799 echo $response; 800 } 801 802 ?> 803 804</code></pre> 805 </div> 806 807 <h5>Response</h5> 808 809 <div class="docs-code-block"> 810 <pre class="shadow-lg rounded"><code class="json hljs"> 811<span>{</span> 812 <span>"status": 200,</span> 813 <span>"data": {</span> 814 <span>"bug_id": "u9mfXevbBDwyYz9zZ0_dKNhmeC1B"</span> 815 <span>}</span> 816<span>}</span> 817 818</code></pre> 819 </div> 820 <h4 id="v1.0_add_attachment"> Add Attachment </h4> 821 <p>If you task need any image or video then after adding bug you need to call following /attachment 822 API.</p> 823 <div class="docs-code-block"> 824 <pre class="shadow-lg rounded"><code class="json hljs"> 825<span class="hljs-attr">POST</span> <span class="">https://app.shakebug.com/v1.0/bug/attachment</span> 826<span class="hljs-attr">Authorization</span> <span class="">Bearer <Your access token></span> 827 828</code></pre> 829 </div> 830 831 832 <br> 833 <p>This request uses multipart/form-data as the content type.</p> 834 835 <div class="table-responsive my-4"> 836 <table class="table table-bordered"> 837 <tbody> 838 839 <tr> 840 <th>PARAMETER</th> 841 <th>TYPE</th> 842 <th>PLATFORM</th> 843 <th>REQUIRED</th> 844 <th>DESCRIPTION</th> 845 </tr> 846 847 848 <tr> 849 <td> bug_id</td> 850 <td>String</td> 851 <td>All</td> 852 <td>Required</td> 853 <td>The id of the bug where the file will be added.</td> 854 </tr> 855 856 <tr> 857 <td>attachment</td> 858 <td>File</td> 859 <td>All</td> 860 <td>Required</td> 861 <td>The file to upload..</td> 862 </tr> 863 864 </tbody> 865 </table> 866 </div> 867 868 <div class="docs-code-block"> 869 <pre class="shadow-lg rounded"><code class="json hljs"> 870 <button id="v1-file-copy" class="btn btn-light code-copy">Copy</button> 871 <span id="v1-file-code"> 872<?php 873 $curl = curl_init();<br> 874 curl_setopt_array($curl, [ 875 <span class="">CURLOPT_URL =>'https://app.shakebug.com/v1.0/bug/attachment',</span> 876 <span class="">CURLOPT_RETURNTRANSFER => true,</span> 877 <span class="">CURLOPT_ENCODING => "",</span> 878 <span class="">CURLOPT_MAXREDIRS => 10,</span> 879 <span class="">CURLOPT_TIMEOUT => 30,</span> 880 <span class="">CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,</span> 881 <span class="">CURLOPT_CUSTOMREQUEST =>
881 "POST",</span> 882 <span>CURLOPT_POSTFIELDS => array('bug_id' => 'Hlmbb7hsmjfBopiS2t9_WWGK2LXu','attachment'=> new CURLFILE('<Your local image path>')),</span> 883 <span class="">CURLOPT_HTTPHEADER => [ </span> 884 <span>"Authorization: Bearer <your access token>"</span> 885 <span class="">],</span> 886 ]); 887 <span>$response = curl_exec($curl);</span> 888 <span>$err = curl_error($curl);</span><br> 889 <span>curl_close($curl);</span><br> 890 <span>if ($err) { </span> 891 <span> echo "cURL Error #:" . $err;</span> 892 <span>} else {</span> 893 echo $response; 894 } 895 896 ?> 897 898</code></pre> 899 </div> 900 <!--//docs-code-block--> 901 <h5>Response</h5> 902 903 <div class="docs-code-block"> 904<pre class="shadow-lg rounded"><code class="json hljs"> 905<span>{</span> 906<span>"status": 200,</span> 907<span>"data": {</span> 908<span>"bug_id": "fcp8ThCjkv3hTE011xvVi0xCAsTfYFLe7kgMEqO2iquyA-PFc_jrOaT0_R8"</span> 909<span>}</span> 910<span>}</span> 911 912</code></pre> 913 </div> 914 915<h4 id="v1.0_get_bugs">Get Bugs (v1.0)</h4> 916<p>Return bugs and/or crashes reported for one of your projects, most recent first, with 917 optional filters. Only records belonging to a project the authenticated user owns are 918 returned. Omit <code>type</code> to get both bugs and crashes in a single list. This is 919 the one list endpoint â <code>getcrash</code> below is simply a shortcut for 920 <code>type=crashed</code>.</p> 921<div class="callout-block callout-block-info"> 922 <div class="content"> 923 <h4 class="callout-title"> 924 <span class="callout-icon-holder me-1"> 925 <i class="fas fa-info-circle"></i> 926 </span> 927 Data retention 928 </h4> 929 <p>Get Bugs (and its <strong>Get Crashes</strong> shortcut) return records only 930 within your plan's data-retention window â older records are not returned by the API, 931 just as they are hidden in the dashboard. For example: 90 days on Standard, 180 days on 932 Premium, and unlimited on Enterprise. The <code>pagination.total</code> count reflects 933 only the records inside that window.</p> 934 </div> 935</div> 936<div class="docs-code-block"> 937 <pre><code class="json hljs"> 938<span class="hljs-attr">GET</span> <span>https://app.shakebug.com/v1.0/bug/getbug?application_id=YOUR_PROJECT_ID&type=bug&status=0&page=1&limit=20</span> 939<span class="hljs-attr">Authorization</span> <span>Bearer YOUR_ACCESS_TOKEN</span> 940</code></pre> 941</div> 942 943<div class="table-responsive my-4"> 944 <table class="table table-bordered"> 945 <thead> 946 <tr> 947 <th>PARAMETER</th> 948 <th>REQUIRED</th> 949 <th>DESCRIPTION</th> 950 </tr> 951 </thead> 952 <tbody> 953 <tr><td><strong>application_id</strong></td><td>Required</td><td>The project ID returned by <code>GET /v1.0/projects</code> (the <code>id</code> field).</td></tr> 954 <tr><td><strong>type</strong></td><td>Optional</td><td><code>bug</code> or <code>crashed</code>. Omit to return both.</td></tr> 955 <tr><td><strong>status</strong></td><td>Optional</td><td>Numeric status: <code>0</code> To-Do, <code>1</code> Completed, <code>2</code> In Progress, <code>3</code> Testing, <code>4</code> Backlog.</td></tr> 956 <tr><td><strong>appversion</strong></td><td>Optional</td><td>Exact app version to filter by.</td></tr> 957 <tr><td><strong>devicemodel</strong></td><td>Optional</td><td>Exact device model to filter by.</td></tr> 958 <tr><td><strong>from</strong></td><td>Optional</td><td>Start date <code>YYYY-MM-DD</code> (inclusive).</td></tr> 959 <tr><td><strong>to</strong></td><td>Optional</td><td>End date <code>YYYY-MM-DD</code> (inclusive).</td></tr> 960 <tr><td><strong>page</strong></td><td>Optional</td><td>Page number (1-based). Defaults to <code>1</code>.</td></tr> 961 <tr><td><strong>limit</strong></td><td>Optional</td><td>Records per page. Defaults to <code>20</code>, maximum <code>100</code>.</td></tr> 962 </tbody> 963 </table> 964</div> 965 966<div class="docs-code-block"> 967 <pre><code class="php"><?php 968 969$curl = curl_init(); 970 971curl_setopt_array($curl, [ 972 CURLOPT_URL => "https://app.shakebug.com/v1.0/bug/getbug?application_id=YOUR_PROJECT_ID&type=bug&page=1&limit=20", 973 CURLOPT_RETURNTRANSFER => true, 974 CURLOPT_CUSTOMREQUEST => "GET", 975 CURLOPT_HTTPHEADER => [ 976 "Authorization: Bearer YOUR_ACCESS_TOKEN" 977 ], 978]); 979 980$response = curl_exec($curl); 981$err = curl_error($curl); 982curl_close($curl); 983 984if ($err) { 985 echo "cURL Error #:" . $err;
986} else { 987 echo $response; 988} 989 990?></code></pre> 991</div> 992 993<h5>Response</h5> 994<p>The <code>records</code> array carries the summary fields below. For the full record of a 995 single bug â reporter email, project context and browser environment â call 996 <a href="#v1.0_bug_detail">Bug Detail</a>.</p> 997<div class="docs-code-block"> 998<pre><code class="json hljs">{ 999 "status": true, 1000 "data": { 1001 "pagination": { "total": 42, "page": 1, "limit": 20, "total_pages": 3 }, 1002 "filters": { "type": "bug", "status": 0, "appversion": null, "devicemodel": null, "from": null, "to": null }, 1003 "count": 20, 1004 "records": [ 1005 { 1006 "id": "u9mfXevbBDwyYz9zZ0_dKNhmeC1B", 1007 "description": "App crashed when submitting form", 1008 "bugtypes": "bug", 1009 "status": "To-Do", 1010 "platform": "Mobile", 1011 "devicemodel": "iPhone 14", 1012 "osversion": "17.2", 1013 "memory": "128MB", 1014 "batteryLevel": "82%", 1015 "internettype": "WiFi", 1016 "appversion": "1.4.0", 1017 "attachment": "https://app.shakebug.com/media/images/bugs/1699999999.png", 1018 "created": "2026-07-06 10:23:00" 1019 } 1020 ] 1021 } 1022}</code></pre> 1023</div> 1024 1025<h4 id="v1.0_get_crashes">Get Crashes (v1.0)</h4> 1026<p>A convenience shortcut for <a href="#v1.0_get_bugs">Get Bugs</a> with <code>type=crashed</code> â 1027 same response shape (including the <code>filters</code> and <code>pagination</code> blocks), 1028 same plan data-retention limits, but always scoped to crashes. The other Get Bugs filters 1029 (<code>status</code>, <code>appversion</code>, <code>devicemodel</code>, <code>from</code>, 1030 <code>to</code>, <code>page</code>, <code>limit</code>) apply here too.</p> 1031<div class="docs-code-block"> 1032 <pre><code class="json hljs"> 1033<span class="hljs-attr">GET</span> <span>https://app.shakebug.com/v1.0/bug/getcrash?application_id=YOUR_PROJECT_ID&page=1&limit=20</span> 1034<span class="hljs-attr">Authorization</span> <span>Bearer YOUR_ACCESS_TOKEN</span> 1035</code></pre> 1036</div> 1037 1038<div class="table-responsive my-4"> 1039 <table class="table table-bordered"> 1040 <thead> 1041 <tr> 1042 <th>PARAMETER</th> 1043 <th>REQUIRED</th> 1044 <th>DESCRIPTION</th> 1045 </tr> 1046 </thead> 1047 <tbody> 1048 <tr> 1049 <td><strong>application_id</strong></td> 1050 <td>Required</td> 1051 <td>The project ID returned by <code>GET /v1.0/projects</code> (the <code>id</code> field).</td> 1052 </tr> 1053 <tr> 1054 <td><strong>page</strong></td> 1055 <td>Optional</td> 1056 <td>Page number to return (1-based). Defaults to <code>1</code>.</td> 1057 </tr> 1058 <tr> 1059 <td><strong>limit</strong></td> 1060 <td>Optional</td> 1061 <td>Records per page. Defaults to <code>20</code>, maximum <code>100</code>.</td> 1062 </tr> 1063 </tbody> 1064 </table> 1065</div> 1066 1067<h5>Response</h5> 1068<div class="docs-code-block"> 1069<pre><code class="json hljs">{ 1070 "status": true, 1071 "data": { 1072 "pagination": { "total": 1, "page": 1, "limit": 20, "total_pages": 1 }, 1073 "filters": { "type": "crashed", "status": null, "appversion": null, "devicemodel": null, "from": null, "to": null }, 1074 "count": 1, 1075 "records": [ 1076 { 1077 "id": "Hlmbb7hsmjfBopiS2t9_WWGK2LXu", 1078 "description": "Fatal: NSInvalidArgumentException", 1079 "bugtypes": "crashed", 1080 "status": "To-Do", 1081 "platform": "Mobile", 1082 "devicemodel": "Pixel 7", 1083 "osversion": "14", 1084 "memory": "256MB", 1085 "batteryLevel": "45%", 1086 "internettype": "4G", 1087 "appversion": "1.4.0", 1088 "attachment": null, 1089 "created": "2026-07-06 09:10:00" 1090 } 1091 ] 1092 } 1093}</code></pre> 1094</div> 1095<h4 id="v1.0_bug_detail">Bug Detail (v1.0)</h4> 1096<p>Return full detail for a single bug or crash by its <code>bug_id</code> (the encrypted 1097 <code>id</code> returned by Get Bugs / Get Crashes / Add Bug). This response is richer than a 1098 Get Bugs list record â it adds the reporter <code>email</code>, project context 1099 (<code>project</code>, <code>project_name</code>) and, for web bugs, the full 1100 <code>browser</code> environment.</p> 1101<div class="docs-code-block"> 1102 <pre><code class="json hljs"> 1103<span class="hljs-attr">
1103GET</span> <span>https://app.shakebug.com/v1.0/bug/detail?bug_id=BUG_ID</span> 1104<span class="hljs-attr">Authorization</span> <span>Bearer YOUR_ACCESS_TOKEN</span> 1105</code></pre> 1106</div> 1107<div class="table-responsive my-4"> 1108 <table class="table table-bordered"> 1109 <thead> 1110 <tr><th>PARAMETER</th><th>REQUIRED</th><th>DESCRIPTION</th></tr> 1111 </thead> 1112 <tbody> 1113 <tr><td><strong>bug_id</strong></td><td>Required</td><td>The encrypted bug ID returned by the list/get endpoints.</td></tr> 1114 </tbody> 1115 </table> 1116</div> 1117<h5>Response</h5> 1118<div class="docs-code-block"> 1119<pre><code class="json hljs">{ 1120 "status": true, 1121 "data": { 1122 "id": "u9mfXevbBDwyYz9zZ0_dKNhmeC1B", 1123 "description": "App crashed when submitting form", 1124 "bugtypes": "bug", 1125 "status": "To-Do", 1126 "platform": "Mobile", 1127 "devicemodel": "iPhone 14", 1128 "osversion": "17.2", 1129 "memory": "128MB", 1130 "batteryLevel": "82%", 1131 "internettype": "WiFi", 1132 "appversion": "1.4.0", 1133 "attachment": "https://app.shakebug.com/media/images/bugs/1699999999.png", 1134 "created": "2026-07-06 10:23:00", 1135 "project": "YWjbqL7xzhFIVBMYvwMJzR-NaQ", 1136 "project_name": "My iOS App", 1137 "email": "[email protected]", 1138 "browser": null 1139 } 1140}</code></pre> 1141</div> 1142 1143<h4 id="v1.0_crash_groups">Crash Groups (v1.0)</h4> 1144<p>Return crashes grouped by their signature (the crash description), most frequent first â 1145 useful for triaging which crash affects the most sessions. Scoped to projects you own and 1146 your plan's retention window, and paginated by group.</p> 1147<div class="docs-code-block"> 1148 <pre><code class="json hljs"> 1149<span class="hljs-attr">GET</span> <span>https://app.shakebug.com/v1.0/crashes/groups?application_id=YOUR_PROJECT_ID&page=1&limit=20</span> 1150<span class="hljs-attr">Authorization</span> <span>Bearer YOUR_ACCESS_TOKEN</span> 1151</code></pre> 1152</div> 1153<div class="table-responsive my-4"> 1154 <table class="table table-bordered"> 1155 <thead> 1156 <tr><th>PARAMETER</th><th>REQUIRED</th><th>DESCRIPTION</th></tr> 1157 </thead> 1158 <tbody> 1159 <tr><td><strong>application_id</strong></td><td>Required</td><td>The project ID from <code>GET /v1.0/projects</code>.</td></tr> 1160 <tr><td><strong>from</strong></td><td>Optional</td><td>Start date <code>YYYY-MM-DD</code> (inclusive).</td></tr> 1161 <tr><td><strong>to</strong></td><td>Optional</td><td>End date <code>YYYY-MM-DD</code> (inclusive).</td></tr> 1162 <tr><td><strong>page</strong></td><td>Optional</td><td>Page number (1-based). Defaults to <code>1</code>.</td></tr> 1163 <tr><td><strong>limit</strong></td><td>Optional</td><td>Groups per page. Defaults to <code>20</code>, maximum <code>100</code>.</td></tr> 1164 </tbody> 1165 </table> 1166</div> 1167<h5>Response</h5> 1168<div class="docs-code-block"> 1169<pre><code class="json hljs">{ 1170 "status": true, 1171 "data": { 1172 "pagination": { "total": 8, "page": 1, "limit": 20, "total_pages": 1 }, 1173 "count": 8, 1174 "groups": [ 1175 { 1176 "signature": "Fatal: NSInvalidArgumentException", 1177 "occurrences": 137, 1178 "affected_versions": 3, 1179 "first_seen": "2026-05-02 08:11:00", 1180 "last_seen": "2026-07-06 09:10:00", 1181 "sample_bug_id": "Hlmbb7hsmjfBopiS2t9_WWGK2LXu" 1182 } 1183 ] 1184 } 1185}</code></pre> 1186</div> 1187 1188<h4 id="v1.0_analytics_summary">Analytics Summary (v1.0)</h4> 1189<p>Return a KPI rollup for a project over your plan's retention window (optionally narrowed by 1190 <code>from</code>/<code>to</code>): bug and crash totals, open vs resolved, status 1191 breakdown, platform split, and top app versions and devices.</p> 1192<div class="docs-code-block"> 1193 <pre><code class="json hljs"> 1194<span class="hljs-attr">GET</span> <span>https://app.shakebug.com/v1.0/analytics/summary?application_id=YOUR_PROJECT_ID</span> 1195<span class="hljs-attr">Authorization</span> <span>Bearer YOUR_ACCESS_TOKEN</span> 1196</code></pre> 1197</div> 1198<div class="table-responsive my-4"> 1199 <table class="table table-bordered"> 1200 <thead> 1201 <tr><th>PARAMETER</th><th>REQUIRED</th><th>DESCRIPTION</th></tr> 1202 </thead> 1203 <tbody> 1204 <tr><td><strong>application_id</strong></td><td>Required</td><td>The project ID from <code>GET /v1.0/projects</code>.</td></tr> 1205 <tr><td><strong>from</strong></td><td>Optional</td><td>Start date <code>YYYY-MM-DD</code> (inclusive).</td></tr> 1206 <tr><td><strong>to</strong></td><td>Optional</td><td>End date <code>YYYY-MM-DD</code> (inclusive).</td></tr> 1207 </tbody> 1208 </table> 1209</div> 1210<h5>Response</h5> 1211<div class="docs-code-block"> 1212<pre><code class="json hljs">{ 1213 "status": true, 1214 "data": { 1215 "project": "YWjbqL7xzhFIVBMYvwMJzR-NaQ", 1216 "period": { "from": null, "to": null, "retention_from": "2026-04-08" }, 1217 "totals": { "bugs": 320, "crashes": 96, "total": 416, "open": 291, "resolved": 125 }, 1218 "by_status": { "To-Do": 210, "In Progress": 44, "Testing": 22, "Backlog": 15, "Completed": 125 }, 1219 "by_platform": { "Web": 40, "Mobile": 376 }, 1220 "top_versions": [ { "appversion": "1.4.0", "count": 180 }, { "appversion": "1.3.2", "count": 96 } ], 1221 "top_devices": [ { "devicemodel": "iPhone 14", "count": 88 }, { "devicemodel": "Pixel 7", "count": 61 } ] 1222 } 1223}</code></pre> 1224</div> 1225</div> 1226<h4 id="v1.0_webhook">Webhook Integration (v1.0)</h4> 1227<p>Webhooks deliver real-time notifications to your server when a bug or crash is reported.
1228 They follow the REST-hook pattern (subscribe â receive events â unsubscribe) and are used 1229 by the built-in Zapier and n8n integrations below. Both <code>subscribe</code> and 1230 <code>unsubscribe</code> are authenticated with your OAuth access token â the account is 1231 derived from the token, so no <code>user_id</code> is needed in the body.</p> 1232 1233<h5 id="v1.0_webhook_prereq">Who am I (optional)</h5> 1234<p>The <code>/v1.0/authorize/me</code> endpoint returns the identity behind an access token. 1235 It is <em>not</em> required to subscribe (the token already identifies you) but is handy for 1236 display in an integration.</p> 1237<div class="docs-code-block"> 1238<pre><code class="json hljs"> 1239<span class="hljs-attr">GET</span> <span class="">https://app.shakebug.com/v1.0/authorize/me</span> 1240<span class="hljs-attr">Authorization</span> <span class="">Bearer <YOUR_ACCESS_TOKEN></span> 1241</code></pre> 1242</div> 1243<div class="docs-code-block"> 1244<pre><code class="json hljs">{ 1245 "status": 200, 1246 "data": { 1247 "user_id": "zKPmYi1ZxOqR5e2nYX9FYKpqw", 1248 "name": "test user", 1249 "email": "[email protected]" 1250 } 1251}</code></pre> 1252</div> 1253 1254<h5 id="v1.0_webhook_subscribe">Subscribe to Webhook</h5> 1255<p>Register a URL to receive events. Returns a subscription <code>id</code> you can store and later 1256 pass to unsubscribe. Subscribing the same URL twice is safe â it returns the existing id.</p> 1257<div class="docs-code-block"> 1258<pre><code class="json hljs"> 1259<span class="hljs-attr">POST</span> <span class="">https://app.shakebug.com/v1.0/webhook/subscribe</span> 1260<span class="hljs-attr">Authorization</span> <span class="">Bearer <YOUR_ACCESS_TOKEN></span> 1261<span class="hljs-attr">Content-Type</span> <span class="">application/json</span> 1262</code></pre> 1263</div> 1264 1265<h6>Request Parameters</h6> 1266<table class="table table-bordered"> 1267<thead> 1268<tr><th>PARAMETER</th><th>TYPE</th><th>REQUIRED</th><th>DESCRIPTION</th></tr> 1269</thead> 1270<tbody> 1271<tr> 1272 <td>hookUrl</td> 1273 <td>String</td> 1274 <td>Yes</td> 1275 <td>The public URL to receive event POSTs. Aliases <code>targetUrl</code> / <code>url</code> are also accepted (for Zapier / n8n).</td> 1276</tr> 1277</tbody> 1278</table> 1279 1280<h6>Example Request</h6> 1281<div class="docs-code-block"> 1282<pre><code class="json hljs">{ 1283 "hookUrl": "https://yourdomain.com/shakebug/webhook" 1284}</code></pre> 1285</div> 1286 1287<h6>Response</h6> 1288<div class="docs-code-block"> 1289<pre><code class="json hljs">{ 1290 "status": 200, 1291 "id": 42, 1292 "message": "Webhook subscribed successfully" 1293}</code></pre> 1294</div> 1295 1296<h5 id="v1.0_webhook_unsubscribe">Unsubscribe from Webhook</h5> 1297<p>Remove a subscription by its <code>id</code> (from subscribe) or by <code>hookUrl</code>.</p> 1298<div class="docs-code-block"> 1299<pre><code class="json hljs"> 1300<span class="hljs-attr">POST</span> <span class="">https://app.shakebug.com/v1.0/webhook/unsubscribe</span> 1301<span class="hljs-attr">Authorization</span> <span class="">Bearer <YOUR_ACCESS_TOKEN></span> 1302<span class="hljs-attr">Content-Type</span> <span class="">application/json</span> 1303</code></pre> 1304</div> 1305 1306<h6>Request Parameters</h6> 1307<table class="table table-bordered"> 1308<thead> 1309<tr><th>PARAMETER</th><th>TYPE</th><th>REQUIRED</th><th>DESCRIPTION</th></tr> 1310</thead> 1311<tbody> 1312<tr><td>id</td><td>Integer</td><td>Conditional</td><td>The subscription id returned by subscribe. Provide this <em>or</em> <code>hookUrl</code>.</td></tr> 1313<tr><td>hookUrl</td><td>String</td><td>Conditional</td><td>The subscribed URL to remove (alias <code>targetUrl</code> / <code>url</code>). Provide this <em>or</em> <code>id</code>.</td></tr> 1314</tbody> 1315</table> 1316 1317<h6>Example Request</h6> 1318<div class="docs-code-block"> 1319<pre><code class="json hljs">{ 1320 "id": 42 1321}</code></pre> 1322</div> 1323 1324<h6>Response</h6> 1325<div class="docs-code-block"> 1326<pre><code class="json hljs">{ 1327 "status": 200, 1328 "message": "Webhook unsubscribed successfully" 1329}</code></pre> 1330</div> 1331 1332<h5 id="v1.0_webhook_payload">Webhook Payload</h5> 1333<p>Once subscribed, Shakebug will send POST requests to your <code>hookUrl</code> whenever a bug or crash is reported. Example payload:</p> 1334<div class="docs-code-block"> 1335<pre><code class="json hljs">{ 1336 "event": "bug_created", 1337 "data": { 1338 "bug_id": "u9mfXevbBDwyYz9zZ0_dKNhmeC1B", 1339 "project": "YWjbqL7xzhFIVBMYvwMJzR-NaQ", 1340 "bugtypes": "bug", 1341 "description": "App crashed when submitting form", 1342 "platform": "Mobile", 1343 "device": "iPhone 14", 1344 "timestamp": "2025-07-14T10:23:00Z" 1345 } 1346}</code></pre> 1347</div> 1348 1349<div class="callout-block callout-block-info"> 1350 <div class="content"> 1351 <h4 class="callout-title">
1352 <span class="callout-icon-holder me-1"> 1353 <i class="fas fa-info-circle"></i> 1354 </span> 1355 Note 1356 </h4> 1357 <p>Ensure your <code>hookUrl</code> endpoint is publicly accessible and returns a <code>200 OK</code> response. Retry logic is not yet implemented, so missed events will not be retried.</p> 1358 </div> 1359</div> 1360 1361<h4 id="v1.0_automation">Automation (Zapier & n8n)</h4> 1362<p>The v1.0 API is designed to work with no-code automation tools. Both Zapier and n8n connect 1363 over OAuth 2.0 (see <a href="#v1.0_oauth_flow">OAuth 2.0 Flow</a>) using the Client ID and 1364 Client Secret from your Developer settings, then use the endpoints on this page.</p> 1365 1366<h5>Trigger â "New Bug or Crash"</h5> 1367<p>Use the webhook (REST-hook) endpoints so automations fire the instant a bug or crash is reported:</p> 1368<ul> 1369 <li><strong>Subscribe</strong>: <code>POST /v1.0/webhook/subscribe</code> with your automation's catch URL â the tool sends this automatically as <code>hookUrl</code> / <code>targetUrl</code>. Store the returned <code>id</code>.</li> 1370 <li><strong>Sample data</strong>: <code>GET /v1.0/webhook/sample_bugs</code> returns a sample event so the tool can map fields.</li> 1371 <li><strong>Unsubscribe</strong>: <code>POST /v1.0/webhook/unsubscribe</code> with that <code>id</code> when the automation is turned off.</li> 1372 <li>Each event is delivered as the <a href="#v1.0_webhook_payload">Webhook Payload</a> (<code>event</code> + <code>data</code>).</li> 1373</ul> 1374<p>Prefer polling? Point the tool at <a href="#v1.0_get_bugs">Get Bugs</a> (newest first, stable 1375 <code>id</code>s for de-duplication) on a schedule instead.</p> 1376 1377<h5>Action â "Create Bug" / "Fetch Data"</h5> 1378<ul> 1379 <li><strong>Create a bug</strong>: <code>POST /v1.0/bug</code> (see <a href="#v1.0_add_bug">Add Bug</a>).</li> 1380 <li><strong>List / filter</strong>: <code>GET /v1.0/bug/getbug</code>, <strong>detail</strong> <code>GET /v1.0/bug/detail</code>, <strong>crash groups</strong> and <strong>analytics</strong> â all usable from an HTTP Request node in n8n or a Zapier action.</li> 1381</ul> 1382 1383<div class="callout-block callout-block-info"> 1384 <div class="content"> 1385 <h4 class="callout-title"> 1386 <span class="callout-icon-holder me-1"><i class="fas fa-info-circle"></i></span> 1387 OpenAPI specification 1388 </h4> 1389 <p>A machine-readable OpenAPI 3.0 description of every v1.0 endpoint is available at 1390 <a href="https://app.shakebug.com/openapi.json" target="_blank">https://app.shakebug.com/openapi.json</a>. 1391 Import it into n8n (HTTP Request â Import cURL / OpenAPI), Postman, or any OpenAPI client to 1392 generate ready-made requests.</p> 1393 </div> 1394</div> 1395 1396 1397 </header> 1398 1399 </div> 1400 1401 </div> 1402</div>
1403<script> 1404/* ====== Define JS Constants ====== */ 1405const sidebarToggler = document.getElementById('mobilemenu'); 1406const sidebar = document.getElementById('docs-sidebar'); 1407const sidebarLinks = document.querySelectorAll('#docs-sidebar .scrollto'); 1408 1409/* ===== Responsive Sidebar ====== */ 1410 1411window.onload = function() { 1412 responsiveSidebar(); 1413}; 1414 1415window.onresize = function() { 1416 responsiveSidebar(); 1417}; 1418 1419 1420function responsiveSidebar() { 1421 let w = window.innerWidth; 1422 if (w >= 1200) { 1423 // if larger 1424 sidebar.classList.remove('sidebar-hidden'); 1425 sidebar.classList.add('sidebar-visible'); 1426 1427 } else { 1428 // if smaller 1429 sidebar.classList.remove('sidebar-visible'); 1430 sidebar.classList.add('sidebar-hidden'); 1431 } 1432}; 1433 1434sidebarToggler.addEventListener('click', () => { 1435 if (sidebar.classList.contains('sidebar-visible')) { 1436 sidebar.classList.remove('sidebar-visible'); 1437 sidebar.classList.add('sidebar-hidden'); 1438 1439 } else { 1440 sidebar.classList.remove('sidebar-hidden'); 1441 sidebar.classList.add('sidebar-visible'); 1442 } 1443}); 1444 1445 1446/* ===== Smooth scrolling ====== */ 1447sidebarLinks.forEach((sidebarLink) => { 1448 1449 sidebarLink.addEventListener('click', (e) => { 1450 1451 e.preventDefault(); 1452 1453 var target = sidebarLink.getAttribute("href").replace('#', ''); 1454 1455 //console.log(target); 1456 1457 document.getElementById(target).scrollIntoView({ 1458 behavior: 'smooth' 1459 }); 1460 1461 1462 //Collapse sidebar after clicking 1463 if (sidebar.classList.contains('sidebar-visible') && window.innerWidth < 1200) { 1464 1465 sidebar.classList.remove('sidebar-visible'); 1466 sidebar.classList.add('sidebar-hidden'); 1467 } 1468 1469 }); 1470 1471}); 1472 1473 1474/* ===== Gumshoe SrollSpy ===== */ 1475// Initialize Gumshoe 1476var spy = new Gumshoe('#docs-nav a', { 1477 offset: 69 //sticky header height 1478}); 1479 1480var lightbox = new SimpleLightbox('.simplelightbox-gallery a', { 1481 /* options */ 1482}); 1483</script>
1483 1484
1485<script> 1486$('#copy').click(function() { 1487 var span_Text = document.getElementById("auth-url").innerText; 1488 1489 var temp = $("<textarea>"); 1490 $("body").append(temp); 1491 temp.val($('#auth-url').text()).select(); 1492 document.execCommand("copy"); 1493 $('#toast-body').show(); 1494 document.getElementById("toast-body").innerHTML = "Key copied!!"; 1495 temp.remove(); 1496}); 1497 1498$('#v1-copy').click(function() { 1499 var span_Text = document.getElementById("v1-auth-url").innerText; 1500 1501 var temp = $("<textarea>"); 1502 $("body").append(temp); 1503 temp.val($('#v1-auth-url').text()).select(); 1504 document.execCommand("copy"); 1505 $('#v1-toast-body').show(); 1506 document.getElementById("v1-toast-body").innerHTML = "Key copied!!"; 1507 temp.remove(); 1508}); 1509 1510$('#project-copy').click(function() { 1511 var span_Text = document.getElementById("project-code").innerText; 1512 1513 var temp = $("<textarea>"); 1514 $("body").append(temp); 1515 temp.val($('#project-code').text()).select(); 1516 document.execCommand("copy"); 1517 // $('#toast-body').show(); 1518 // document.getElementById("toast-body").innerHTML = "Key copied!!"; 1519 temp.remove(); 1520}); 1521$('#v1-project-copy').click(function() { 1522 var span_Text = document.getElementById("v1-project-code").innerText; 1523 1524 var temp = $("<textarea>"); 1525 $("body").append(temp); 1526 temp.val($('#v1-project-code').text()).select(); 1527 document.execCommand("copy"); 1528 // $('#toast-body').show(); 1529 // document.getElementById("toast-body").innerHTML = "Key copied!!"; 1530 temp.remove(); 1531}); 1532 1533$('#v1-bug-copy').click(function() { 1534 var span_Text = document.getElementById("v1-bug-code").innerText; 1535 1536 var temp = $("<textarea>"); 1537 $("body").append(temp); 1538 temp.val($('#v1-bug-code').text()).select(); 1539 document.execCommand("copy"); 1540 // $('#toast-body').show(); 1541 // document.getElementById("toast-body").innerHTML = "Key copied!!"; 1542 temp.remove(); 1543}); 1544 1545$('#file-copy').click(function() { 1546 var span_Text = document.getElementById("file-code").innerText; 1547 1548 var temp = $("<textarea>"); 1549 $("body").append(temp); 1550 temp.val($('#file-code').text()).select(); 1551 document.execCommand("copy"); 1552 // $('#toast-body').show(); 1553 // document.getElementById("toast-body").innerHTML = "Key copied!!"; 1554 temp.remove(); 1555}); 1556$('#v1-file-copy').click(function() { 1557 var span_Text = document.getElementById("v1-file-code").innerText; 1558 1559 var temp = $("<textarea>"); 1560 $("body").append(temp); 1561 temp.val($('#v1-file-code').text()).select(); 1562 document.execCommand("copy"); 1563 // $('#toast-body').show(); 1564 // document.getElementById("toast-body").innerHTML = "Key copied!!"; 1565 temp.remove(); 1566}); 1567</script>
1567 1568</body> 1569 1570</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.