Skip to content

Latest commit

 

History

History
4861 lines (4043 loc) · 227 KB

README.md

File metadata and controls

4861 lines (4043 loc) · 227 KB

Dashbaord REST API Documentation

Find all the endpoints, resources and detailed documentation for Measure Dashboard REST APIs.

Contents

Apps

GET /apps/:id/journey

Fetch an app's issue journey map. Filter time range using from & to query string parameters. Filter versions using versions & version_codes query string parameter.

Usage Notes

  • App's UUID must be passed in the URI
  • Accepted query parameters
    • from - ISO8601 timestamp to include crashes after this time.
    • to - ISO8601 timestamp to include crashes before this time.
    • versions - List of comma separated version identifier strings to return only matching crashes.
    • version_codes - List of comma separated version codes to return only matching crashes.
    • bigraph (optional) - Choose journey's directionality. 0 computes a unidirectional graph. Default is 1.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "links": [
        {
          "source": "au.com.shiftyjelly.pocketcasts.ui.MainActivity",
          "target": "au.com.shiftyjelly.pocketcasts.player.view.PlayerContainerFragment",
          "value": 4
        },
        {
          "source": "au.com.shiftyjelly.pocketcasts.ui.MainActivity",
          "target": "au.com.shiftyjelly.pocketcasts.player.view.UpNextFragment",
          "value": 4
        },
        {
          "source": "au.com.shiftyjelly.pocketcasts.ui.MainActivity",
          "target": "au.com.shiftyjelly.pocketcasts.discover.view.DiscoverFragment",
          "value": 4
        },
        {
          "source": "au.com.shiftyjelly.pocketcasts.account.onboarding.OnboardingActivity",
          "target": "au.com.shiftyjelly.pocketcasts.ui.MainActivity",
          "value": 1
        }
      ],
      "nodes": [
        {
          "id": "au.com.shiftyjelly.pocketcasts.ui.MainActivity",
          "issues": {
            "anrs": [],
            "crashes": []
          }
        },
        {
          "id": "au.com.shiftyjelly.pocketcasts.player.view.PlayerContainerFragment",
          "issues": {
            "anrs": [],
            "crashes": []
          }
        },
        {
          "id": "au.com.shiftyjelly.pocketcasts.player.view.UpNextFragment",
          "issues": {
            "anrs": [],
            "crashes": []
          }
        },
        {
          "id": "au.com.shiftyjelly.pocketcasts.discover.view.DiscoverFragment",
          "issues": {
            "anrs": [],
            "crashes": [
              {
                "id": "018f5c68-6fe0-75c9-81ba-b36871c8b5fa",
                "title": "java.lang.IllegalStateException",
                "count": 18
              },
              {
                "id": "018f5c68-b814-739d-bf8f-b8235da0e458",
                "title": "java.lang.IllegalStateException",
                "count": 6
              },
              {
                "id": "018f5c68-cab2-76f4-9404-3d3eb0de83f0",
                "title": "java.lang.IllegalStateException",
                "count": 4
              },
              {
                "id": "018f5c68-d389-732f-882b-8be086c82093",
                "title": "java.lang.IllegalStateException",
                "count": 2
              }
            ]
          }
        },
        {
          "id": "au.com.shiftyjelly.pocketcasts.account.onboarding.OnboardingActivity",
          "issues": {
            "anrs": [],
            "crashes": []
          }
        }
      ],
      "totalIssues": 30
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/metrics

Fetch an app's health metrics. Filter time range using from & to query string parameters. Filter version using versions & version_codes query string parameter.

