Key featuresFeaturesPricingSecurityDocsChangelog
Log inStart for free

Getting Started

  • What is QA Note?
  • Quick Start Guide
  • Install Extension
  • Project Members

Feature Guide

  • Screenshot & Annotation
  • Session Recording
  • Maintenance Reports
  • Issue State Model
  • Multi-issue Windows
  • Storage · DOM Snapshot

Integrations

  • GitHub
  • Commit Keys
  • MCP Server
  • Slack
  • Webhook
  • Vercel
  • Existing Playwright

API Reference

  • Authentication
  • Endpoint Reference
  • Public API v1
  • Error Handling

The issue tracker you use with your AI agent. Your agent fixes; QA Note keeps the record.

Made in Seoul · © 2026 QA Note
ProductKey featuresFeaturesPricingSecurityChangelog
ResourcesDocsMCP guideChrome Extension
CompanyBrandTerms of ServicePrivacy Policy

ffgg|CEO: Songwook Han

Business Registration No.: 746-54-00870[Verify]|E-Commerce License No.: 2024-Seoul Mapo-2178

Address: 5F, 26 World Cup buk-ro 6-gil, Mapo-gu, Seoul, Republic of Korea

Email: support@qanote.app|Hosting Provider: Vercel Inc.

© 2026 QA Note. All rights reserved.

Terms of ServicePrivacy PolicyCookie Policy
  1. Home
  2. /
  3. Docs
  4. /
  5. API Reference

Public API v1

REST API v1 reference for reading and managing QA Note projects and issues from external systems.

Table of Contents
  • Versioning policy
  • Authentication
  • Base URL · Request format
  • Endpoints (v1)
  • GET/api/v1/projects
  • GET/api/v1/projects/{projectId}/issues
  • GET/api/v1/projects/{projectId}/issues/{issueNumber}
  • PATCH/api/v1/projects/{projectId}/issues/{issueNumber}
  • POST/api/v1/projects/{projectId}/issues/{issueNumber}/comments
  • Error responses
  • Rate limits
  • Webhook vs API
  • Changelog
  • SDK · code samples
  • curl
  • JavaScript (fetch)
  • Node.js (with error handling)

Public API v1

The QA Note Public API v1 is a REST API for working with projects and issues from external systems. Every path is prefixed with /api/v1/, and breaking changes only ship under a new version (v2).

Internal endpoints used by the Extension (for example /api/extension/...) are out of scope for this document. See the Endpoint Reference for the full list and the Authentication page for issuing API keys.

Versioning policy

  • Stability guarantee: v1 response schemas and paths stay stable as long as the change is backward-compatible. Adding a new field is considered backward-compatible.
  • Breaking changes: removing a field, changing a type, or moving a path ships only with v2. v1 is supported in parallel for at least six months after v2 releases.
  • Change announcements: backward-incompatible changes are pre-announced in the Changelog and via dashboard notices.

Authentication

Public API v1 accepts an API Key or an MCP OAuth access token. API keys are recommended for CI/CD, headless servers, and external automation.

bash
curl https://qanote.app/api/v1/projects \
  -H "Authorization: Bearer qn_YOUR_API_KEY"
ItemValue
HeaderAuthorization: Bearer qn_...
Scope (read)projects:read · issues:read
Scope (write)issues:write
Issued fromDashboard → Org settings → API Keys

Each API key is bound to a single organization. Issue a separate key per organization if you need to access multiple. See the Authentication guide for details.

Base URL · Request format

https://qanote.app/api/v1
  • All requests and responses are UTF-8 JSON.
  • POST and PATCH requests must send Content-Type: application/json.
  • Timestamps are ISO 8601 (2025-03-15T14:30:00.000Z).

Endpoints (v1)

The full endpoint catalog lives in the Endpoint Reference. The endpoints below are the ones used most often from external integrations.

GET /api/v1/projects

Returns the projects in the organization the API key was issued for.

Required scope: projects:read

Query parameters

NameTypeRequiredDescription
organizationSlugstringNoFilter by organization slug (the slug in /dashboard/<slug>/...)
organizationIdstring (uuid)NoFilter by organization id (alternative to organizationSlug)

Request

bash
curl https://qanote.app/api/v1/projects \
  -H "Authorization: Bearer qn_YOUR_API_KEY"

Response

json
{
  "data": [
    {
      "id": "project_abc123",
      "name": "Web Service",
      "slug": "web-service",
      "description": null,
      "organizationId": "2a3f7b04-6e91-4c2d-9f77-3d6c9a1e4b58",
      "organizationSlug": "acme",
      "organizationName": "Acme Inc.",
      "createdAt": "2025-01-15T09:00:00.000Z"
    }
  ]
}

GET /api/v1/projects/{projectId}/issues

Lists issues in a project with pagination and filtering. The response keeps the body light (LLM token-friendly) and exposes only the core fields.

Required scope: issues:read

Query parameters

NameTypeRequiredDescription
statusstringNoopen · in_progress · blocked · fix_submitted · verified · closed
prioritystringNolow · medium · high · critical
qstringNoSearch across title and description
labelstringNoFilter by label name
pagenumberNoPage number (default 1)
limitnumberNoItems per page (default 20, max 100)

Request

