miatz™
Verify a credentialLog inSit ChuunSit Chuun
  • Learners
  • Mentors
  • Business
CoursesApplied AIProgramResidencyPlaygroundsWar RoomsXookAtlasReadiness Check
miatz

The AI-era engineering institute. The machines got fast — we train the drivers. Real work, a daily loop that compounds, and a record that proves you can think.

Toggle theme
Explore
  • Courses
  • Applied AI
  • Program
  • Residency
  • Playgrounds
  • War Rooms
  • Xook
  • Atlas
  • Readiness Check
  • Tokenizer Lab
  • Chunking Lab
  • Prompt Anatomy
  • Calibration Lab
  • All playgrounds →
Learn
  • Courses
  • The Method
  • The Residency
  • Chuun · Entrance Examination
  • Manifesto
  • The Itz'at credential
  • Verified engineers
  • Playground Catalog
  • AI Use-Case Atlas
  • AI Readiness Check
  • Guides
  • Glossary
  • Compare approaches
  • Blog
  • What's New
For teams
  • For Students
  • For Mentors
  • For Business
  • Classroom migration
  • Miatz Index
  • API reference
  • Sit Chuun
  • Log in
Company
  • About
  • Experts
  • Why it's free
  • Pricing
  • FAQ
  • Contact
  • Privacy Policy
  • Terms of Service
  • Your data & privacy requests
  • Grievance redressal
  • Security & disclosure
  • Subprocessors
  • Data Processing Agreement
Take miatz with you

The Android app is live. iOS is on the way.

Available on AndroidGet it on Google Play
Not yet on iPhoneiOS — use the web app

Miatz Private Limited

Registered office:
C-101, Lotus Tower, Arge Urban Bloom, 30/A, 4th Main, 2nd Stage, Yeswanthpur, Bengaluru, Karnataka 560022, India
CIN:
U62013KA2026PTC226418
GSTIN:
29AAVCM3922D1Z6
Phone:
+91 82802 73456
Email:
hello@miatz.com
Website:
miatz.com
Grievance Officer:
Aishwarya · aishwarya@miatz.com · replies within 30 days
© 2026 miatz · Miatz Private Limited · Built in Bangalore·PrivacyTerms

miatz™, Itz'at™, Tuukul™, T'aan™, Kanan™, Xook™ and Chuun™ are trademarks of Miatz Private Limited (registrations in progress) · what the names mean

miatz
Machine layer

The QA API Beta

Bugs and test cycles for every application under test, callable by machines: CI jobs, crons, dashboards and orchestrated agents. The contract below is generated from the spec this page serves, so the two can never disagree.

Base URL https://miatz.com/api/qa · verify against https://dev.miatz.com/api/qa first.

OpenAPI 3.1 spec (/api/openapi.yaml) — point a client generator or a viewer straight at it.

Authentication

One header, and scopes that never widen themselves

Send the credential as a bearer token. Read never implies write, and the scope is re-checked on every call — a tool list is a convenience, never a boundary.

bearerAuth
Either a `qa_` machine token or a Supabase access token. A browser session cookie also works. 120 requests/minute per credential.
orgSession
The Supabase browser session, which must belong to an owner or admin of the org. The GitHub connection endpoints take no other credential: a grant is repo write access for the whole tenant, so a machine token cannot start or undo one.
  • apps:read
  • bugs:read
  • bugs:write
  • comments:write
  • tests:write
  • github:write
Paging

Every list returns one page

A list that stops at the first page is a silently truncated sample, not an answer. Loop while has_more is true, sending cursor=<next_cursor> and every other parameter unchanged.

count
Rows in this page — never the size of the result set.
has_more
true means matching rows exist that this page did not show.
next_cursor
Send back as ?cursor= for the next page; null on the last.

The cursor is opaque — a keyset position over (sort column, id). Never parse one and never construct your own; a cursor this API did not issue is refused.