Usage Notes

  • App's UUID must be passed in the URI.
  • All filters must be passed as query strings.
  • Both version & version_codes should be present if any one of them is present.
  • Number of items in version & version_codes must be same.
  • from & to values must be ISO 8601 UTC strings in milliseconds precision. Example: ?from=2023-11-01T18:30:00.000Z&to=2023-11-08T18:30:00.000Z
  • from & to will default to a last 7 days time range if not supplied.
  • versions can accept multiple version identifiers separated with comma. Only the first version will be used to query at the moment.
  • version_codes can accept multiple version identifiers separated with comma. Only the first version will be used to query at the moment.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • nan can be true if some computed values result in a division by zero error.

  • Response

    Click to expand
    {
      "adoption": {
        "all_versions": 53,
        "selected_version": 23,
        "adoption": 43.4,
        "nan": false
      },
      "anr_free_sessions": {
        "anr_free_sessions": 100,
        "delta": 1,
        "nan": false
      },
      "cold_launch": {
        "delta": 0,
        "nan": true,
        "p95": 0
      },
      "crash_free_sessions": {
        "crash_free_sessions": 0,
        "delta": 1,
        "nan": false
      },
      "hot_launch": {
        "delta": 0,
        "nan": true,
        "p95": 0
      },
      "perceived_anr_free_sessions": {
        "perceived_anr_free_sessions": 100,
        "delta": 1,
        "nan": false
      },
      "perceived_crash_free_sessions": {
        "perceived_crash_free_sessions": 0,
        "delta": 1,
        "nan": false
      },
      "sizes": {
        "average_app_size": 26298701,
        "selected_app_size": 25887094,
        "delta": -411607,
        "nan": false
      },
      "warm_launch": {
        "delta": 0,
        "nan": true,
        "p95": 0
      }
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/filters

Fetch an app's filters.

Usage Notes

  • App's UUID must be passed in the URI
  • Pass crash=1 as query string parameter to only return filters for crashes
  • Pass anr=1 as query string parameter to only return filters for ANRs
  • Pass ud_attr_keys=1 as query string parameter to return user defined attribute keys
  • If no query string parameters are passed, the API computes filters from all events

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "countries": [
        "bogon"
      ],
      "device_manufacturers": [
        "Google"
      ],
      "device_names": [
        "emu64a",
        "emu64a16k"
      ],
      "locales": [
        "en-US"
      ],
      "network_generations": [
        "3g",
        "unknown"
      ],
      "network_providers": [
        "T-Mobile",
        "unknown"
      ],
      "network_types": [
        "cellular",
        "no_network",
        "unknown",
        "wifi"
      ],
      "os_versions": [
        {
          "name": "android",
          "version": "35"
        },
        {
          "name": "android",
          "version": "33"
        }
      ],
      "ud_attrs": {
        "key_types": [
          {
            "key": "username",
            "type": "string"
          },
          {
            "key": "paid_user",
            "type": "bool"
          },
          {
            "key": "credit_balance",
            "type": "int64"
          },
          {
            "key": "latitude",
            "type": "float64"
          }
        ],
        "operator_types": {
          "bool": [
            "eq",
            "neq"
          ],
          "float64": [
            "eq",
            "neq",
            "gt",
            "lt",
            "gte",
            "lte"
          ],
          "int64": [
            "eq",
            "neq",
            "gt",
            "lt",
            "gte",
            "lte"
          ],
          "string": [
            "eq",
            "neq",
            "contains",
            "startsWith"
          ]
        }
      },
      "versions": [
        {
          "code": "800",
          "name": "0.8.0-SNAPSHOT.debug"
        },
        {
          "code": "700",
          "name": "0.7.0-SNAPSHOT.debug"
        },
        {
          "code": "1",
          "name": "1.0"
        }
      ]
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/crashGroups

Fetch an app's crash overview.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from (optional) - Start time boundary for temporal filtering. ISO8601 Datetime string. If not passed, a default value is assumed.
    • to (optional) - End time boundary for temporal filtering. ISO8601 Datetime string. If not passed, a default value is assumed.
    • versions (optional) - List of comma separated version identifier strings to return crash groups that have events matching the version.
    • version_codes (optional) - List of comma separated version codes to return crash groups that have events matching the version code.
    • key_id (optional) - UUID of the last item. Used for keyset based pagination. Should be used along with limit.
    • limit (optional) - Number of items to return. Used for keyset based pagination. Should be used along with key_id. Negative values traverses backward along with limit.
    • filter_short_code (optional) - Code representing combination of filters.
    • ud_expression (optional) - Expression in JSON to filter using user defined attributes.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "meta": {
        "next": false,
        "previous": false
      },
      "results": [
        {
          "id": "01903291-1eb4-7b81-854b-fd9d3bbccb4b",
          "app_id": "fddf4d6d-1df1-45f8-8bc7-9730f2236cb0",
          "name": "[email protected]:118",
          "fingerprint": "c37a8c1cc1c037f9",
          "count": 41,
          "percentage_contribution": 77.35849,
          "created_at": "2024-06-19T22:14:49.77Z",
          "updated_at": "2024-06-19T22:15:25.636Z"
        },
        {
          "id": "01903291-6652-7ecf-9a6d-53ef16b6203a",
          "app_id": "fddf4d6d-1df1-45f8-8bc7-9730f2236cb0",
          "name": "[email protected]:118",
          "fingerprint": "c3ea8c1cc1d033f9",
          "count": 6,
          "percentage_contribution": 11.320755,
          "created_at": "2024-06-19T22:15:08.109Z",
          "updated_at": "2024-06-19T22:15:23.134Z"
        },
        {
          "id": "01903291-7992-7c4f-b98e-6f8e93417695",
          "app_id": "fddf4d6d-1df1-45f8-8bc7-9730f2236cb0",
          "name": "[email protected]:118",
          "fingerprint": "c3faac1cc1c037bb",
          "count": 4,
          "percentage_contribution": 7.5471697,
          "created_at": "2024-06-19T22:15:13.038Z",
          "updated_at": "2024-06-19T22:15:21.224Z"
        },
        {
          "id": "01903291-8379-79ee-8a27-678368a0a5b8",
          "app_id": "fddf4d6d-1df1-45f8-8bc7-9730f2236cb0",
          "name": "[email protected]:118",
          "fingerprint": "c37acc1cc0c037bb",
          "count": 2,
          "percentage_contribution": 3.7735848,
          "created_at": "2024-06-19T22:15:15.573Z",
          "updated_at": "2024-06-19T22:15:19.957Z"
        }
      ]
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/crashGroups/plots/instances

Fetch an app's crash overview instances plot aggregated by date range & version.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from (optional) - Start time boundary for temporal filtering. ISO8601 Datetime string. If not passed, a default value is assumed.
    • to (optional) - End time boundary for temporal filtering. ISO8601 Datetime string. If not passed, a default value is assumed.
    • versions (optional) - List of comma separated version identifier strings to return crash groups that have events matching the version.
    • version_codes (optional) - List of comma separated version codes to return crash groups that have events matching the version code.
    • filter_short_code (optional) - Code representing combination of filters.
    • ud_expression (optional) - Expression in JSON to filter using user defined attributes.
  • Both from and to MUST be present when specifyng date range.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    [
      {
        "id": "7.61 (9400)",
        "data": [
          {
            "crash_free_sessions": 0,
            "datetime": "2024-04-29",
            "instances": 23
          }
        ]
      },
      {
        "id": "7.62 (9223)",
        "data": [
          {
            "crash_free_sessions": 0,
            "datetime": "2024-04-29",
            "instances": 30
          }
        ]
      }
    ]
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/crashGroups/:id/crashes

Fetch an app's crash detail.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from (optional) - ISO8601 timestamp to include crashes after this time.
    • to (optional) - ISO8601 timestamp to include crashes before this time.
    • versions (optional) - List of comma separated version identifier strings to return only matching crashes.
    • version_codes (optional) - List of comma separated version codes to return only matching crashes.
    • countries (optional) - List of comma separated country identifier strings to return only matching crashes.
    • device_names (optional) - List of comma separated device name identifier strings to return only matching crashes.
    • device_manufacturers (optional) - List of comma separated device manufacturer identifier strings to return only matching crashes.
    • locales (optional) - List of comma separated device locale identifier strings to return only matching crashes.
    • network_providers (optional) - List of comma separated network provider identifier strings to return only matching crashes.
    • network_types (optional) - List of comma separated network type identifier strings to return only matching crashes.
    • network_generations (optional) - List of comma separated network generation identifier strings to return only matching crashes.
    • key_id (optional) - UUID of the last item. Used for keyset based pagination. Should be used along with key_timestamp & limit.
    • key_timestamp (optional) - ISO8601 timestamp of the last item. Used for keyset based pagination. Should be used along with key_id & limit.
    • limit (optional) - Number of items to return. Used for keyset based pagination. Should be used along with key_id & key_timestamp.
    • filter_short_code (optional) - Code representing combination of filters.
    • ud_expression (optional) - Expression in JSON to filter using user defined attributes.
  • For multiple comma separated fields, make sure no whitespace characters exist before or after comma.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "meta": {
        "next": false,
        "previous": false
      },
      "results": [
        {
          "id": "d0cae3d6-c42a-4d0c-a35b-df0b5d1435b2",
          "session_id": "f1681cff-4da9-4a33-bb1f-ed5d00b21b90",
          "timestamp": "2024-05-03T23:33:59.724Z",
          "type": "exception",
          "attribute": {
            "installation_id": "ee40eb0e-c579-473d-bc10-557049f51cda",
            "app_version": "1.0",
            "app_build": "1",
            "app_unique_id": "sh.measure.sample",
            "measure_sdk_version": "0.1.0",
            "platform": "android",
            "thread_name": "main",
            "user_id": "",
            "device_name": "emu64a",
            "device_model": "sdk_gphone64_arm64",
            "device_manufacturer": "Google",
            "device_type": "phone",
            "device_is_foldable": true,
            "device_is_physical": false,
            "device_density_dpi": 440,
            "device_width_px": 1080,
            "device_height_px": 2154,
            "device_density": 2.75,
            "device_locale": "en-US",
            "os_name": "android",
            "os_version": "33",
            "network_type": "wifi",
            "network_provider": "",
            "network_generation": "unknown"
          },
          "exception": {
            "title": "[email protected]:29",
            "stacktrace": "java.lang.OutOfMemoryError: Failed to allocate a 104857616 byte allocation with 25165824 free bytes and 87MB until OOM, target footprint 134540152, growth limit 201326592\n\tat sh.measure.sample.ExceptionDemoActivity.onCreate$lambda$2(ExceptionDemoActivity.kt:29)\n\tat sh.measure.sample.ExceptionDemoActivity.$r8$lambda$itIQQMXgA5GFCPpehqNC2ZDufqA\n\tat sh.measure.sample.ExceptionDemoActivity$$ExternalSyntheticLambda3.onClick(D8$$SyntheticClass)\n\tat android.view.View.performClick(View.java:7506)\n\tat com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1218)\n\tat android.view.View.performClickInternal(View.java:7483)\n\tat android.view.View.-$$Nest$mperformClickInternal\n\tat android.view.View$PerformClick.run(View.java:29334)\n\tat android.os.Handler.handleCallback(Handler.java:942)\n\tat android.os.Handler.dispatchMessage(Handler.java:99)\n\tat android.os.Looper.loopOnce(Looper.java:201)\n\tat android.os.Looper.loop(Looper.java:288)\n\tat android.app.ActivityThread.main(ActivityThread.java:7872)\n\tat java.lang.reflect.Method.invoke(Method.java:-2)\n\tat com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)\n\tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)",
            "message": "Failed to allocate a 104857616 byte allocation with 25165824 free bytes and 87MB until OOM, target footprint 134540152, growth limit 201326592"
          },
          "attachments": [
            {
              "id": "ccd173ca-a9de-47ec-998f-0dd2f386ee12",
              "name": "screenshot.png",
              "type": "screenshot",
              "key": "ccd173ca-a9de-47ec-998f-0dd2f386ee12.png",
              "location": "http://localhost:9111/msr-attachments-sandbox/ccd173ca-a9de-47ec-998f-0dd2f386ee12.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minio%2F20240620%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240620T031359Z&X-Amz-Expires=172800&X-Amz-SignedHeaders=host&X-Amz-Signature=9d3e372b98eb55ded8ca88b50edc2975cd77f3b722c357f400cf6d6e9e2d8fbe"
            }
          ],
          "threads": [
            {
              "name": "Thread-2",
              "frames": [
                "java.lang.Thread.sleep(Thread.java:-2)",
                "java.lang.Thread.sleep(Thread.java:450)",
                "java.lang.Thread.sleep(Thread.java:355)",
                "sh.measure.android.anr.ANRWatchDog.run(ANRWatchDog.kt:70)"
              ]
            },
            {
              "name": "LeakCanary-Heap-Dump",
              "frames": [
                "android.os.MessageQueue.nativePollOnce(MessageQueue.java:-2)",
                "android.os.MessageQueue.next(MessageQueue.java:335)",
                "android.os.Looper.loopOnce(Looper.java:161)",
                "android.os.Looper.loop(Looper.java:288)",
                "android.os.HandlerThread.run(HandlerThread.java:67)"
              ]
            },
            {
              "name": "Okio Watchdog",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)",
                "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2211)",
                "okio.AsyncTimeout$Companion.awaitTimeout(AsyncTimeout.kt:370)",
                "okio.AsyncTimeout$Watchdog.run(AsyncTimeout.kt:211)"
              ]
            },
            {
              "name": "FinalizerDaemon",
              "frames": [
                "java.lang.Object.wait(Object.java:-2)",
                "java.lang.Object.wait(Object.java:442)",
                "java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:203)",
                "java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:224)",
                "java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:300)",
                "java.lang.Daemons$Daemon.run(Daemons.java:140)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "ReferenceQueueDaemon",
              "frames": [
                "java.lang.Object.wait(Object.java:-2)",
                "java.lang.Object.wait(Object.java:442)",
                "java.lang.Object.wait(Object.java:568)",
                "java.lang.Daemons$ReferenceQueueDaemon.runInternal(Daemons.java:232)",
                "java.lang.Daemons$Daemon.run(Daemons.java:140)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "msr-ep",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)",
                "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)",
                "java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1176)",
                "java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905)",
                "java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "msr-bg",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)",
                "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)",
                "java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1176)",
                "java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905)",
                "java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "FinalizerWatchdogDaemon",
              "frames": [
                "java.lang.Thread.sleep(Thread.java:-2)",
                "java.lang.Thread.sleep(Thread.java:450)",
                "java.lang.Thread.sleep(Thread.java:355)",
                "java.lang.Daemons$FinalizerWatchdogDaemon.sleepForNanos(Daemons.java:438)",
                "java.lang.Daemons$FinalizerWatchdogDaemon.waitForProgress(Daemons.java:480)",
                "java.lang.Daemons$FinalizerWatchdogDaemon.runInternal(Daemons.java:369)",
                "java.lang.Daemons$Daemon.run(Daemons.java:140)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "msr-ee",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)",
                "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)",
                "java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1176)",
                "java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905)",
                "java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            }
          ]
        }
      ]
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/crashGroups/:id/plots/instances

Fetch an app's crash detail instances aggregrated by date range & version.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from (optional) - ISO8601 timestamp to include crashes after this time.
    • to (optional) - ISO8601 timestamp to include crashes before this time.
    • versions (optional) - List of comma separated version identifier strings to return only matching crashes.
    • version_codes (optional) - List of comma separated version codes to return only matching crashes.
    • countries (optional) - List of comma separated country identifier strings to return only matching crashes.
    • device_names (optional) - List of comma separated device name identifier strings to return only matching crashes.
    • device_manufacturers (optional) - List of comma separated device manufacturer identifier strings to return only matching crashes.
    • locales (optional) - List of comma separated device locale identifier strings to return only matching crashes.
    • network_providers (optional) - List of comma separated network provider identifier strings to return only matching crashes.
    • network_types (optional) - List of comma separated network type identifier strings to return only matching crashes.
    • network_generations (optional) - List of comma separated network generation identifier strings to return only matching crashes.
    • filter_short_code (optional) - Code representing combination of filters.
    • ud_expression (optional) - Expression in JSON to filter using user defined attributes.
  • For multiple comma separated fields, make sure no whitespace characters exist before or after comma.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    [
      {
        "id": "7.61 (9400)",
        "data": [
          {
            "datetime": "2024-04-29",
            "instances": 23
          }
        ]
      },
      {
        "id": "7.62 (9223)",
        "data": [
          {
            "datetime": "2024-04-29",
            "instances": 18
          }
        ]
      }
    ]
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/crashGroups/:id/plots/journey

Fetch an app's crash journey map.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from - ISO8601 timestamp to include crashes after this time.
    • to - ISO8601 timestamp to include crashes before this time.
    • versions (optional) - List of comma separated version identifier strings to return only matching crashes.
    • version_codes (optional) - List of comma separated version codes to return only matching crashes.
    • bigraph - Choose journey's directionality. 0 computes a unidirectional graph. Default is 1.
    • countries (optional) - List of comma separated country identifier strings to return only matching crashes.
    • device_names (optional) - List of comma separated device name identifier strings to return only matching crashes.
    • device_manufacturers (optional) - List of comma separated device manufacturer identifier strings to return only matching crashes.
    • locales (optional) - List of comma separated device locale identifier strings to return only matching crashes.
    • network_providers (optional) - List of comma separated network provider identifier strings to return only matching crashes.
    • network_types (optional) - List of comma separated network type identifier strings to return only matching crashes.
    • network_generations (optional) - List of comma separated network generation identifier strings to return only matching crashes.
  • For multiple comma separated fields, make sure no whitespace characters exist before or after comma.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "links": [
        {
          "source": "sh.measure.sample.ExceptionDemoActivity",
          "target": "sh.measure.sample.OkHttpActivity",
          "value": 6
        },
        {
          "source": "sh.measure.sample.ExceptionDemoActivity",
          "target": "sh.measure.sample.ComposeActivity",
          "value": 5
        },
        {
          "source": "sh.measure.sample.ExceptionDemoActivity",
          "target": "sh.measure.sample.ComposeNavigationActivity",
          "value": 6
        }
      ],
      "nodes": [
        {
          "id": "sh.measure.sample.ExceptionDemoActivity",
          "issues": {
            "crashes": [
              {
                "id": "018fba31-0012-7274-8874-8b062b9f6690",
                "title": "java.lang.IllegalAccessException",
                "count": 7
              }
            ]
          }
        },
        {
          "id": "sh.measure.sample.OkHttpActivity",
          "issues": {
            "crashes": [
              {
                "id": "018fba31-0012-7274-8874-8b062b9f6690",
                "title": "java.lang.IllegalAccessException",
                "count": 1
              }
            ]
          }
        },
        {
          "id": "sh.measure.sample.ComposeActivity",
          "issues": {
            "crashes": []
          }
        },
        {
          "id": "sh.measure.sample.ComposeNavigationActivity",
          "issues": {
            "crashes": [
              {
                "id": "018fba31-0012-7274-8874-8b062b9f6690",
                "title": "java.lang.IllegalAccessException",
                "count": 9
              }
            ]
          }
        }
      ],
      "totalIssues": 17
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/anrGroups

Fetch an app's ANR overview.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from (optional) - Start time boundary for temporal filtering. ISO8601 Datetime string. If not passed, a default value is assumed.
    • to (optional) - End time boundary for temporal filtering. ISO8601 Datetime string. If not passed, a default value is assumed.
    • versions (optional) - List of comma separated version identifier strings to return anr groups that have events matching the version.
    • version_codes (optional) - List of comma separated version codes to return anr groups that have events matching the version code.
    • key_id (optional) - UUID of the last item. Used for keyset based pagination. Should be used along with limit.
    • limit (optional) - Number of items to return. Used for keyset based pagination. Should be used along with key_id. Negative values traverses backward along with limit.
    • filter_short_code (optional) - Code representing combination of filters.
    • ud_expression (optional) - Expression in JSON to filter using user defined attributes.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "meta": {
        "next": false,
        "previous": false
      },
      "results": [
        {
          "id": "01903291-c21a-7e2a-923d-90d3793a8fb0",
          "app_id": "2b7ddad4-40a6-42a7-9e21-a90577e08263",
          "name": "[email protected]:62",
          "fingerprint": "c37ac85cc1d013f9",
          "count": 3,
          "percentage_contribution": 75,
          "created_at": "2024-06-19T22:15:31.608Z",
          "updated_at": "2024-06-19T22:15:34.659Z"
        },
        {
          "id": "01903291-cc74-793b-ba28-842ffecdb774",
          "app_id": "2b7ddad4-40a6-42a7-9e21-a90577e08263",
          "name": "[email protected]:66",
          "fingerprint": "8368c85cc1c013f9",
          "count": 1,
          "percentage_contribution": 25,
          "created_at": "2024-06-19T22:15:34.258Z",
          "updated_at": "2024-06-19T22:15:34.258Z"
        }
      ]
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/anrGroups/plots/instances

Fetch an app's ANR overview instances plot aggregated by date range & version.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from (optional) - Start time boundary for temporal filtering. ISO8601 Datetime string. If not passed, a default value is assumed.
    • to (optional) - End time boundary for temporal filtering. ISO8601 Datetime string. If not passed, a default value is assumed.
    • versions (optional) - List of comma separated version identifier strings to return crash groups that have events matching the version.
    • version_codes (optional) - List of comma separated version codes to return crash groups that have events matching the version code.
    • filter_short_code (optional) - Code representing combination of filters.
    • ud_expression (optional) - Expression in JSON to filter using user defined attributes.
  • Both from and to MUST be present when specifyng date range.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    [
      {
        "id": "7.61 (9400)",
        "data": [
          {
            "anr_free_sessions": 100,
            "datetime": "2024-04-29",
            "instances": 0
          }
        ]
      },
      {
        "id": "7.62 (9223)",
        "data": [
          {
            "anr_free_sessions": 100,
            "datetime": "2024-04-29",
            "instances": 0
          }
        ]
      }
    ]
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/anrGroups/:id/anrs

Fetch an app's ANR detail.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from (optional) - ISO8601 timestamp to include anrs after this time.
    • to (optional) - ISO8601 timestamp to include anrs before this time.
    • versions (optional) - List of comma separated version identifier strings to return only matching anrs.
    • version_codes (optional) - List of comma separated version codes to return only matching anrs.
    • countries (optional) - List of comma separated country identifier strings to return only matching anrs.
    • device_names (optional) - List of comma separated device name identifier strings to return only matching anrs.
    • device_manufacturers (optional) - List of comma separated device manufacturer identifier strings to return only matching anrs.
    • locales (optional) - List of comma separated device locale identifier strings to return only matching anrs.
    • network_providers (optional) - List of comma separated network provider identifier strings to return only matching anrs.
    • network_types (optional) - List of comma separated network type identifier strings to return only matching anrs.
    • network_generations (optional) - List of comma separated network generation identifier strings to return only matching anrs.
    • key_id (optional) - UUID of the last item. Used for keyset based pagination. Should be used along with key_timestamp & limit.
    • key_timestamp (optional) - ISO8601 timestamp of the last item. Used for keyset based pagination. Should be used along with key_id & limit.
    • limit (optional) - Number of items to return. Used for keyset based pagination. Should be used along with key_id & key_timestamp.
    • filter_short_code (optional) - Code representing combination of filters.
    • ud_expression (optional) - Expression in JSON to filter using user defined attributes.
  • For multiple comma separated fields, make sure no whitespace characters exist before or after comma.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "meta": {
        "next": false,
        "previous": false
      },
      "results": [
        {
          "id": "e8f656b5-65c3-46ad-a03d-0ba777cff13f",
          "session_id": "58e94ae9-a084-479f-9049-2c5135f6090f",
          "timestamp": "2024-05-03T23:34:27.578Z",
          "type": "anr",
          "attribute": {
            "installation_id": "ee40eb0e-c579-473d-bc10-557049f51cda",
            "app_version": "1.0",
            "app_build": "1",
            "app_unique_id": "sh.measure.sample",
            "measure_sdk_version": "0.1.0",
            "platform": "android",
            "thread_name": "Thread-2",
            "user_id": "",
            "device_name": "emu64a",
            "device_model": "sdk_gphone64_arm64",
            "device_manufacturer": "Google",
            "device_type": "phone",
            "device_is_foldable": true,
            "device_is_physical": false,
            "device_density_dpi": 440,
            "device_width_px": 1080,
            "device_height_px": 2154,
            "device_density": 2.75,
            "device_locale": "en-US",
            "os_name": "android",
            "os_version": "33",
            "network_type": "wifi",
            "network_provider": "",
            "network_generation": "unknown"
          },
          "anr": {
            "title": "[email protected]:66",
            "stacktrace": "sh.measure.android.anr.AnrError: Application Not Responding for at least 5000 ms.\n\tat sh.measure.sample.ExceptionDemoActivity.deadLock$lambda$10(ExceptionDemoActivity.kt:66)\n\tat sh.measure.sample.ExceptionDemoActivity.$r8$lambda$G4MY09CRhRk9ettfD7HPDD_b1n4\n\tat sh.measure.sample.ExceptionDemoActivity$$ExternalSyntheticLambda0.run(R8$$SyntheticClass)\n\tat android.os.Handler.handleCallback(Handler.java:942)\n\tat android.os.Handler.dispatchMessage(Handler.java:99)\n\tat android.os.Looper.loopOnce(Looper.java:201)\n\tat android.os.Looper.loop(Looper.java:288)\n\tat android.app.ActivityThread.main(ActivityThread.java:7872)\n\tat java.lang.reflect.Method.invoke(Method.java:-2)\n\tat com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)\n\tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)",
            "message": "Application Not Responding for at least 5000 ms."
          },
          "attachments": [
            {
              "id": "63fb0950-faff-4028-bf3d-354559e4e540",
              "name": "screenshot.png",
              "type": "screenshot",
              "key": "63fb0950-faff-4028-bf3d-354559e4e540.png",
              "location": "http://localhost:9111/msr-attachments-sandbox/63fb0950-faff-4028-bf3d-354559e4e540.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minio%2F20240620%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240620T031655Z&X-Amz-Expires=172800&X-Amz-SignedHeaders=host&X-Amz-Signature=c174d870816ed98612760b4cd60252bfb9c7551f800a8fa0fc6e2acd3bffc98c"
            }
          ],
          "threads": [
            {
              "name": "OkHttp TaskRunner",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)",
                "java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)",
                "java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)",
                "java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)",
                "java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "OkHttp TaskRunner",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)",
                "java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)",
                "java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)",
                "java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)",
                "java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "FinalizerWatchdogDaemon",
              "frames": [
                "java.lang.Object.wait(Object.java:-2)",
                "java.lang.Object.wait(Object.java:442)",
                "java.lang.Object.wait(Object.java:568)",
                "java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded(Daemons.java:385)",
                "java.lang.Daemons$FinalizerWatchdogDaemon.runInternal(Daemons.java:365)",
                "java.lang.Daemons$Daemon.run(Daemons.java:140)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "OkHttp Dispatcher",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)",
                "java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)",
                "java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)",
                "java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)",
                "java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "Thread-2",
              "frames": [
                "dalvik.system.VMStack.getThreadStackTrace(VMStack.java:-2)",
                "java.lang.Thread.getStackTrace(Thread.java:1841)",
                "java.lang.Thread.getAllStackTraces(Thread.java:1909)",
                "sh.measure.android.exceptions.ExceptionFactory.createMeasureException(ExceptionFactory.kt:36)",
                "sh.measure.android.anr.AnrCollector.toMeasureException(AnrCollector.kt:41)",
                "sh.measure.android.anr.AnrCollector.onAppNotResponding(AnrCollector.kt:36)",
                "sh.measure.android.anr.ANRWatchDog.run(ANRWatchDog.kt:102)"
              ]
            },
            {
              "name": "OkHttp TaskRunner",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)",
                "java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)",
                "java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)",
                "java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)",
                "java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "Okio Watchdog",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)",
                "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2211)",
                "okio.AsyncTimeout$Companion.awaitTimeout(AsyncTimeout.kt:370)",
                "okio.AsyncTimeout$Watchdog.run(AsyncTimeout.kt:211)"
              ]
            },
            {
              "name": "msr-ep",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)",
                "java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)",
                "java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1176)",
                "java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905)",
                "java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "OkHttp TaskRunner",
              "frames": [
                "jdk.internal.misc.Unsafe.park(Unsafe.java:-2)",
                "java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)",
                "java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)",
                "java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)",
                "java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)",
                "java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            },
            {
              "name": "ConnectivityThread",
              "frames": [
                "android.os.MessageQueue.nativePollOnce(MessageQueue.java:-2)",
                "android.os.MessageQueue.next(MessageQueue.java:335)",
                "android.os.Looper.loopOnce(Looper.java:161)",
                "android.os.Looper.loop(Looper.java:288)",
                "android.os.HandlerThread.run(HandlerThread.java:67)"
              ]
            },
            {
              "name": "OkHttp TaskRunner",
              "frames": [
                "java.lang.Object.wait(Object.java:-2)",
                "okhttp3.internal.concurrent.TaskRunner$RealBackend.coordinatorWait(TaskRunner.kt:294)",
                "okhttp3.internal.concurrent.TaskRunner.awaitTaskToRun(TaskRunner.kt:218)",
                "okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.kt:59)",
                "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)",
                "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)",
                "java.lang.Thread.run(Thread.java:1012)"
              ]
            }
          ]
        }
      ]
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/anrGroups/:id/plots/instances

Fetch an app's ANR detail instances aggregated by date range & version.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from (optional) - ISO8601 timestamp to include crashes after this time.
    • to (optional) - ISO8601 timestamp to include crashes before this time.
    • versions (optional) - List of comma separated version identifier strings to return only matching crashes.
    • version_codes (optional) - List of comma separated version codes to return only matching crashes.
    • countries (optional) - List of comma separated country identifier strings to return only matching crashes.
    • device_names (optional) - List of comma separated device name identifier strings to return only matching crashes.
    • device_manufacturers (optional) - List of comma separated device manufacturer identifier strings to return only matching crashes.
    • locales (optional) - List of comma separated device locale identifier strings to return only matching crashes.
    • network_providers (optional) - List of comma separated network provider identifier strings to return only matching crashes.
    • network_types (optional) - List of comma separated network type identifier strings to return only matching crashes.
    • network_generations (optional) - List of comma separated network generation identifier strings to return only matching crashes.
    • filter_short_code (optional) - Code representing combination of filters.
    • ud_expression (optional) - Expression in JSON to filter using user defined attributes.
  • For multiple comma separated fields, make sure no whitespace characters exist before or after comma.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    [
      {
        "id": "1.0 (1)",
        "data": [
          {
            "datetime": "2024-05-03",
            "instances": 1
          }
        ]
      }
    ]
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/anrGroups/:id/plots/journey

Fetch an app's ANR journey map.

Usage Notes

  • App's UUID must be passed in the URI
  • Both version & version_codes should be present if any one of them is present.
  • Accepted query parameters
    • from - ISO8601 timestamp to include crashes after this time.
    • to - ISO8601 timestamp to include crashes before this time.
    • versions (optional) - List of comma separated version identifier strings to return only matching crashes.
    • version_codes (optional) - List of comma separated version codes to return only matching crashes.
    • bigraph - Choose journey's directionality. 0 computes a unidirectional graph. Default is 1.
    • countries (optional) - List of comma separated country identifier strings to return only matching crashes.
    • device_names (optional) - List of comma separated device name identifier strings to return only matching crashes.
    • device_manufacturers (optional) - List of comma separated device manufacturer identifier strings to return only matching crashes.
    • locales (optional) - List of comma separated device locale identifier strings to return only matching crashes.
    • network_providers (optional) - List of comma separated network provider identifier strings to return only matching crashes.
    • network_types (optional) - List of comma separated network type identifier strings to return only matching crashes.
    • network_generations (optional) - List of comma separated network generation identifier strings to return only matching crashes.
  • For multiple comma separated fields, make sure no whitespace characters exist before or after comma.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "links": [
        {
          "source": "sh.measure.sample.ExceptionDemoActivity",
          "target": "sh.measure.sample.ComposeActivity",
          "value": 5
        },
        {
          "source": "sh.measure.sample.ExceptionDemoActivity",
          "target": "sh.measure.sample.ComposeNavigationActivity",
          "value": 6
        },
        {
          "source": "sh.measure.sample.ExceptionDemoActivity",
          "target": "sh.measure.sample.OkHttpActivity",
          "value": 6
        },
        {
          "source": "sh.measure.sample.OkHttpActivity",
          "target": "sh.measure.sample.ExceptionDemoActivity",
          "value": 5
        },
        {
          "source": "sh.measure.sample.ComposeActivity",
          "target": "sh.measure.sample.ExceptionDemoActivity",
          "value": 5
        },
        {
          "source": "sh.measure.sample.ComposeNavigationActivity",
          "target": "sh.measure.sample.ExceptionDemoActivity",
          "value": 6
        }
      ],
      "nodes": [
        {
          "id": "sh.measure.sample.ExceptionDemoActivity",
          "issues": {
            "anrs": [
              {
                "id": "018fba31-057c-70db-83c5-a7fa3c27f3f5",
                "title": "sh.measure.android.anr.AnrError",
                "count": 1
              }
            ]
          }
        },
        {
          "id": "sh.measure.sample.OkHttpActivity",
          "issues": {
            "anrs": []
          }
        },
        {
          "id": "sh.measure.sample.ComposeActivity",
          "issues": {
            "anrs": []
          }
        },
        {
          "id": "sh.measure.sample.ComposeNavigationActivity",
          "issues": {
            "anrs": [
              {
                "id": "018fba31-057c-70db-83c5-a7fa3c27f3f5",
                "title": "sh.measure.android.anr.AnrError",
                "count": 1
              }
            ]
          }
        }
      ],
      "totalIssues": 2
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/sessions

Fetch an app's sessions by applying various optional filters.

Usage Notes

  • App's UUID must be passed in the URI
  • Accepted query parameters
    • from (optional) - ISO8601 timestamp to include sessions after this time.
    • to (optional) - ISO8601 timestamp to include sessions before this time.
    • versions (optional) - List of comma separated version identifier strings to return only matching sessions.
    • version_codes (optional) - List of comma separated version codes to return only matching sessions.
    • crash (optional) - Boolean true/false to control if only sessions containing at least 1 crash should be fetched.
    • anr (optional) - Boolean true/false to control if only sessions containing at least 1 ANR should be fetched.
    • countries (optional) - List of comma separated country identifier strings to return only matching sessions.
    • device_names (optional) - List of comma separated device name identifier strings to return only matching sessions.
    • device_manufacturers (optional) - List of comma separated device manufacturer identifier strings to return only matching sessions.
    • locales (optional) - List of comma separated device locale identifier strings to return only matching sessions.
    • network_providers (optional) - List of comma separated network provider identifier strings to return only matching sessions.
    • network_types (optional) - List of comma separated network type identifier strings to return only matching sessions.
    • network_generations (optional) - List of comma separated network generation identifier strings to return only matching sessions.
    • free_text (optional) - A sequence of characters used to filter sessions matching various criteria like user_id, even type, exception message and so on.
    • offset (optional) - Number of items to skip when paginating. Use with limit parameter to control amount of items fetched.
    • limit (optional) - Number of items to return. Used for pagination. Should be used along with offset.
    • filter_short_code (optional) - Code representing combination of filters.
    • ud_expression (optional) - Expression in JSON to filter using user defined attributes.
  • For multiple comma separated fields, make sure no whitespace characters exist before or after comma.
  • Pass limit and offset values to paginate results

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "meta": {
        "next": true,
        "previous": false
      },
      "results": [
        {
          "session_id": "295842e1-7cd9-4ca3-8545-d6a5b36be9a4",
          "app_id": "36e1b948-3a0a-4e71-80f3-625e61d6c832",
          "attribute": {
            "installation_id": "00000000-0000-0000-0000-000000000000",
            "app_version": "0.8.0-SNAPSHOT.debug",
            "app_build": "800",
            "app_unique_id": "",
            "measure_sdk_version": "",
            "platform": "",
            "thread_name": "",
            "user_id": "",
            "device_name": "emu64a16k",
            "device_model": "sdk_gphone16k_arm64",
            "device_manufacturer": "Google",
            "device_type": "",
            "device_is_foldable": false,
            "device_is_physical": false,
            "device_density_dpi": 0,
            "device_width_px": 0,
            "device_height_px": 0,
            "device_density": 0,
            "device_locale": "",
            "os_name": "android",
            "os_version": "35",
            "os_page_size": 0,
            "network_type": "",
            "network_provider": "",
            "network_generation": ""
          },
          "events": null,
          "first_event_time": "2024-10-26T05:52:43.104Z",
          "last_event_time": "2024-10-26T05:53:58.596Z",
          "duration": 75492,
          "matched_free_text": ""
        },
        {
          "session_id": "2cc9ffd2-9f9d-40a7-9f55-d802a460507a",
          "app_id": "36e1b948-3a0a-4e71-80f3-625e61d6c832",
          "attribute": {
            "installation_id": "00000000-0000-0000-0000-000000000000",
            "app_version": "0.8.0-SNAPSHOT.debug",
            "app_build": "800",
            "app_unique_id": "",
            "measure_sdk_version": "",
            "platform": "",
            "thread_name": "",
            "user_id": "",
            "device_name": "emu64a",
            "device_model": "sdk_gphone64_arm64",
            "device_manufacturer": "Google",
            "device_type": "",
            "device_is_foldable": false,
            "device_is_physical": false,
            "device_density_dpi": 0,
            "device_width_px": 0,
            "device_height_px": 0,
            "device_density": 0,
            "device_locale": "",
            "os_name": "android",
            "os_version": "33",
            "os_page_size": 0,
            "network_type": "",
            "network_provider": "",
            "network_generation": ""
          },
          "events": null,
          "first_event_time": "2024-10-02T18:26:58.226Z",
          "last_event_time": "2024-10-02T18:27:09.151Z",
          "duration": 10925,
          "matched_free_text": ""
        },
        {
          "session_id": "1152c238-4583-49b7-93fa-0c73d6a3d5b1",
          "app_id": "36e1b948-3a0a-4e71-80f3-625e61d6c832",
          "attribute": {
            "installation_id": "00000000-0000-0000-0000-000000000000",
            "app_version": "0.8.0-SNAPSHOT.debug",
            "app_build": "800",
            "app_unique_id": "",
            "measure_sdk_version": "",
            "platform": "",
            "thread_name": "",
            "user_id": "",
            "device_name": "emu64a",
            "device_model": "sdk_gphone64_arm64",
            "device_manufacturer": "Google",
            "device_type": "",
            "device_is_foldable": false,
            "device_is_physical": false,
            "device_density_dpi": 0,
            "device_width_px": 0,
            "device_height_px": 0,
            "device_density": 0,
            "device_locale": "",
            "os_name": "android",
            "os_version": "33",
            "os_page_size": 0,
            "network_type": "",
            "network_provider": "",
            "network_generation": ""
          },
          "events": null,
          "first_event_time": "2024-10-02T13:11:45.182Z",
          "last_event_time": "2024-10-02T13:15:14.489Z",
          "duration": 209307,
          "matched_free_text": ""
        },
        {
          "session_id": "6d132488-9f91-4f4e-9869-e80fc5f4a03c",
          "app_id": "36e1b948-3a0a-4e71-80f3-625e61d6c832",
          "attribute": {
            "installation_id": "00000000-0000-0000-0000-000000000000",
            "app_version": "0.8.0-SNAPSHOT.debug",
            "app_build": "800",
            "app_unique_id": "",
            "measure_sdk_version": "",
            "platform": "",
            "thread_name": "",
            "user_id": "",
            "device_name": "emu64a",
            "device_model": "sdk_gphone64_arm64",
            "device_manufacturer": "Google",
            "device_type": "",
            "device_is_foldable": false,
            "device_is_physical": false,
            "device_density_dpi": 0,
            "device_width_px": 0,
            "device_height_px": 0,
            "device_density": 0,
            "device_locale": "",
            "os_name": "android",
            "os_version": "33",
            "os_page_size": 0,
            "network_type": "",
            "network_provider": "",
            "network_generation": ""
          },
          "events": null,
          "first_event_time": "2024-10-02T13:10:28.454Z",
          "last_event_time": "2024-10-02T13:11:08.89Z",
          "duration": 40436,
          "matched_free_text": ""
        },
        {
          "session_id": "5e6e1064-9eed-499f-b552-c2dc993b4792",
          "app_id": "36e1b948-3a0a-4e71-80f3-625e61d6c832",
          "attribute": {
            "installation_id": "00000000-0000-0000-0000-000000000000",
            "app_version": "0.7.0-SNAPSHOT.debug",
            "app_build": "700",
            "app_unique_id": "",
            "measure_sdk_version": "",
            "platform": "",
            "thread_name": "",
            "user_id": "",
            "device_name": "emu64a16k",
            "device_model": "sdk_gphone16k_arm64",
            "device_manufacturer": "Google",
            "device_type": "",
            "device_is_foldable": false,
            "device_is_physical": false,
            "device_density_dpi": 0,
            "device_width_px": 0,
            "device_height_px": 0,
            "device_density": 0,
            "device_locale": "",
            "os_name": "android",
            "os_version": "35",
            "os_page_size": 0,
            "network_type": "",
            "network_provider": "",
            "network_generation": ""
          },
          "events": null,
          "first_event_time": "2024-09-23T10:07:08.236Z",
          "last_event_time": "2024-09-23T10:07:13.063Z",
          "duration": 4827,
          "matched_free_text": ""
        }
      ]
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/sessions/:id

Fetch an app's session replay.

Usage Notes

  • App's UUID must be passed in the URI
  • Sessions's UUID must be passed in the URI

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response
Click to expand
{
  "app_id": "2b7ddad4-40a6-42a7-9e21-a90577e08263",
  "attribute": {
    "installation_id": "ee40eb0e-c579-473d-bc10-557049f51cda",
    "app_version": "1.0",
    "app_build": "1",
    "app_unique_id": "sh.measure.sample",
    "measure_sdk_version": "0.1.0",
    "platform": "android",
    "thread_name": "msr-cmu",
    "user_id": "",
    "device_name": "emu64a",
    "device_model": "sdk_gphone64_arm64",
    "device_manufacturer": "Google",
    "device_type": "phone",
    "device_is_foldable": true,
    "device_is_physical": false,
    "device_density_dpi": 440,
    "device_width_px": 1080,
    "device_height_px": 2154,
    "device_density": 2.75,
    "device_locale": "en-US",
    "os_name": "android",
    "os_version": "33",
    "network_type": "wifi",
    "network_provider": "",
    "network_generation": "unknown"
  },
  "cpu_usage": [
    {
      "timestamp": "2024-05-03T23:34:17.591Z",
      "value": 6.999999999999999
    },
    {
      "timestamp": "2024-05-03T23:34:20.567Z",
      "value": 24
    },
    {
      "timestamp": "2024-05-03T23:34:23.567Z",
      "value": 28.999999999999996
    },
    {
      "timestamp": "2024-05-03T23:34:26.569Z",
      "value": 30.333333333333336
    }
  ],
  "duration": 22084,
  "memory_usage": [
    {
      "java_max_heap": 196608,
      "java_total_heap": 196608,
      "java_free_heap": 183734,
      "total_pss": 63702,
      "rss": 171692,
      "native_total_heap": 21872,
      "native_free_heap": 1299,
      "interval": 2000,
      "timestamp": "2024-05-03T23:34:17.607Z"
    },
    {
      "java_max_heap": 196608,
      "java_total_heap": 49152,
      "java_free_heap": 25884,
      "total_pss": 96896,
      "rss": 187708,
      "native_total_heap": 24060,
      "native_free_heap": 1171,
      "interval": 2000,
      "timestamp": "2024-05-03T23:34:19.566Z"
    },
    {
      "java_max_heap": 196608,
      "java_total_heap": 49152,
      "java_free_heap": 25063,
      "total_pss": 94875,
      "rss": 185312,
      "native_total_heap": 24828,
      "native_free_heap": 1452,
      "interval": 2000,
      "timestamp": "2024-05-03T23:34:21.565Z"
    },
    {
      "java_max_heap": 196608,
      "java_total_heap": 49152,
      "java_free_heap": 24975,
      "total_pss": 95547,
      "rss": 185920,
      "native_total_heap": 24828,
      "native_free_heap": 1452,
      "interval": 2000,
      "timestamp": "2024-05-03T23:34:23.571Z"
    },
    {
      "java_max_heap": 196608,
      "java_total_heap": 49152,
      "java_free_heap": 24923,
      "total_pss": 95587,
      "rss": 185920,
      "native_total_heap": 24828,
      "native_free_heap": 1436,
      "interval": 2000,
      "timestamp": "2024-05-03T23:34:25.568Z"
    },
    {
      "java_max_heap": 196608,
      "java_total_heap": 24300,
      "java_free_heap": 0,
      "total_pss": 99105,
      "rss": 191340,
      "native_total_heap": 26620,
      "native_free_heap": 2879,
      "interval": 2000,
      "timestamp": "2024-05-03T23:34:27.565Z"
    }
  ],
  "session_id": "58e94ae9-a084-479f-9049-2c5135f6090f",
  "threads": {
    "OkHttp https://httpbin.org/...": [
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "OkHttp https://httpbin.org/...",
        "user_triggered": false,
        "url": "https://httpbin.org/",
        "method": "get",
        "status_code": 200,
        "start_time": 5128127,
        "end_time": 5129475,
        "request_body": "",
        "response_body": "",
        "failure_reason": "",
        "failure_description": "",
        "request_headers": {
          "accept-encoding": "gzip",
          "connection": "Keep-Alive",
          "host": "httpbin.org",
          "user-agent": "okhttp/4.12.0"
        },
        "response_headers": {
          "access-control-allow-credentials": "true",
          "access-control-allow-origin": "*",
          "content-length": "9593",
          "content-type": "text/html; charset=utf-8",
          "date": "Fri, 03 May 2024 23:34:20 GMT",
          "server": "gunicorn/19.9.0"
        },
        "client": "okhttp",
        "duration": 1348,
        "timestamp": "2024-05-03T23:34:19.979Z"
      }
    ],
    "Thread-2": [
      {
        "event_type": "anr",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "title": "[email protected]:66",
        "thread_name": "Thread-2",
        "stacktrace": "sh.measure.android.anr.AnrError: Application Not Responding for at least 5000 ms.\n\tat sh.measure.sample.ExceptionDemoActivity.deadLock$lambda$10(ExceptionDemoActivity.kt:66)\n\tat sh.measure.sample.ExceptionDemoActivity.$r8$lambda$G4MY09CRhRk9ettfD7HPDD_b1n4\n\tat sh.measure.sample.ExceptionDemoActivity$$ExternalSyntheticLambda0.run(R8$$SyntheticClass)\n\tat android.os.Handler.handleCallback(Handler.java:942)\n\tat android.os.Handler.dispatchMessage(Handler.java:99)\n\tat android.os.Looper.loopOnce(Looper.java:201)\n\tat android.os.Looper.loop(Looper.java:288)\n\tat android.app.ActivityThread.main(ActivityThread.java:7872)\n\tat java.lang.reflect.Method.invoke(Method.java:-2)\n\tat com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)\n\tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)",
        "foreground": true,
        "timestamp": "2024-05-03T23:34:27.578Z",
        "attachments": [
          {
            "id": "63fb0950-faff-4028-bf3d-354559e4e540",
            "name": "screenshot.png",
            "type": "screenshot",
            "key": "63fb0950-faff-4028-bf3d-354559e4e540.png",
            "location": "http://localhost:9111/msr-attachments-sandbox/63fb0950-faff-4028-bf3d-354559e4e540.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minio%2F20240626%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240626T194224Z&X-Amz-Expires=172800&X-Amz-SignedHeaders=host&X-Amz-Signature=bd6825a4a47dd4df3742492239d05bbee8881f59a27a314f7e7bf7ea5dc139e9"
          }
        ]
      }
    ],
    "main": [
      {
        "event_type": "lifecycle_activity",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "type": "created",
        "class_name": "sh.measure.sample.ExceptionDemoActivity",
        "intent": "",
        "saved_instance_state": false,
        "timestamp": "2024-05-03T23:34:17.647Z"
      },
      {
        "event_type": "lifecycle_app",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "type": "foreground",
        "timestamp": "2024-05-03T23:34:17.74Z"
      },
      {
        "event_type": "lifecycle_activity",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "type": "resumed",
        "class_name": "sh.measure.sample.ExceptionDemoActivity",
        "intent": "",
        "saved_instance_state": false,
        "timestamp": "2024-05-03T23:34:17.744Z"
      },
      {
        "event_type": "cold_launch",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "duration": 698,
        "timestamp": "2024-05-03T23:34:17.825Z"
      },
      {
        "event_type": "gesture_click",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "target": "com.google.android.material.button.MaterialButton",
        "target_id": "btn_okhttp",
        "width": 262,
        "height": 132,
        "x": 546.95435,
        "y": 1460.94,
        "timestamp": "2024-05-03T23:34:18.586Z"
      },
      {
        "event_type": "lifecycle_activity",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "type": "paused",
        "class_name": "sh.measure.sample.ExceptionDemoActivity",
        "intent": "",
        "saved_instance_state": false,
        "timestamp": "2024-05-03T23:34:18.603Z"
      },
      {
        "event_type": "lifecycle_activity",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "type": "created",
        "class_name": "sh.measure.sample.OkHttpActivity",
        "intent": "",
        "saved_instance_state": false,
        "timestamp": "2024-05-03T23:34:18.615Z"
      },
      {
        "event_type": "lifecycle_activity",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "type": "resumed",
        "class_name": "sh.measure.sample.OkHttpActivity",
        "intent": "",
        "saved_instance_state": false,
        "timestamp": "2024-05-03T23:34:18.637Z"
      },
      {
        "event_type": "lifecycle_activity",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "type": "paused",
        "class_name": "sh.measure.sample.OkHttpActivity",
        "intent": "",
        "saved_instance_state": false,
        "timestamp": "2024-05-03T23:34:20.04Z"
      },
      {
        "event_type": "lifecycle_activity",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "type": "resumed",
        "class_name": "sh.measure.sample.ExceptionDemoActivity",
        "intent": "",
        "saved_instance_state": false,
        "timestamp": "2024-05-03T23:34:20.048Z"
      },
      {
        "event_type": "lifecycle_activity",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "type": "destroyed",
        "class_name": "sh.measure.sample.OkHttpActivity",
        "intent": "",
        "saved_instance_state": false,
        "timestamp": "2024-05-03T23:34:20.606Z"
      },
      {
        "event_type": "gesture_click",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "main",
        "target": "com.google.android.material.button.MaterialButton",
        "target_id": "btn_deadlock",
        "width": 311,
        "height": 132,
        "x": 549.9536,
        "y": 1324.8999,
        "timestamp": "2024-05-03T23:34:20.98Z"
      }
    ],
    "msr-bg": [
      {
        "event_type": "app_exit",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-bg",
        "reason": "ANR",
        "importance": "FOREGROUND",
        "trace": "DALVIK THREADS (37):\n\"Signal Catcher\" daemon prio=10 tid=2 Runnable\n  native: #00 pc 000000000053a6e0  /apex/com.android.art/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+128) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #01 pc 00000000006f0e84  /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool, BacktraceMap*, bool) const+236) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #02 pc 00000000006fe710  /apex/com.android.art/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)+208) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #03 pc 0000000000364248  /apex/com.android.art/lib64/libart.so (art::ThreadList::RunCheckpoint(art::Closure*, art::Closure*)+440) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #04 pc 00000000006fceb0  /apex/com.android.art/lib64/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool)+280) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #05 pc 00000000006fc8a4  /apex/com.android.art/lib64/libart.so (art::ThreadList::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+292) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #06 pc 00000000006d5974  /apex/com.android.art/lib64/libart.so (art::Runtime::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+184) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #07 pc 00000000006e1a20  /apex/com.android.art/lib64/libart.so (art::SignalCatcher::HandleSigQuit()+468) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #08 pc 0000000000574230  /apex/com.android.art/lib64/libart.so (art::SignalCatcher::Run(void*)+264) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #09 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #10 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"main\" prio=5 tid=1 Blocked\n  at sh.measure.sample.ExceptionDemoActivity.deadLock$lambda$10(ExceptionDemoActivity.kt:66)\n  - waiting to lock <0x0b2cc044> (a java.lang.Object) held by thread 38\n  at sh.measure.sample.ExceptionDemoActivity.$r8$lambda$G4MY09CRhRk9ettfD7HPDD_b1n4(unavailable:0)\n  at sh.measure.sample.ExceptionDemoActivity$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)\n  at android.os.Handler.handleCallback(Handler.java:942)\n  at android.os.Handler.dispatchMessage(Handler.java:99)\n  at android.os.Looper.loopOnce(Looper.java:201)\n  at android.os.Looper.loop(Looper.java:288)\n  at android.app.ActivityThread.main(ActivityThread.java:7872)\n  at java.lang.reflect.Method.invoke(Native method)\n  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)\n  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)\n\n\"ADB-JDWP Connection Control Thread\" daemon prio=0 tid=4 WaitingInMainDebuggerLoop\n  native: #00 pc 00000000000a34b8  /apex/com.android.runtime/lib64/bionic/libc.so (__ppoll+8) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 000000000005dc1c  /apex/com.android.runtime/lib64/bionic/libc.so (poll+92) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #02 pc 00000000000099e4  /apex/com.android.art/lib64/libadbconnection.so (adbconnection::AdbConnectionState::RunPollLoop(art::Thread*)+724) (BuildId: 3952e992b55a158a16b3d569cf8894e7)\n  native: #03 pc 00000000000080ac  /apex/com.android.art/lib64/libadbconnection.so (adbconnection::CallbackFunction(void*)+1320) (BuildId: 3952e992b55a158a16b3d569cf8894e7)\n  native: #04 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #05 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"perfetto_hprof_listener\" prio=10 tid=5 Native (still starting up)\n  native: #00 pc 00000000000a20f4  /apex/com.android.runtime/lib64/bionic/libc.so (read+4) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 000000000001d840  /apex/com.android.art/lib64/libperfetto_hprof.so (void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, ArtPlugin_Initialize::$_34> >(void*)+260) (BuildId: 525cc92a7dc49130157aeb74f6870364)\n  native: #02 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #03 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"Jit thread pool worker thread 0\" daemon prio=5 tid=6 Native\n  native: #00 pc 000000000004df5c  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 000000000047cc80  /apex/com.android.art/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+140) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #02 pc 000000000047cb18  /apex/com.android.art/lib64/libart.so (art::ThreadPool::GetTask(art::Thread*)+120) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #03 pc 00000000006199e4  /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Run()+136) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #04 pc 00000000006198c4  /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Callback(void*)+160) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #05 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #06 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"HeapTaskDaemon\" daemon prio=5 tid=7 WaitingForTaskProcessor\n  native: #00 pc 000000000004df60  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+32) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 000000000048771c  /apex/com.android.art/lib64/libart.so (art::ConditionVariable::TimedWait(art::Thread*, long, int)+252) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #02 pc 000000000046cf20  /apex/com.android.art/lib64/libart.so (art::gc::TaskProcessor::GetTask(art::Thread*)+196) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #03 pc 000000000046ce10  /apex/com.android.art/lib64/libart.so (art::gc::TaskProcessor::RunAllTasks(art::Thread*)+32) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  at dalvik.system.VMRuntime.runHeapTasks(Native method)\n  at java.lang.Daemons$HeapTaskDaemon.runInternal(Daemons.java:609)\n  at java.lang.Daemons$Daemon.run(Daemons.java:140)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"ReferenceQueueDaemon\" daemon prio=5 tid=8 Waiting\n  at java.lang.Object.wait(Native method)\n  - waiting on <0x0d3ac52d> (a java.lang.Class<java.lang.ref.ReferenceQueue>)\n  at java.lang.Object.wait(Object.java:442)\n  at java.lang.Object.wait(Object.java:568)\n  at java.lang.Daemons$ReferenceQueueDaemon.runInternal(Daemons.java:232)\n  - locked <0x0d3ac52d> (a java.lang.Class<java.lang.ref.ReferenceQueue>)\n  at java.lang.Daemons$Daemon.run(Daemons.java:140)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"FinalizerDaemon\" daemon prio=5 tid=9 Waiting\n  at java.lang.Object.wait(Native method)\n  - waiting on <0x07e7da62> (a java.lang.Object)\n  at java.lang.Object.wait(Object.java:442)\n  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:203)\n  - locked <0x07e7da62> (a java.lang.Object)\n  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:224)\n  at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:300)\n  at java.lang.Daemons$Daemon.run(Daemons.java:140)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"FinalizerWatchdogDaemon\" daemon prio=5 tid=10 Waiting\n  at java.lang.Object.wait(Native method)\n  - waiting on <0x0c0e07f3> (a java.lang.Daemons$FinalizerWatchdogDaemon)\n  at java.lang.Object.wait(Object.java:442)\n  at java.lang.Object.wait(Object.java:568)\n  at java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded(Daemons.java:385)\n  - locked <0x0c0e07f3> (a java.lang.Daemons$FinalizerWatchdogDaemon)\n  at java.lang.Daemons$FinalizerWatchdogDaemon.runInternal(Daemons.java:365)\n  at java.lang.Daemons$Daemon.run(Daemons.java:140)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"binder:10281_1\" prio=5 tid=11 Native\n  native: #00 pc 00000000000a23d8  /apex/com.android.runtime/lib64/bionic/libc.so (__ioctl+8) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 000000000005b50c  /apex/com.android.runtime/lib64/bionic/libc.so (ioctl+156) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #02 pc 0000000000094690  /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+316) (BuildId: ee18e52b95e38eaab55a9a48518c8c3b)\n  native: #03 pc 0000000000094540  /system/lib64/libbinder.so (android::PoolThread::threadLoop()+24) (BuildId: ee18e52b95e38eaab55a9a48518c8c3b)\n  native: #04 pc 00000000000148e8  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+528) (BuildId: 5a0d720732600c94ad8354a1188e9f52)\n  native: #05 pc 00000000000c8918  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140) (BuildId: a31474ac581b716d4588f8c97eb06009)\n  native: #06 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #07 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"binder:10281_2\" prio=5 tid=12 Native\n  native: #00 pc 00000000000a23d8  /apex/com.android.runtime/lib64/bionic/libc.so (__ioctl+8) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 000000000005b50c  /apex/com.android.runtime/lib64/bionic/libc.so (ioctl+156) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #02 pc 0000000000094690  /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+316) (BuildId: ee18e52b95e38eaab55a9a48518c8c3b)\n  native: #03 pc 0000000000094540  /system/lib64/libbinder.so (android::PoolThread::threadLoop()+24) (BuildId: ee18e52b95e38eaab55a9a48518c8c3b)\n  native: #04 pc 00000000000148e8  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+528) (BuildId: 5a0d720732600c94ad8354a1188e9f52)\n  native: #05 pc 00000000000c8918  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140) (BuildId: a31474ac581b716d4588f8c97eb06009)\n  native: #06 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #07 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"binder:10281_3\" prio=5 tid=13 Native\n  native: #00 pc 00000000000a23d8  /apex/com.android.runtime/lib64/bionic/libc.so (__ioctl+8) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 000000000005b50c  /apex/com.android.runtime/lib64/bionic/libc.so (ioctl+156) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #02 pc 0000000000094690  /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+316) (BuildId: ee18e52b95e38eaab55a9a48518c8c3b)\n  native: #03 pc 0000000000094540  /system/lib64/libbinder.so (android::PoolThread::threadLoop()+24) (BuildId: ee18e52b95e38eaab55a9a48518c8c3b)\n  native: #04 pc 00000000000148e8  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+528) (BuildId: 5a0d720732600c94ad8354a1188e9f52)\n  native: #05 pc 00000000000c8918  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140) (BuildId: a31474ac581b716d4588f8c97eb06009)\n  native: #06 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #07 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"binder:10281_4\" prio=5 tid=14 Native\n  native: #00 pc 00000000000a23d8  /apex/com.android.runtime/lib64/bionic/libc.so (__ioctl+8) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 000000000005b50c  /apex/com.android.runtime/lib64/bionic/libc.so (ioctl+156) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #02 pc 0000000000094690  /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+316) (BuildId: ee18e52b95e38eaab55a9a48518c8c3b)\n  native: #03 pc 0000000000094540  /system/lib64/libbinder.so (android::PoolThread::threadLoop()+24) (BuildId: ee18e52b95e38eaab55a9a48518c8c3b)\n  native: #04 pc 00000000000148e8  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+528) (BuildId: 5a0d720732600c94ad8354a1188e9f52)\n  native: #05 pc 00000000000c8918  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140) (BuildId: a31474ac581b716d4588f8c97eb06009)\n  native: #06 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #07 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"Profile Saver\" daemon prio=5 tid=15 Native\n  native: #00 pc 000000000004df60  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+32) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 000000000048771c  /apex/com.android.art/lib64/libart.so (art::ConditionVariable::TimedWait(art::Thread*, long, int)+252) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #02 pc 000000000054380c  /apex/com.android.art/lib64/libart.so (art::ProfileSaver::Run()+524) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #03 pc 0000000000538fc0  /apex/com.android.art/lib64/libart.so (art::ProfileSaver::RunProfileSaverThread(void*)+148) (BuildId: e24a1818231cfb1649cb83a5d2869598)\n  native: #04 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #05 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"msr-cmu\" prio=5 tid=16 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2123)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1188)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"Thread-2\" prio=5 tid=17 Sleeping\n  at java.lang.Thread.sleep(Native method)\n  - sleeping on <0x01579cb0> (a java.lang.Object)\n  at java.lang.Thread.sleep(Thread.java:450)\n  - locked <0x01579cb0> (a java.lang.Object)\n  at java.lang.Thread.sleep(Thread.java:355)\n  at sh.measure.android.anr.ANRWatchDog.run(ANRWatchDog.kt:70)\n\n\"ConnectivityThread\" prio=5 tid=18 Native\n  native: #00 pc 00000000000a33b8  /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 0000000000010dfc  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+176) (BuildId: 5a0d720732600c94ad8354a1188e9f52)\n  native: #02 pc 000000000015a56c  /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44) (BuildId: a31474ac581b716d4588f8c97eb06009)\n  at android.os.MessageQueue.nativePollOnce(Native method)\n  at android.os.MessageQueue.next(MessageQueue.java:335)\n  at android.os.Looper.loopOnce(Looper.java:161)\n  at android.os.Looper.loop(Looper.java:288)\n  at android.os.HandlerThread.run(HandlerThread.java:67)\n\n\"msr-ep\" prio=5 tid=19 Waiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)\n  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1176)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"LeakCanary-Heap-Dump\" prio=5 tid=20 Native\n  native: #00 pc 00000000000a33b8  /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 0000000000010dfc  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+176) (BuildId: 5a0d720732600c94ad8354a1188e9f52)\n  native: #02 pc 000000000015a56c  /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44) (BuildId: a31474ac581b716d4588f8c97eb06009)\n  at android.os.MessageQueue.nativePollOnce(Native method)\n  at android.os.MessageQueue.next(MessageQueue.java:335)\n  at android.os.Looper.loopOnce(Looper.java:161)\n  at android.os.Looper.loop(Looper.java:288)\n  at android.os.HandlerThread.run(HandlerThread.java:67)\n\n\"RenderThread\" daemon prio=7 tid=21 Native\n  native: #00 pc 00000000000a33b8  /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 0000000000010dfc  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+176) (BuildId: 5a0d720732600c94ad8354a1188e9f52)\n  native: #02 pc 000000000057c4c0  /system/lib64/libhwui.so (android::uirenderer::renderthread::RenderThread::threadLoop()+220) (BuildId: 5e787210ce0f171dbee073e4a14a376c)\n  native: #03 pc 00000000000148e8  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+528) (BuildId: 5a0d720732600c94ad8354a1188e9f52)\n  native: #04 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #05 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"msr-bg\" prio=5 tid=22 Waiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)\n  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1176)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"msr-eh\" prio=5 tid=23 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2123)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1188)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"msr-ee\" prio=5 tid=24 Waiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)\n  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1176)\n  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:905)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1063)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"hwuiTask1\" daemon prio=6 tid=25 Native\n  native: #00 pc 000000000004df5c  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 0000000000052664  /apex/com.android.runtime/lib64/bionic/libc.so (__futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+144) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #02 pc 00000000000b56cc  /apex/com.android.runtime/lib64/bionic/libc.so (pthread_cond_wait+76) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #03 pc 00000000000699e0  /system/lib64/libc++.so (std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&)+20) (BuildId: 6ae0290e5bfb8abb216bde2a4ee48d9e)\n  native: #04 pc 0000000000250af8  /system/lib64/libhwui.so (android::uirenderer::CommonPool::workerLoop()+96) (BuildId: 5e787210ce0f171dbee073e4a14a376c)\n  native: #05 pc 0000000000250d5c  /system/lib64/libhwui.so (android::uirenderer::CommonPool::CommonPool()::$_0::operator()() const (.__uniq.99815402873434996937524029735804459536)+188) (BuildId: 5e787210ce0f171dbee073e4a14a376c)\n  native: #06 pc 0000000000250c9c  /system/lib64/libhwui.so (void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, android::uirenderer::CommonPool::CommonPool()::$_0> >(void*) (.__uniq.99815402873434996937524029735804459536)+40) (BuildId: 5e787210ce0f171dbee073e4a14a376c)\n  native: #07 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #08 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"hwuiTask0\" daemon prio=6 tid=26 Native\n  native: #00 pc 000000000004df5c  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 0000000000052664  /apex/com.android.runtime/lib64/bionic/libc.so (__futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+144) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #02 pc 00000000000b56cc  /apex/com.android.runtime/lib64/bionic/libc.so (pthread_cond_wait+76) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #03 pc 00000000000699e0  /system/lib64/libc++.so (std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&)+20) (BuildId: 6ae0290e5bfb8abb216bde2a4ee48d9e)\n  native: #04 pc 0000000000250af8  /system/lib64/libhwui.so (android::uirenderer::CommonPool::workerLoop()+96) (BuildId: 5e787210ce0f171dbee073e4a14a376c)\n  native: #05 pc 0000000000250d5c  /system/lib64/libhwui.so (android::uirenderer::CommonPool::CommonPool()::$_0::operator()() const (.__uniq.99815402873434996937524029735804459536)+188) (BuildId: 5e787210ce0f171dbee073e4a14a376c)\n  native: #06 pc 0000000000250c9c  /system/lib64/libhwui.so (void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, android::uirenderer::CommonPool::CommonPool()::$_0> >(void*) (.__uniq.99815402873434996937524029735804459536)+40) (BuildId: 5e787210ce0f171dbee073e4a14a376c)\n  native: #07 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #08 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  (no managed stack frames)\n\n\"Okio Watchdog\" daemon prio=5 tid=27 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2211)\n  at okio.AsyncTimeout$Companion.awaitTimeout(AsyncTimeout.kt:370)\n  at okio.AsyncTimeout$Watchdog.run(AsyncTimeout.kt:211)\n\n\"OkHttp Dispatcher\" prio=5 tid=28 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)\n  at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)\n  at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"queued-work-looper\" prio=5 tid=29 Native\n  native: #00 pc 00000000000a33b8  /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 0000000000010dfc  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+176) (BuildId: 5a0d720732600c94ad8354a1188e9f52)\n  native: #02 pc 000000000015a56c  /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44) (BuildId: a31474ac581b716d4588f8c97eb06009)\n  at android.os.MessageQueue.nativePollOnce(Native method)\n  at android.os.MessageQueue.next(MessageQueue.java:335)\n  at android.os.Looper.loopOnce(Looper.java:161)\n  at android.os.Looper.loop(Looper.java:288)\n  at android.os.HandlerThread.run(HandlerThread.java:67)\n\n\"OkHttp httpbin.org\" daemon prio=5 tid=30 Native\n  native: #00 pc 00000000000a2f54  /apex/com.android.runtime/lib64/bionic/libc.so (recvfrom+4) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 00000000000298c8  /apex/com.android.art/lib64/libopenjdk.so (NET_Read+80) (BuildId: df8df6b1c275e887f918729a4f22136c)\n  native: #02 pc 000000000002a440  /apex/com.android.art/lib64/libopenjdk.so (SocketInputStream_socketRead0+216) (BuildId: df8df6b1c275e887f918729a4f22136c)\n  at java.net.SocketInputStream.socketRead0(Native method)\n  at java.net.SocketInputStream.socketRead(SocketInputStream.java:118)\n  at java.net.SocketInputStream.read(SocketInputStream.java:173)\n  at java.net.SocketInputStream.read(SocketInputStream.java:143)\n  at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:945)\n  at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:909)\n  at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824)\n  at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797)\n  - locked <0x042b8729> (a java.lang.Object)\n  at okio.InputStreamSource.read(JvmOkio.kt:93)\n  at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:153)\n  at okio.RealBufferedSource.request(RealBufferedSource.kt:209)\n  at okio.RealBufferedSource.require(RealBufferedSource.kt:202)\n  at okhttp3.internal.http2.Http2Reader.nextFrame(Http2Reader.kt:89)\n  at okhttp3.internal.http2.Http2Connection$ReaderRunnable.invoke(Http2Connection.kt:618)\n  at okhttp3.internal.http2.Http2Connection$ReaderRunnable.invoke(Http2Connection.kt:609)\n  at okhttp3.internal.concurrent.TaskQueue$execute$1.runOnce(TaskQueue.kt:98)\n  at okhttp3.internal.concurrent.TaskRunner.runTask(TaskRunner.kt:116)\n  at okhttp3.internal.concurrent.TaskRunner.access$runTask(TaskRunner.kt:42)\n  at okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.kt:65)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"OkHttp TaskRunner\" daemon prio=5 tid=31 TimedWaiting\n  at java.lang.Object.wait(Native method)\n  - waiting on <0x0c6d3aae> (a okhttp3.internal.concurrent.TaskRunner)\n  at okhttp3.internal.concurrent.TaskRunner$RealBackend.coordinatorWait(TaskRunner.kt:294)\n  at okhttp3.internal.concurrent.TaskRunner.awaitTaskToRun(TaskRunner.kt:218)\n  at okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.kt:59)\n  - locked <0x0c6d3aae> (a okhttp3.internal.concurrent.TaskRunner)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"OkHttp TaskRunner\" daemon prio=5 tid=32 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)\n  at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)\n  at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"OkHttp TaskRunner\" daemon prio=5 tid=33 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)\n  at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)\n  at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"OkHttp TaskRunner\" daemon prio=5 tid=34 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)\n  at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)\n  at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"OkHttp TaskRunner\" daemon prio=5 tid=35 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)\n  at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)\n  at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"OkHttp TaskRunner\" daemon prio=5 tid=36 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)\n  at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)\n  at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"OkHttp TaskRunner\" daemon prio=5 tid=37 TimedWaiting\n  at jdk.internal.misc.Unsafe.park(Native method)\n  - waiting on an unknown object\n  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)\n  at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:463)\n  at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:361)\n  at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:939)\n  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)\n  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1123)\n  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)\n  at java.lang.Thread.run(Thread.java:1012)\n\n\"APP: Locker\" prio=5 tid=38 Sleeping\n  at java.lang.Thread.sleep(Native method)\n  - sleeping on <0x02f7304f> (a java.lang.Object)\n  at java.lang.Thread.sleep(Thread.java:450)\n  - locked <0x02f7304f> (a java.lang.Object)\n  at java.lang.Thread.sleep(Thread.java:355)\n  at sh.measure.sample.ExceptionDemoActivity.sleep(ExceptionDemoActivity.kt:86)\n  at sh.measure.sample.ExceptionDemoActivity.access$sleep(ExceptionDemoActivity.kt:12)\n  at sh.measure.sample.ExceptionDemoActivity$LockerThread.run(ExceptionDemoActivity.kt:80)\n  - locked <0x0b2cc044> (a java.lang.Object)\n\n\"binder:10281_2\" prio=5 (not attached)\n  native: #00 pc 000000000004df5c  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #01 pc 0000000000052664  /apex/com.android.runtime/lib64/bionic/libc.so (__futex_wait_ex(void volatile*, bool, int, bool, timespec const*)+144) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #02 pc 00000000000b56cc  /apex/com.android.runtime/lib64/bionic/libc.so (pthread_cond_wait+76) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #03 pc 00000000000699e0  /system/lib64/libc++.so (std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&)+20) (BuildId: 6ae0290e5bfb8abb216bde2a4ee48d9e)\n  native: #04 pc 00000000000a048c  /system/lib64/libgui.so (android::AsyncWorker::run()+112) (BuildId: 383a37b5342fd0249afb25e7134deb33)\n  native: #05 pc 00000000000a0878  /system/lib64/libgui.so (void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (android::AsyncWorker::*)(), android::AsyncWorker*> >(void*)+80) (BuildId: 383a37b5342fd0249afb25e7134deb33)\n  native: #06 pc 00000000000b63b0  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n  native: #07 pc 00000000000530b8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)\n\n----- end 10281 -----\n",
        "process_name": "sh.measure.sample",
        "pid": "10281",
        "timestamp": "2024-05-03T23:34:39.675Z"
      }
    ],
    "msr-ee": [
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5127443,
        "end_time": 5127508,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 65,
        "timestamp": "2024-05-03T23:34:18.012Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5127520,
        "end_time": 5127558,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 38,
        "timestamp": "2024-05-03T23:34:18.061Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5127569,
        "end_time": 5127602,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 33,
        "timestamp": "2024-05-03T23:34:18.106Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5127606,
        "end_time": 5127639,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 33,
        "timestamp": "2024-05-03T23:34:18.143Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5127644,
        "end_time": 5127675,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 31,
        "timestamp": "2024-05-03T23:34:18.179Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5137254,
        "end_time": 5137278,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 24,
        "timestamp": "2024-05-03T23:34:27.782Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5137295,
        "end_time": 5137321,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 26,
        "timestamp": "2024-05-03T23:34:27.824Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5137326,
        "end_time": 5137360,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 34,
        "timestamp": "2024-05-03T23:34:27.863Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5137387,
        "end_time": 5137429,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 42,
        "timestamp": "2024-05-03T23:34:27.932Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5137440,
        "end_time": 5137463,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 23,
        "timestamp": "2024-05-03T23:34:27.967Z"
      },
      {
        "event_type": "http",
        "user_defined_attribute": {
          "username": "alice",
          "paid_user": true,
          "credit_balance": 12345,
          "latitude": 30.2661403415387
        },
        "thread_name": "msr-ee",
        "user_triggered": false,
        "url": "http://10.0.2.2:8080/events",
        "method": "put",
        "status_code": 0,
        "start_time": 5137475,
        "end_time": 5137504,
        "request_body": "",
        "response_body": "",
        "failure_reason": "java.net.ConnectException",
        "failure_description": "Failed to connect to /10.0.2.2:8080",
        "request_headers": {},
        "response_headers": {},
        "client": "okhttp",
        "duration": 29,
        "timestamp": "2024-05-03T23:34:28.007Z"
      }
    ]
  }
}
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/alertPrefs

