v1.0REST API

API Reference

Programmatic access to the BeforeMerge knowledge base — rules, skills, collections, and cross-content search. Use the API to pull rules into your own tooling, build integrations, or automate code review workflows.

OpenAPI 3.1 spec (JSON)·Base URL: https://www.beforemerge.com/api/v1/public

Authentication

Every request must include an API key in the Authorization header using the Bearer scheme. API keys are created in your organization's settings and begin with the bm_ prefix.

http
Authorization: Bearer bm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Scopes

Each API key is issued with one or more scopes that control which endpoints it can access. Calling an endpoint without the required scope returns a 403 Forbidden.

ScopeGrants access to
read:rulesGET /rules, GET /rules/{slug}
read:skillsGET /skills, GET /skills/{slug}
read:collectionsGET /collections, GET /collections/{slug}
searchGET /search

Rate limits

The API enforces a limit of 100 requests per minute per API key using a token bucket algorithm. Exceeding the limit returns 429 Too Many Requests.

Every response includes rate limit headers so you can track your usage:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute (always 100).
X-RateLimit-RemainingRequests remaining in the current window.
X-RateLimit-ResetUnix timestamp (seconds) when the window resets.

Endpoints

All endpoints are read-only (GET). Responses are JSON. Paginated list endpoints share a common meta shape; detail endpoints return a single data object.

GET/rules

List rules

Scope:read:rules

Returns a paginated list of published public rules sorted alphabetically by title. Supports filtering by category, impact level, associated skill, and tags.

Query parameters

ParameterTypeDescription
searchstringCase-insensitive substring search against title and description.
categorystringFilter by category. One of: security, performance, architecture, quality.
impactstringFilter by impact level. One of: CRITICAL, HIGH, MEDIUM, LOW (case-insensitive).
skillstringFilter by skill slug (the {short_id}-{slug} format returned by the skills endpoints).
tagsstringComma-separated tag names. Returns rules matching any of the provided tags.
pageintegerPage number, 1-indexed. Default: 1.
limitintegerResults per page, 1–100. Default: 20.
curl
curl https://www.beforemerge.com/api/v1/public/rules \
  -H "Authorization: Bearer bm_your_key_here" \
  -G \
  --data-urlencode "category=security" \
  --data-urlencode "impact=HIGH" \
  --data-urlencode "limit=5"
json
{
  "data": [
    {
      "slug": "abc12345-avoid-raw-sql-in-server-actions",
      "title": "Avoid raw SQL in Server Actions",
      "description": "Raw SQL queries in Server Actions bypass Row Level Security.",
      "impact": "HIGH",
      "impact_description": "An attacker could extract or modify any row in the database.",
      "category": "security",
      "effort_level": "low",
      "skill": {
        "slug": "def67890-next-js-security",
        "name": "Next.js Security"
      },
      "likes_count": 12,
      "views_count": 340,
      "created_at": "2024-11-01T09:00:00Z",
      "updated_at": "2025-01-15T14:22:00Z"
    }
  ],
  "meta": {
    "total": 142,
    "page": 1,
    "limit": 5,
    "hasMore": true
  }
}
GET/rules/{slug}

Get a rule

Scope:read:rules

Returns full detail for a single rule. The slug is the combined {short_id}-{slug} value returned by the list endpoint (e.g. abc12345-avoid-raw-sql-in-server-actions). Includes the full Markdown body, detection patterns, and tags.

Path parameters

ParameterTypeDescription
slug*stringCombined {short_id}-{slug} identifier for the rule.
curl
curl https://www.beforemerge.com/api/v1/public/rules/abc12345-avoid-raw-sql-in-server-actions \
  -H "Authorization: Bearer bm_your_key_here"
json
{
  "data": {
    "slug": "abc12345-avoid-raw-sql-in-server-actions",
    "title": "Avoid raw SQL in Server Actions",
    "description": "Raw SQL queries in Server Actions bypass Row Level Security.",
    "impact": "HIGH",
    "impact_description": "An attacker could extract or modify any row in the database.",
    "category": "security",
    "effort_level": "low",
    "body": "## What to look for\n\nServer Actions that build SQL strings with template literals...",
    "detection_grep": "sql`|db.query(",
    "detection_semgrep": "rules:\n  - id: raw-sql-server-action\n    ...",
    "skill": {
      "slug": "def67890-next-js-security",
      "name": "Next.js Security",
      "description": "Security patterns for Next.js applications."
    },
    "tags": [
      { "name": "sql", "slug": "sql" },
      { "name": "supabase", "slug": "supabase" }
    ],
    "likes_count": 12,
    "views_count": 340,
    "created_at": "2024-11-01T09:00:00Z",
    "updated_at": "2025-01-15T14:22:00Z"
  }
}
GET/skills

List skills

Scope:read:skills

Returns a paginated list of published public skills, sorted alphabetically by name. Skills are installable bundles of rules scoped to a framework or domain.

Query parameters