Reference

All 22 operations

Read straight from the spec at build time. If an endpoint is missing here, it is missing from the contract.

Apps under test

GET/api/qa/apps

Applications under test this credential can reach

An empty list means nothing is in scope for this credential, never that no apps exist.

query (query, string)
Filter on name or slug
limit (query, integer)
cursor (query, string)
The `next_cursor` from the previous page. Opaque — decode nothing from it and construct none of your own; it encodes a keyset position and the encoding is ours to change. Keep every other filter identical across a walk.
  • 200 · OK
  • 401 · No valid credential
  • 429 · Over 120 requests/minute

Bugs

GET/api/qa/bugs

List bugs, newest first

Use `updated_since` to poll — it returns only what moved. The default excludes closed and won't-fix bugs. Ordered on (created_at desc, id desc) and walked with `cursor`: while `has_more` is true there are older matching bugs this page did not show. A poller that stops at the first page silently loses the rest of its backlog.

app (query, string)
App slug or uuid
workflow_state (query, WorkflowState[])
Repeatable, or comma-separated
severity (query, Severity[])
priority (query, Priority[])
assignee_id (query, string)
mine (query, boolean)
Only bugs the calling person reported. User sessions only.
updated_since (query, string)
include_closed (query, boolean)
limit (query, integer)
cursor (query, string)
The `next_cursor` from the previous page. Opaque — decode nothing from it and construct none of your own; it encodes a keyset position and the encoding is ours to change. Keep every other filter identical across a walk.
  • 200 · OK
  • 401 · No valid credential
  • 403 · The credential is missing a required scope
POST/api/qa/bugs

File a bug

steps, expected and actual are required. A report without them cannot be verified, so it is refused rather than accepted.

Body: NewBug

  • 200 · Filed
  • 400 · The request body failed validation
  • 403 · The credential is missing a required scope
GET/api/qa/bugs/{id}

One bug with its whole comment thread

  • 200 · OK
  • 404 · Not found, or outside this credential's scope (the two are indistinguishable by design)
PATCH/api/qa/bugs/{id}

Move a bug through its lifecycle, or re-grade it

A state change with no `comment` still writes one automatically. A non-staff reporter may send only `comment`.

Body: object

  • 200 · Updated
  • 400 · The request body failed validation
  • 404 · Not found, or outside this credential's scope (the two are indistinguishable by design)
POST/api/qa/bugs/{id}/github

Mirror the bug as a GitHub issue, or attach an existing one

Needs a GitHub repo_url on the app. The credential is resolved per bug, tenant first: (1) the GitHub App installation of the org the bug belongs to, which ALWAYS wins so one customer's connection can never reach another's repos; (2) GITHUB_QA_TOKEN / GITHUB_TOKEN, the platform's own credential, and only for repos owned by GITHUB_QA_PLATFORM_OWNERS — a tenant admin may set repo_url freely, so without that fence they could borrow our access; (3) neither, which is the 503, naming which of the two is missing and for whom. An existing_ref is verified against the GitHub API, not trusted.

Body: object

  • 200 · Linked
  • 400 · The request body failed validation
  • 503 · The GitHub bridge is not configured on this deployment

Comments

GET/api/qa/bugs/{id}/comments

The thread, oldest first

  • 200 · OK
POST/api/qa/bugs/{id}/comments

Append to the thread

Machine comments are attributed to the credential, never to a person.

Body: object

  • 200 · Posted

Test cycles

GET/api/qa/cycles

Recent test cycles, newest first

Ordered on (started_at desc, id desc) and walked with `cursor` while `has_more` is true.

app (query, string)
status (query, CycleStatus[])
limit (query, integer)
cursor (query, string)
The `next_cursor` from the previous page. Opaque — decode nothing from it and construct none of your own; it encodes a keyset position and the encoding is ours to change. Keep every other filter identical across a walk.
  • 200 · OK