Fetch an app's alert preferences for current user.

Usage Notes

  • App's UUID must be passed in the URI

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
        "crash_rate_spike": {
          "email": true,
          "slack": false
        },
        "anr_rate_spike": {
          "email": true,
          "slack": false
        },
        "launch_time_spike": {
          "email": true,
          "slack": false
        }
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

PATCH /apps/:id/alertPrefs

Update an app's alert preferences for current user.

Usage Notes

  • App's UUID must be passed in the URI

Request body

{
    "crash_rate_spike": {
      "email": true,
      "slack": false
    },
    "anr_rate_spike": {
      "email": true,
      "slack": false
    },
    "launch_time_spike": {
      "email": true,
      "slack": false
    }
  }

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "ok" : "done"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

PATCH /apps/:id/rename

Modify the name of an app.

Usage Notes

  • App's UUID must be passed in the URI

Request body

{
  "name": "acme app"
}

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "ok" : "done"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/settings

Fetch an app's settings.

Usage Notes

  • App's UUID must be passed in the URI

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
        "retention_period": 30
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

PATCH /apps/:id/settings

Update an app's settings.

Usage Notes

  • App's UUID must be passed in the URI

Request body

{
    "retention_period": 365
}

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "ok" : "done"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

POST /apps/:id/shortFilters

