Back to home

Mite developer docs

SDK, REST API, authentication, errors, rate limits, and webhooks

Mite is in-app feedback and release notes for Expo and React Native apps. Your
app sends bug reports, feature requests, and user identities to the Mite API;
you triage them in the Mite dashboard and publish release notes back to the
same app.

This page is the developer index: SDK, REST API, authentication, errors, rate
limits, webhooks, and the machine-readable files that describe all of it.

Quickstart

  1. Create an app in the Mite dashboard and generate
    an API key under Settings → Keys.
  2. Install the SDK in your Expo or React Native app.
  3. Submit your first bug report.
npm install @usemite/mite-sdk
import { Mite, MiteProvider, useBugReport } from '@usemite/mite-sdk'

const mite = new Mite({ apiKey: 'mite_ak_...' })
mite.init()

// Wrap your app once:
<MiteProvider miteInstance={mite}>{/* Your app */}</MiteProvider>

// Then submit bugs from anywhere:
const { submitBugReport } = useBugReport()
await submitBugReport({
  title: 'Something broke',
  description: 'What the user saw',
})

SDK

The React Native and Expo SDK is published as
@usemite/mite-sdk. It wraps every
endpoint below, collects device and app context, and retries safely. Use it
unless you have a reason to call the API directly.

Authentication

Every endpoint except /api/v1/health needs a Mite API key, sent as a bearer
token:

Authorization: Bearer mite_ak_...

Mite API keys are publishable, SDK-style tokens, like a Sentry DSN or a PostHog
project key. They ship inside your mobile binary and anyone can extract them
from a shipped APK or IPA, so they are not secrets. Mite handles abuse with
per-key rate limits and instant revocation instead of secrecy. Never use a Mite
key as a substitute for your own user authentication.

Each key carries scopes:

Scope Grants
read List releases, announcements, feature requests
write Submit bug reports, feature requests, votes, identities

A request with the wrong scope is refused with 403.

Base URL

https://intent-okapi-412.convex.site

API endpoints

Method Path Scope Purpose
GET /api/v1/health none Liveness probe
POST /api/v1/bug-reports write Submit a bug report
POST /api/v1/upload-url write Create a single-use attachment upload URL
POST /api/v1/identify write Create or update an end-user profile
GET /api/v1/releases read List published releases
GET /api/v1/announcements read List active announcements
GET /api/v1/feature-requests read List feature requests
POST /api/v1/feature-requests write Submit a feature request
POST /api/v1/feature-requests/vote write Toggle a vote
GET /api/v1/feature-requests/votes read List one voter's votes
GET /getImage read Fetch a stored attachment

Every path also answers OPTIONS for CORS preflight.

The full request and response schema for each endpoint is published as OpenAPI
3.1 at usemite.com/openapi.json.

Submit a bug report

curl -X POST https://intent-okapi-412.convex.site/api/v1/bug-reports \
  -H "Authorization: Bearer mite_ak_..." \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Crash when opening the Profile tab",
    "description": "The app closes immediately after tapping Profile.",
    "app_version": "1.4.2",
    "device_info": { "model": "iPhone 15", "os": "iOS 18.2" }
  }'
{ "id": "j57...", "status": "NEEDS_TRIAGE" }

Errors

Every failure returns JSON, never HTML. Branch on code, not on error.

{
  "error": "API key is missing the required 'write' scope",
  "code": "forbidden",
  "hint": "Create a key with the write scope in Settings → Keys, or use an existing key that has it."
}
Status code Meaning
400 invalid_request Malformed JSON, or a field failed validation
401 unauthorized Missing, malformed, or unknown API key
402 REPORT_QUOTA_EXCEEDED The plan's monthly report allowance is used up
402 STORAGE_QUOTA_EXCEEDED The plan's attachment storage is used up
403 forbidden The key lacks the scope the endpoint needs
404 not_found No such resource for this application
413 payload_too_large The request body is larger than 256 KB
429 rate_limited Per-key rate limit exceeded
500 internal_error Unexpected server error

A quota refusal is 402, never 429. A 429 tells a client to retry; a
monthly quota cannot improve by retrying, only by changing plan. Quota
responses carry a quota object with limit, used, and resets_at.

Rate limits

Limits are per API key, as a token bucket refilled every minute.

Endpoint Requests per minute
/api/v1/bug-reports 60
/api/v1/upload-url 30
/api/v1/identify 120
/api/v1/releases 120
/api/v1/announcements 120
/api/v1/feature-requests (GET) 120
/api/v1/feature-requests (POST) 30
/api/v1/feature-requests/vote 60
/api/v1/feature-requests/votes 120
/getImage 300

A refused request returns 429 with a Retry-After header in seconds.

Webhooks

Mite posts outgoing notifications to Discord and Slack. Add an incoming webhook
URL under Settings → Webhooks in the dashboard and choose which events fire:

  • a new bug report arrives
  • a bug report changes status
  • a new feature request arrives

Discord URLs must start with https://discord.com/api/webhooks/ and Slack URLs
with https://hooks.slack.com/services/. Mite does not accept inbound webhooks.

Machine-readable resources

Resource What it is
/openapi.json OpenAPI 3.1 description of the API
/llms.txt Index of Mite's pages for agents
/sitemap.xml Every public page
/docs.md This page as Markdown
/api/v1 API discovery document

Every public page also answers Accept: text/markdown with a Markdown
rendition of itself, and advertises it with a Link: rel="alternate" header.

Support

Open an issue on github.com/usemite/mite-sdk
for SDK problems, or use the in-app feedback widget in the Mite dashboard.