bash
curl "https://qanote.app/api/v1/projects/PROJECT_ID/issues?status=open&limit=20" \
  -H "Authorization: Bearer qn_YOUR_API_KEY"

Response

json
{
  "data": [
    {
      "id": "issue_xyz",
      "issueNumber": 42,
      "title": "TypeError raised when submitting password on /login",
      "status": "open",
      "priority": "high",
      "labels": ["bug", "auth"],
      "assignees": ["Jee Lee"],
      "createdAt": "2025-03-15T14:30:00.000Z",
      "updatedAt": "2025-03-15T14:30:00.000Z"
    }
  ],
  "total": 42,
  "page": 1,
  "totalPages": 3
}

GET /api/v1/projects/{projectId}/issues/{issueNumber}

Fetches a single issue. The response includes a metadata summary (console error count, network error count, JS error count). Detailed metadata bodies live behind dedicated endpoints (console-logs, network-logs, etc.).

Required scope: issues:read

bash
curl https://qanote.app/api/v1/projects/PROJECT_ID/issues/42 \
  -H "Authorization: Bearer qn_YOUR_API_KEY"

PATCH /api/v1/projects/{projectId}/issues/{issueNumber}

Updates the status or priority of an issue. Useful for external automation — e.g. a GitHub Actions workflow that flips an issue to resolved on merge.

Required scope: issues:write

Request body

NameTypeRequiredDescription
statusstringNoNew status. verified requires a human web/extension session; closed is report-publish only.
prioritystringNoNew priority
bash
curl -X PATCH https://qanote.app/api/v1/projects/PROJECT_ID/issues/42 \
  -H "Authorization: Bearer qn_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "in_progress"}'

POST /api/v1/projects/{projectId}/issues/{issueNumber}/comments

Adds a comment to an issue. Useful for external bots — e.g. a deploy notifier that comments on the related issue.

Required scope: issues:write

bash
curl -X POST https://qanote.app/api/v1/projects/PROJECT_ID/issues/42/comments \
  -H "Authorization: Bearer qn_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content": "Reproduced this on the Preview deployment."}'

Creating new issues is not part of Public API v1. Issues authored through the Extension, reporter submissions, or the dashboard can be read and updated through this API.

Error responses

All errors return a standard HTTP status code and a JSON body. The body shape and code-by-code meaning are documented in Error Handling.

json
{
  "error": "Insufficient scope"
}

Validation failures include a details array.

json
{
  "error": "Invalid input",
  "details": [
    { "field": "status", "message": "Invalid enum value." }
  ]
}
StatusMeaning
200 · 201Success
400Bad request body or query
401Authentication failed (missing or expired API key)
403Insufficient scope
404Resource not found or belongs to another organization
429Rate limit exceeded
500Internal server error

Rate limits

LimitValue
Per minute100 req/min per API key (sliding window)
Auth attempts5 per 15 minutes

When the limit is exceeded the API returns 429 Too Many Requests. Honor the Retry-After (seconds) header or apply exponential backoff.

bash
# Example response headers
HTTP/2 429
Retry-After: 32

Webhook vs API

Use caseRecommended
Receive events (issue created, status changed, …)Webhook
Active queries · status updates · commentsPublic API v1
Calls from AI coding toolsMCP Server (OAuth)

Webhooks are a one-way push from QA Note to your system. Use this API when your system needs to pull data or push changes on its own.

Changelog

VersionDateChanges
v1.02026-04Initial public release — /projects, /issues, /comments, plus 13 metadata endpoints

Backward-incompatible changes are added to this table as they ship.

SDK · code samples

curl

bash
curl https://qanote.app/api/v1/projects \
  -H "Authorization: Bearer qn_YOUR_API_KEY"

JavaScript (fetch)

ts
const res = await fetch("https://qanote.app/api/v1/projects", {
  headers: { Authorization: `Bearer ${process.env.QANOTE_API_KEY}` },
});
const { data } = await res.json();

Node.js (with error handling)

ts
async function listOpenIssues(projectId: string) {
  const res = await fetch(
    `https://qanote.app/api/v1/projects/${projectId}/issues?status=open`,
    { headers: { Authorization: `Bearer ${process.env.QANOTE_API_KEY}` } },
  );

  if (res.status === 429) {
    const retryAfter = Number(res.headers.get("retry-after") ?? 30);
    throw new Error(`Rate limited. Retry after ${retryAfter}s`);
  }
  if (!res.ok) {
    const body = await res.json().catch(() => ({}));
    throw new Error(body.error ?? `HTTP ${res.status}`);
  }

  const { data } = await res.json();
  return data;
}

The complete endpoint specification continues in the Endpoint Reference.

Previous
Endpoint Reference
Next
Error Handling

Table of Contents

  • Versioning policy
  • Authentication
  • Base URL · Request format
  • Endpoints (v1)
  • GET/api/v1/projects
  • GET/api/v1/projects/{projectId}/issues
  • GET/api/v1/projects/{projectId}/issues/{issueNumber}
  • PATCH/api/v1/projects/{projectId}/issues/{issueNumber}
  • POST/api/v1/projects/{projectId}/issues/{issueNumber}/comments
  • Error responses
  • Rate limits
  • Webhook vs API
  • Changelog
  • SDK · code samples
  • curl
  • JavaScript (fetch)
  • Node.js (with error handling)