Create a shortcode to represent a combination of various app filters.

These shortcodes can then be used in other app APIs which accept different filters. Shortcodes are short-lived, they'll be automatically removed after an hour or so.

Usage Notes

  • App's UUID must be passed in the URI

Request body

{
  "filters": {
    "versions": ["1.0"],
    "version_codes": ["1"],
    "os_names": ["android"],
    "os_versions": ["33"],
    "countries": ["bogon"],
    "network_providers": ["unknown"],
    "network_types": ["wifi"],
    "network_generations": ["unknown"],
    "locales": ["en-US"],
    "device_manufacturers": ["Google"],
    "device_names": ["emu64a"],
    "ud_expression": "{\"and\":[{\"cmp\":{\"key\":\"username\",\"type\":\"string\",\"op\":\"eq\",\"value\":\"alice\"}},{\"cmp\":{\"key\":\"premium_user\",\"type\":\"bool\",\"op\":\"eq\",\"value\":\"true\"}}]}"
  }
}

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "filter_short_code" : "86f379b7afd9836d0877eb5c8ff93538"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/spans/roots/names

Fetch an app's root span names list with optional filters.

Usage Notes

  • App's UUID must be passed in the URI

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {"results":["activity.onCreate","SampleApp.onCreate"]}
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/spans/instances