ParameterTypeDescription
searchstringCase-insensitive substring search against name and description.
pageintegerPage number, 1-indexed. Default: 1.
limitintegerResults per page, 1–100. Default: 20.
curl
curl https://www.beforemerge.com/api/v1/public/skills \
  -H "Authorization: Bearer bm_your_key_here"
json
{
  "data": [
    {
      "slug": "def67890-next-js-security",
      "name": "Next.js Security",
      "description": "Security review patterns for Next.js applications using the App Router.",
      "version": "1.2.0",
      "likes_count": 45,
      "views_count": 1280,
      "created_at": "2024-10-15T08:00:00Z",
      "updated_at": "2025-02-01T11:00:00Z"
    }
  ],
  "meta": {
    "total": 12,
    "page": 1,
    "limit": 20,
    "hasMore": false
  }
}
GET/skills/{slug}

Get a skill

Scope:read:skills

Returns full detail for a single skill, including the Markdown body, the count of associated published rules, and tags.

Path parameters

ParameterTypeDescription
slug*stringCombined {short_id}-{slug} identifier for the skill.
curl
curl https://www.beforemerge.com/api/v1/public/skills/def67890-next-js-security \
  -H "Authorization: Bearer bm_your_key_here"
json
{
  "data": {
    "slug": "def67890-next-js-security",
    "name": "Next.js Security",
    "description": "Security review patterns for Next.js applications using the App Router.",
    "version": "1.2.0",
    "body": "# Next.js Security Skill\n\nThis skill covers...",
    "rules_count": 18,
    "tags": [
      { "name": "next.js", "slug": "next-js" },
      { "name": "react", "slug": "react" }
    ],
    "likes_count": 45,
    "views_count": 1280,
    "created_at": "2024-10-15T08:00:00Z",
    "updated_at": "2025-02-01T11:00:00Z"
  }
}
GET/collections

List collections

Scope:read:collections

Returns a paginated list of published public collections. Featured collections appear first; the remainder are sorted alphabetically by name.

Query parameters

ParameterTypeDescription
searchstringCase-insensitive substring search against name and description.
pageintegerPage number, 1-indexed. Default: 1.
limitintegerResults per page, 1–100. Default: 20.
curl
curl https://www.beforemerge.com/api/v1/public/collections \
  -H "Authorization: Bearer bm_your_key_here"
json
{
  "data": [
    {
      "slug": "ghi11223-owasp-top-10",
      "name": "OWASP Top 10",
      "description": "Rules mapped to the OWASP Top 10 web application security risks.",
      "item_count": 24,
      "views_count": 890,
      "install_count": 63,
      "is_featured": true,
      "created_at": "2024-12-01T00:00:00Z",
      "updated_at": "2025-03-01T09:00:00Z"
    }
  ],
  "meta": {
    "total": 8,
    "page": 1,
    "limit": 20,
    "hasMore": false
  }
}
GET/collections/{slug}

Get a collection

Scope:read:collections

Returns full detail for a single collection, including all items. Items are sorted by sort_order and include a content object with the slug and title/name of the linked rule, skill, knowledge item, or prompt.

Path parameters

ParameterTypeDescription
slug*stringCombined {short_id}-{slug} identifier for the collection.
curl
curl https://www.beforemerge.com/api/v1/public/collections/ghi11223-owasp-top-10 \
  -H "Authorization: Bearer bm_your_key_here"
json
{
  "data": {
    "slug": "ghi11223-owasp-top-10",
    "name": "OWASP Top 10",
    "description": "Rules mapped to the OWASP Top 10 web application security risks.",
    "item_count": 2,
    "views_count": 890,
    "install_count": 63,
    "is_featured": true,
    "items": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "content_type": "rule",
        "sort_order": 1,
        "content": {
          "slug": "abc12345-avoid-raw-sql-in-server-actions",
          "title": "Avoid raw SQL in Server Actions"
        }
      },
      {
        "id": "660e8400-e29b-41d4-a716-446655440001",
        "content_type": "skill",
        "sort_order": 2,
        "content": {
          "slug": "def67890-next-js-security",
          "name": "Next.js Security"
        }
      }
    ],
    "created_at": "2024-12-01T00:00:00Z",
    "updated_at": "2025-03-01T09:00:00Z"
  }
}

Error handling

All errors follow a consistent shape with a machine-readable code and a human-readable message.

json
{
  "error": {
    "code": "unauthorized",
    "message": "Missing Authorization header. Use: Authorization: Bearer bm_..."
  }
}
StatusCodeWhen it occurs
400bad_requestA required parameter is missing or invalid (e.g. missing q on /search).
401unauthorizedAuthorization header is missing, malformed, invalid, revoked, or expired.
403forbiddenAPI key is valid but lacks the required scope for this endpoint.
404not_foundThe requested resource does not exist or is not publicly visible.
429rate_limitedMore than 100 requests in a 60-second window for this API key.
500internal_errorAn unexpected server-side error occurred.