POST/api/qa/cycles

Open a test cycle

Body: object

  • 200 · Opened
GET/api/qa/cycles/{id}

One cycle with every case outcome

  • 200 · OK
POST/api/qa/cycles/{id}/results

Post case outcomes, optionally closing the cycle

Totals and the final status are recomputed server-side from the stored rows, never taken from the caller. Any fail or blocked case ⇒ failed.

Body: object

  • 200 · Recorded

GitHub bridge

GET/api/qa/github/connect

Start a tenant's GitHub App installation

A browser redirect, not a machine call: it sends an owner or admin of `orgId` to GitHub's install page for the miatz app, where THEY choose which of their own repositories to grant. The org travels onward inside a signed, expiring `state`, never re-read from the callback's query string.

orgId (query, string, required)
  • 302 · Redirect to GitHub's installation page
  • 400 · The request body failed validation
  • 401 · No valid credential
  • 403 · The credential is missing a required scope
GET/api/qa/github/callback

Where GitHub returns after an install

Called by GitHub, never by an integrator. The signed `state` must verify AND the caller must STILL hold owner/admin on that org; the installation's account is read from GitHub, not from the query string. Every outcome is a redirect to /org/integrations — a JSON body would be shown as raw text in the browser the person landed in.

state (query, string)
The signed
installation_id (query, integer)
setup_action (query, install · update)
`update` with no installation_id is a Configure visit, not a new install
  • 302 · Redirect to /org/integrations — `?github=connected&account=…` when the installation was recorded, `?error=…` otherwise.
DELETE/api/qa/github/installations/{id}

Forget a GitHub connection

Removes OUR record so the bridge stops using it. It deliberately does NOT uninstall the app on GitHub: the grant belongs to the customer's GitHub organization, and revoking it from our side would misrepresent who controls it. The response says where to finish the removal.

orgId (query, string, required)
  • 200 · Forgotten
  • 400 · The request body failed validation
  • 401 · No valid credential
  • 403 · The credential is missing a required scope

feedback

GET/api/qa/feedback

List one feedback stream, newest first

The four person-submitted streams from the capture endpoint — support tickets, product feedback, suggestions and public bug reports — fenced per tenant. A credential scoped to apps sees only items stamped with an app it can reach; a platform-wide credential sees everything, including the shared pool of items filed before the fence existed. `not_yet_available: true` means the caller is a tenant credential and this deployment has not applied the fence yet: the page is empty ON PURPOSE. A tenant is never shown the unfenced table. Ordered on (updated_at desc, id desc) and walked with `cursor`; use `updated_since` to poll.

stream (query, FeedbackStream, required)
status (query, string[])
That stream's own vocabulary. Repeatable, or comma-separated.
app_id (query, string)
updated_since (query, string)
limit (query, integer)
cursor (query, string)
The `next_cursor` from the previous page. Opaque — decode nothing from it and construct none of your own; it encodes a keyset position and the encoding is ours to change. Keep every other filter identical across a walk.
  • 200 · OK
  • 400 · The request body failed validation
  • 401 · No valid credential
  • 403 · The credential is missing a required scope
GET/api/qa/feedback/{stream}/{id}

One feedback item in full

  • 200 · OK
  • 404 · Not found, or outside this credential's scope (the two are indistinguishable by design)
PATCH/api/qa/feedback/{stream}/{id}

Move an item through its stream's own lifecycle

Each stream has its own status vocabulary (a suggestion goes open → under_review → planned → in_build → shipped; a ticket goes open → in_progress → waiting_on_submitter → resolved → closed). A value outside that stream's vocabulary is refused and the allowed values are named. An item outside the caller's fence is a 404, never a silent no-op.

Body: object

  • 200 · Updated
  • 400 · The request body failed validation
  • 403 · The credential is missing a required scope
  • 404 · Not found, or outside this credential's scope (the two are indistinguishable by design)