Fetch an span's list of instances with optional filters.

Usage Notes

  • App's UUID must be passed in the URI
  • Span name for which instances list is being fetched must be passed as a query param
  • Accepted query parameters
    • span_name (required) - Name of the span for which instances list is being fetched.
    • from (optional) - ISO8601 timestamp to include sessions after this time.
    • to (optional) - ISO8601 timestamp to include sessions before this time.
    • versions (optional) - List of comma separated version identifier strings to return only matching sessions.
    • version_codes (optional) - List of comma separated version codes to return only matching sessions.
    • countries (optional) - List of comma separated country identifier strings to return only matching sessions.
    • device_names (optional) - List of comma separated device name identifier strings to return only matching sessions.
    • device_manufacturers (optional) - List of comma separated device manufacturer identifier strings to return only matching sessions.
    • locales (optional) - List of comma separated device locale identifier strings to return only matching sessions.
    • network_providers (optional) - List of comma separated network provider identifier strings to return only matching sessions.
    • network_types (optional) - List of comma separated network type identifier strings to return only matching sessions.
    • network_generations (optional) - List of comma separated network generation identifier strings to return only matching sessions.
    • offset (optional) - Number of items to skip when paginating. Use with limit parameter to control amount of items fetched.
    • limit (optional) - Number of items to return. Used for pagination. Should be used along with offset.
    • filter_short_code (optional) - Code representing combination of filters.
    • span_statuses (optional) - should be 0 (Unset), 1 (Ok) or 2 (Error). If multiple status are required, they should passed as multiple query params like span_statuses=0&span_statuses=1&span_statuses=2
  • For multiple comma separated fields, make sure no whitespace characters exist before or after comma.
  • Pass limit and offset values to paginate results

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "meta": {
          "next": false,
          "previous": false
      },
      "results": [
          {
              "app_id": "e963e98a-aca9-4bab-bd62-70a74801384e",
              "span_name": "activity.onCreate",
              "span_id": "54b40eb484ade006",
              "trace_id": "e0826847053bb9e539c9dc4d4da793ad",
              "status": 0,
              "start_time": "2024-11-18T14:14:55.491Z",
              "end_time": "2024-11-18T14:14:55.573Z",
              "duration": 82,
              "app_version": "0.9.0-SNAPSHOT.debug",
              "app_build": "900",
              "os_name": "android",
              "os_version": "35",
              "device_model": "sdk_gphone16k_arm64",
              "device_manufacturer": "Google"
          },
          {
              "app_id": "e963e98a-aca9-4bab-bd62-70a74801384e",
              "span_name": "activity.onCreate",
              "span_id": "9f1890db9aedb305",
              "trace_id": "d71f3d909689859469a7d9b38e605d56",
              "status": 0,
              "start_time": "2024-11-18T14:14:40.545Z",
              "end_time": "2024-11-18T14:14:40.62Z",
              "duration": 75,
              "app_version": "0.9.0-SNAPSHOT.debug",
              "app_build": "900",
              "os_name": "android",
              "os_version": "35",
              "device_model": "sdk_gphone16k_arm64",
              "device_manufacturer": "Google"
          },
          {
              "app_id": "e963e98a-aca9-4bab-bd62-70a74801384e",
              "span_name": "activity.onCreate",
              "span_id": "0b227c80be4050d8",
              "trace_id": "bba721b7bc78ae746e2c81a5e9e41e7a",
              "status": 0,
              "start_time": "2024-11-18T14:14:33.658Z",
              "end_time": "2024-11-18T14:14:33.743Z",
              "duration": 85,
              "app_version": "0.9.0-SNAPSHOT.debug",
              "app_build": "900",
              "os_name": "android",
              "os_version": "35",
              "device_model": "sdk_gphone16k_arm64",
              "device_manufacturer": "Google"
          }
      ]
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/spans/plot

Fetch an span's metrics plot with optional filters.

Usage Notes

  • App's UUID must be passed in the URI
  • Span name for which metrics plot is being fetched must be passed as a query param
  • Accepted query parameters
    • span_name (required) - Name of the span for which metrics plot is being fetched.
    • from (optional) - ISO8601 timestamp to include sessions after this time.
    • to (optional) - ISO8601 timestamp to include sessions before this time.
    • versions (optional) - List of comma separated version identifier strings to return only matching sessions.
    • version_codes (optional) - List of comma separated version codes to return only matching sessions.
    • countries (optional) - List of comma separated country identifier strings to return only matching sessions.
    • device_names (optional) - List of comma separated device name identifier strings to return only matching sessions.
    • device_manufacturers (optional) - List of comma separated device manufacturer identifier strings to return only matching sessions.
    • locales (optional) - List of comma separated device locale identifier strings to return only matching sessions.
    • network_providers (optional) - List of comma separated network provider identifier strings to return only matching sessions.
    • network_types (optional) - List of comma separated network type identifier strings to return only matching sessions.
    • network_generations (optional) - List of comma separated network generation identifier strings to return only matching sessions.
    • offset (optional) - Number of items to skip when paginating. Use with limit parameter to control amount of items fetched.
    • limit (optional) - Number of items to return. Used for pagination. Should be used along with offset.
    • filter_short_code (optional) - Code representing combination of filters.
    • span_statuses (optional) - should be 0 (Unset), 1 (Ok) or 2 (Error). If multiple status are required, they should passed as multiple query params like span_statuses=0&span_statuses=1&span_statuses=2
  • For multiple comma separated fields, make sure no whitespace characters exist before or after comma.
  • Pass limit and offset values to paginate results

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    [
      {
          "id": "0.9.0-SNAPSHOT.debug (900)",
          "data": [
              {
                  "datetime": "2024-11-18",
                  "p50": 82,
                  "p90": 85,
                  "p95": 85,
                  "p99": 85
              }
          ]
      }
    ]
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /apps/:id/traces/:traceId