MCP

POST/api/qa/mcp

The QA remote MCP server (JSON-RPC 2.0, Streamable HTTP)

Stateless single-response mode. `tools/list` advertises only the tools the calling credential can run, and the dispatcher re-checks the scope before every call — a tool list is a convenience, never the boundary. A TOOL failure comes back 200 with `isError` so the agent can read the reason and adapt; only parse and auth failures use a transport status. Add it to a repo's agent with `claude mcp add --transport http miatz-qa https://miatz.com/api/qa/mcp --header "Authorization: Bearer qa_…"`.

Body: RpcRequest

  • 200 · A JSON-RPC result, including a tool call that failed
  • 202 · A notification was accepted; there is no body
  • 400 · Unparseable JSON-RPC, or an unknown method
  • 401 · No valid credential (JSON-RPC error -32001)
  • 429 · Over 120 requests/minute (JSON-RPC error -32002)

Credentials

GET/api/qa/tokens

Every QA credential, without its hash

Super admin only.

  • 200 · OK
  • 403 · The credential is missing a required scope
POST/api/qa/tokens

Mint a credential

Super admin only. The plaintext is returned EXACTLY ONCE and cannot be recovered. created_by is who machine-filed bugs are attributed to.

Body: object

  • 200 · Minted
DELETE/api/qa/tokens/{id}

Revoke a credential (soft — attribution survives)

  • 200 · Revoked
  • 403 · The credential is missing a required scope
Errors

The whole failure vocabulary

Every response is { "ok": true, … } or { "error": "…" } with a status. Provider text is never echoed back to you.

401 · Unauthorized
No valid credential
403 · Forbidden
The credential is missing a required scope
404 · NotFound
Not found, or outside this credential's scope (the two are indistinguishable by design)
400 · Invalid
The request body failed validation
429 · RateLimited
Over 120 requests/minute

Closed vocabularies

Severity
low · medium · high · critical
Priority
p0 · p1 · p2 · p3
WorkflowState
open · triaged · in_progress · fixed · verified · closed · wont_fix · duplicate · cannot_reproduce
TriageStatus
pending · valid · invalid · duplicate
CycleKind
manual · ci · agent · regression · smoke · e2e
CycleStatus
running · passed · failed · cancelled
CaseResult
pass · fail · skip · blocked
FeedbackStream
ticket · feedback · suggestion · bug_report
MCP

Add the server to any repo's agent

One command, and your agent has the whole surface. tools/list advertises only what the calling credential can run, and the dispatcher re-checks the scope before every call.

claude mcp add --transport http miatz-qa \
  https://miatz.com/api/qa/mcp \
  --header "Authorization: Bearer qa_…"

Or commit it per repo, with the token coming from the environment:

{
  "mcpServers": {
    "miatz-qa": {
      "type": "http",
      "url": "https://miatz.com/api/qa/mcp",
      "headers": { "Authorization": "Bearer ${MIATZ_QA_TOKEN}" }
    }
  }
}

The server also ships prompts, so the method arrives with the connection and there is nothing to install or keep in sync:

  • triage_queue — survey the open queue, judge what is genuinely reproducible, and recommend one bug to start. Changes nothing.
  • fix_bug — work one bug end to end: reproduce it with a failing test first, stop and report if you cannot, run the full gate, and never touch migrations, CI, auth or payment paths.

Reproduction-first is the load-bearing rule. A test that passes before and after a change proves nothing, and an agent that writes one has encoded the bug as expected behaviour rather than fixing it.

Support tickets, product feedback and suggestions are tools too — list_feedback, get_feedback, update_feedback — behind their own feedback:* scopes and fenced to the apps a credential can reach, so a fixing agent and a product agent are different tokens.

Wire your CI to it

Mint a credential from the QA console, give the poller read-only scopes, and verify on dev.miatz.com before you point production at it.

Log in to mint a token Report a security issue