Fetch a trace.

Usage Notes

  • App's UUID must be passed in the URI
  • Trace Id must be passed in the URI

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "app_id": "e963e98a-aca9-4bab-bd62-70a74801384e",
      "trace_id": "e0826847053bb9e539c9dc4d4da793ad",
      "session_id": "9b33b3cd-2588-46b4-9b1e-19d7d2c462fa",
      "user_id": "",
      "start_time": "2024-11-18T14:14:55.491Z",
      "end_time": "2024-11-18T14:14:55.573Z",
      "duration": 82,
      "app_version": "0.9.0-SNAPSHOT.debug(900)",
      "os_version": "android 35",
      "device_manufacturer": "Google",
      "device_model": "sdk_gphone16k_arm64",
      "network_type": "wifi",
      "spans": [
          {
              "span_name": "activity.onCreate",
              "span_id": "54b40eb484ade006",
              "parent_id": "",
              "status": 0,
              "start_time": "2024-11-18T14:14:55.491Z",
              "end_time": "2024-11-18T14:14:55.573Z",
              "duration": 82,
              "thread_name": "main",
              "device_low_power_mode": false,
              "device_thermal_throttling_enabled": false,
              "checkpoints": []
          }
      ]
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

Teams

POST /teams

Create a new team. Only owners of existing team can create new teams.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Request Body

Pass the name in "name" JSON property.

{
  "name": "acme-team"
}

Usage Notes

  • "name" cannot be empty

Response Body

  • Response

    Click to expand
    {
      "id": "269362f4-27a5-4eac-84f8-b2291515edd3",
      "name": "acme-team"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
201 Created Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /teams

Fetch list of teams of access token holder.

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    [
      {
          "id": "099f0f9b-5ee9-47de-a8aa-e996adc049c1",
          "name": "Team 1",
          "role": "owner"
      },
      {
          "id": "823f0g9c-2gg7-32mp-x6cj-v368geb129d0",
          "name": "Team 2",
          "role": "admin"
      }
    ]
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /teams/:id/apps

Fetch list of apps for a team

Usage Notes

  • Teams's UUID must be passed in the URI
  • The onboarded flag in the response indicates whether this app has received it's first session
  • The unique_identifier field in the response is the package name or bundle id of the app
  • The api_key field in the response is the key used by the client SDK to send data
  • The revoked field in the api_key object in the response indicates whether the API key is valid or has been revoked due to security issues

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    [
      {
          "id": "3dd90264-6be7-420f-aaf7-3f39a7588b0c",
          "team_id": "099f0f9b-5ee9-47de-a8aa-e996adc049c1",
          "name": "App 1",
          "api_key": {
              "created_at": "2024-01-19T06:16:00.896Z",
              "key": "msrsh_a235c69a0e9550d9d4bec7c6cdce653982cb452d8b6cb1f46875329c7ea7c3f4_abdb5a57",
              "last_seen": null,
              "revoked": false
          },
          "onboarded": false,
          "created_at": "2024-01-19T06:16:00.894744Z",
          "updated_at": "2024-01-19T06:16:00.894744Z",
          "platform": null,
          "onboarded_at": null,
          "unique_identifier": null
      },
      {
          "id": "a8367cc5-be17-4854-bb58-bb05e53e9a8c",
          "team_id": "099f0f9b-5ee9-47de-a8aa-e996adc049c1",
          "name": "App 2",
          "api_key": {
              "created_at": "2024-01-17T08:22:36.547Z",
              "key": "msrsh_d294b2f7f27eb9068b76d44ca4cbf67f5e192fda7075655cec311926acd145b4_2f7e56f9",
              "last_seen": null,
              "revoked": false
          },
          "onboarded": true,
          "created_at": "2024-01-17T08:22:36.540065Z",
          "updated_at": "2024-01-17T08:22:36.540065Z",
          "platform": "android",
          "onboarded_at": "2024-01-18T08:00:14.007865Z",
          "unique_identifier": "sh.measure.app2"
      }
    ]
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /teams/:id/apps/:id

Fetch details of an app for a team

Usage Notes

  • Teams's UUID must be passed in the URI as the first ID
  • Apps's UUID must be passed in the URI as the second ID
  • The onboarded flag in the response indicates whether this app has received it's first session
  • The unique_identifier field in the response is the package name or bundle id of the app
  • The api_key field in the response is the key used by the client SDK to send data
  • The revoked field in the api_key object in the response indicates whether the API key is valid or has been revoked due to security issues

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "id": "349ae6bb-deda-43a0-bee5-a0c8910872ab",
      "team_id": "9e139caa-27b5-4d22-a190-f13167ca14fe",
      "name": "App 1",
      "api_key": {
        "created_at": "2024-01-17T11:01:09.323Z",
        "key": "msrsh_d581058a398a021be561a46c9b92458f618a8a9cd3fed47fc8255b3c2be6b646_57cf688e",
        "last_seen": null,
        "revoked": false
      },
      "onboarded": true,
      "created_at": "2024-01-17T11:01:09.319248Z",
      "updated_at": "2024-01-18T08:00:14.007865Z",
      "platform": "android",
      "onboarded_at": "2024-01-18T08:00:14.007865Z",
      "unique_identifier": "sh.measure.app1"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

POST /teams/:id/apps

Create a new app for a team

Usage Notes

  • Teams's UUID must be passed in the URI
  • The app name of the new app must be passed in the request body
  • The onboarded flag in the response indicates whether this app has received it's first session
  • The unique_identifier field in the response is the package name or bundle id of the app
  • The api_key field in the response is the key used by the client SDK to send data
  • The revoked field in the api_key object in the response indicates whether the API key is valid or has been revoked due to security issues

Request body

{
  "name": "App 3"
}

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "id": "a787cbd6-1c94-4ffb-9cf9-f2fe0c4ebdeb",
      "team_id": "099f0f9b-5ee9-47de-a8aa-e996adc049c1",
      "name": "App 3",
      "api_key": {
          "created_at": "2024-01-19T06:40:37.489Z",
          "key": "msrsh_9d33956c945c386ea69790eab71550b955b09aa3dae9e1130d2d9fca6ea783b9_937e81c4",
          "last_seen": null,
          "revoked": false
      },
      "onboarded": false,
      "created_at": "2024-01-19T06:40:37.483752508Z",
      "updated_at": "2024-01-19T06:40:37.483752508Z",
      "platform": null,
      "onboarded_at": null,
      "unique_identifier": null
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
201 Created Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

POST /auth/invite

Invite new members (both existing & non measure users) to a team

Usage Notes

  • The email id of the user to be invited, team ID and role of the user to be invited must be passed in the request body
  • If a invited user does not have a measure account, they will get an invite email to sign up and will be added to team post signup automatically
  • If invited user already has a measure acccount, they will be added to the team immediately

Request body

[
  {
    "email": "[email protected]",
    "role": "admin",
    "teamId": "099f0f9b-5ee9-47de-a8aa-e996adc049c1",
  }
]

Authorization & Content Type

  1. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "ok":"invited [email protected]"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

PATCH /teams/:id/rename

Rename a team

Usage Notes

  • Teams's UUID must be passed in the URI
  • The new name of the team must be passed in the request body

Request body

{
  "name": "Team 2"
}

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "ok":"team was renamed"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /teams/:id/members

Fetch list of team members for a team

Usage Notes

  • Teams's UUID must be passed in the URI

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    [
      {
        "id": "7737299c-82cb-4769-8fed-b313a230aa9d",
        "name": "User 1",
        "email": "[email protected]",
        "role": "owner",
        "last_sign_in_at": "2024-01-19T06:11:47.928Z",
        "created_at": "2024-01-17T08:22:28.274Z"
      },
      {
        "id": "a787cbd6-1c94-4ffb-9cf9-f2fe0c4ebdeb",
        "name": "User 2",
        "email": "[email protected]",
        "role": "admin",
        "last_sign_in_at": "2024-01-19T03:09:47.928Z",
        "created_at": "2024-01-17T04:21:23.274Z"
      }
    ]
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

DELETE /teams/:id/members/:id

Remove a member from a team

Usage Notes

  • Teams's UUID must be passed in the URI as the first ID
  • Members's UUID must be passed in the URI as the second ID

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "ok": "removed member [f0ee4474-bcde-4d3f-979d-bbf36f2d66b7] from team [099f0f9b-5ee9-47de-a8aa-e996adc049c1]"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

PATCH /teams/:id/members/:id/role

Change role of a member of a team

Usage Notes

  • Teams's UUID must be passed in the URI as the first ID
  • Members's UUID must be passed in the URI as the second ID

Request body

{
  "role": "developer"
}

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "ok" : "done"
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.

GET /teams/:id/authz

Fetch authorization details of access token holder for a team.

Usage Notes

  • Teams's UUID must be passed in the URI
  • The can_invite field in the response indicates what roles new team members can be invited as by the current user
  • The can_change_roles field in the authz field in the response indicates what roles the current user is allowed to assign for that particular member
  • The can_remove flag in the authz field in the response indicates whether the current user is allowed to remove that particular member from the team

Authorization & Content Type

  1. Set the user's access token in Authorization: Bearer <access-token> format

  2. Set content type as Content-Type: application/json; charset=utf-8

These headers must be present in each request.

Request Headers - Click to expand
Name Value
Authorization Bearer <user-access-token>
Content-Type application/json; charset=utf-8

Response Body

  • Response

    Click to expand
    {
      "can_invite": [
          "owner",
          "admin",
          "developer",
          "viewer"
      ],
      "members": [
          {
              "id": "7737299c-82cb-4769-8fed-b313a230aa9d",
              "name": "User 1",
              "email": "[email protected]",
              "role": "owner",
              "last_sign_in_at": "2024-01-19T08:30:04.915Z",
              "created_at": "2024-01-17T08:22:28.274Z",
              "authz": {
                  "can_change_roles": [
                      "owner",
                      "admin",
                      "developer",
                      "viewer"
                  ],
                  "can_remove": true
              }
          },
          {
              "id": "f0ee4474-bcde-4d3f-979d-bbf36f2d66b7",
              "name": null,
              "email": "[email protected]",
              "role": "developer",
              "last_sign_in_at": "2024-01-19T08:27:04.38Z",
              "created_at": "2024-01-19T06:55:16.522Z",
              "authz": {
                  "can_change_roles": [
                      "owner",
                      "admin",
                      "developer",
                      "viewer"
                  ],
                  "can_remove": true
              }
          }
      ]
    }
  • Failed requests have the following response shape

    {
      "error": "Error message"
    }

Status Codes & Troubleshooting

List of HTTP status codes for success and failures.

Status Codes - Click to expand
Status Meaning
200 Ok Successful response, no errors.
400 Bad Request Request URI is malformed or does not meet one or more acceptance criteria. Check the "error" field for more details.
401 Unauthorized Either the user's access token is invalid or has expired.
403 Forbidden Requester does not have access to this resource.
429 Too Many Requests Rate limit of the requester has crossed maximum limits.
500 Internal Server Error Measure server encountered an unfortunate error. Report this to your server administrator.