# Apira Docs > Public documentation for Apira, the semantic search API for GitHub repositories built for AI agents. ## API Reference Apira keeps exact endpoint schemas in generated OpenAPI, not in hand-written guide pages. ### Canonical sources Use these sources when you need the current request and response contract: * [Interactive API reference](https://api.apira.dev/docs): Scalar UI for exploring endpoints. * [OpenAPI JSON](https://api.apira.dev/.well-known/openapi.json): machine-readable OpenAPI 3.1 schema. * [`/llms.txt`](https://api.apira.dev/llms.txt): plain-text API guide for AI agents. The Vocs docs explain how to use Apira. The OpenAPI document is the source of truth for exact endpoint field names, validation rules, and documented response schemas. Operational/global errors are summarized in these docs when they are not endpoint-specific. ### Primary search endpoint The main public search endpoint is: ```txt POST /v1/github/search ``` Authenticated requests use the `X-API-Key` header. For coding-agent setup, see [Apira for Coding Agents](/guides/apira-for-coding-agents). For companion skill/workflow templates, see [Follow-on Skills](/guides/follow-on-skills). ### Avoid schema drift When building clients, agents, or tests, fetch the OpenAPI document instead of copying endpoint schemas from these narrative docs. ## Errors and Rate Limits Apira returns structured JSON errors so agents can decide whether to revise the request, retry later, or stop and ask for operator action. ### Error envelope Errors use this shape: ```json { "error": { "code": "VALIDATION_ERROR", "message": "query is required", "status": 400 } } ``` Validation errors may also include a `details` array with field-level information. ### Common status codes | Status | Code | Meaning | Agent behavior | | ------ | ------------------------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | | `400` | `VALIDATION_ERROR` | Request body or parameters failed validation. | Revise the tool arguments before retrying. | | `401` | `AUTH_ERROR` | The API key is missing or invalid. | Stop and ask the operator to configure a valid key. | | `403` | `FORBIDDEN` or `INSUFFICIENT_CREDITS` | The authenticated user is not allowed to perform the request, or the account has no available credits. | Stop retrying; report the permission or credit issue. | | `404` | `NOT_FOUND` | The requested resource does not exist. | Check the endpoint or URL. | | `429` | `RATE_LIMIT_EXCEEDED` | The request exceeded a configured rate limit. | Back off until `Retry-After`; preserve task state. | | `500` | `INTERNAL_ERROR` | An unexpected server error occurred. | Retry with jitter if the user task can wait, otherwise degrade gracefully. | | `502` | `EXTERNAL_SERVICE_ERROR` | An upstream service failed. | Retry with jitter or explain the upstream failure. | | `503` | `RATE_LIMIT_UNAVAILABLE` | The rate-limit backend is temporarily unavailable when configured to fail closed. | Retry later; do not spin in a tight loop. | ### Rate limits Default public limits are: * `30` requests per minute per IP, applied globally before authentication. * `60` requests per minute per authenticated user/account for search traffic. Authenticated search requests can therefore be constrained by both the global per-IP limit and the authenticated user/account limit. `429 RATE_LIMIT_EXCEEDED` responses include: * `X-RateLimit-Limit`: the limit for the current window. * `X-RateLimit-Remaining`: remaining requests in the current window. * `X-RateLimit-Reset`: Unix timestamp when the current window resets. * `Retry-After`: seconds to wait before retrying. `503 RATE_LIMIT_UNAVAILABLE` responses are limiter-backend failures and may include only `Retry-After`. ### Agent retry guidance Agents should retry only when the error is likely transient: * Retry `429`, `500`, `502`, and `503` with backoff and a maximum attempt count. * Do not retry `400` without changing the request. * Do not retry `401` or `403 INSUFFICIENT_CREDITS`; these need operator or account action. * Preserve the user's task state so the agent can resume after waiting. * Disclose degraded results if the agent falls back to a broader search, cached candidates, or no Apira call. For exact status codes and schemas, use the [OpenAPI JSON](https://api.apira.dev/.well-known/openapi.json). ## Apira for Coding Agents This page is the setup prompt. Use the built-in “Copy page for LLM” action to copy the whole page into your coding agent and create or update a reusable Apira skill for discovering relevant GitHub repositories. ### Goal You are adding Apira as a reusable skill or tool for this coding agent. Create or update an `apira` skill that lets the agent discover relevant GitHub repositories by semantic search before implementing unfamiliar, complex, or blocked work. Apira is a semantic search API for GitHub repositories, built for AI agents. Use it when you need to find repositories by describing implementation intent, architecture, library usage, or code patterns. ### When to use Apira Use Apira when: * You need existing open-source implementations before building something complex. * You are blocked on an implementation detail and need real repositories to study. * You need libraries, frameworks, tools, starter templates, or architecture examples. * You need alternatives to a known dependency or approach. Do not use Apira for: * Searching inside a known repository. * Fetching repository source files. * Non-GitHub web search. * Replacing license, security, or code-quality review. ### API key setup Read the API key from `APIRA_API_KEY`. Do not hard-code, print, or log the API key. Send it as the `X-API-Key` header. If `APIRA_API_KEY` is missing, explain how to configure it and stop before making requests. ```bash export APIRA_API_KEY="apira_your_key_here" ``` ### API contract * Base URL: `https://api.apira.dev` * Endpoint: `POST /v1/github/search` * Auth header: `X-API-Key: $APIRA_API_KEY` * Request fields: `query`, `limit`, `includeTree`, `filters` ### Request shape ```json { "query": "specific implementation pattern or repository capability", "limit": 10, "includeTree": false, "filters": { "language": "typescript", "categories": ["agent"], "topics": ["cli"], "minStars": 100, "maxStars": 50000, "excludeArchived": true, "staleAfterMonths": 18, "excludeRepos": ["owner/repo"] } } ``` ### Response shape ```json { "query": "specific implementation pattern or repository capability", "results": [ { "name": "owner/repo", "url": "https://github.com/owner/repo", "description": "Repository summary", "score": 0.82, "language": "TypeScript", "stars": 12000, "forks": 800, "topics": ["agent", "cli"], "pushedAt": "2026-04-01T00:00:00.000Z", "isArchived": false, "llmsUrl": "https://raw.githubusercontent.com/owner/repo/main/llms.txt", "evidence": ["Why this repository matched the query..."], "tree": ["optional repository tree entries when includeTree is true"] } ], "meta": { "total": 10, "appliedFilters": { "language": "typescript", "categories": { "mode": "explicit", "values": ["agent"] } } } } ``` ### Available request fields * `query` — required. Describe the behavior, architecture, implementation pattern, or repository capability you need. * `limit` — optional, 1–50. Use 5–10 for focused searches; use more only when comparing alternatives. * `includeTree` — optional. Set `true` when module layout matters before deeper inspection. * `filters.language` — exact GitHub language match. * `filters.categories` — repository type, such as `agent`, `tool`, `framework`, `library`, `infrastructure`, or `starter`. * `filters.topics` — owner-provided GitHub topics. * `filters.minStars` / `filters.maxStars` — maturity or niche bands. * `filters.excludeArchived` — exclude archived repositories. * `filters.staleAfterMonths` — freshness cutoff for active projects. * `filters.excludeRepos` — omit repositories already reviewed. ### Response fields to inspect * `results[].evidence` — why the repository matched the query. * `results[].score` — relative ranking score within this result set. * `results[].stars` / `results[].forks` — adoption signals. * `results[].pushedAt` / `results[].isArchived` — freshness and maintenance signals. * `results[].language` / `results[].topics` — ecosystem fit. * `results[].llmsUrl` — maintainer-authored agent documentation when available. * `results[].tree` — repository structure when `includeTree` is enabled. * `meta.appliedFilters` — constraints Apira actually applied. ### Search policy and best practices Use an intent-rich natural-language query. Describe what you need to learn or build, and prefer implementation descriptions over keyword lists. Good queries: * `minimal terminal coding agent harness` * `TypeScript coding agent CLI with tool execution` * `reference implementation of OAuth token metering middleware` * `Kubernetes cost monitoring controller` Weak queries: * `agent` * `terminal` * `auth` * `monitoring` Put behavior and architecture in `query`. Put non-negotiable constraints in `filters`. Avoid filtering out useful references too early. Read `meta.appliedFilters` before explaining a filtered result set. Treat each result as a candidate, not a final answer. Read `evidence` before recommending repositories. Shortlist repositories with rationale, caveats, and next inspection steps. Do not copy code blindly; license, security, fit, and code quality still need review. When results are empty, noisy, or low confidence: 1. Remove optional filters first. 2. Broaden overly specific wording. 3. Search adjacent concepts. 4. Use `excludeRepos` after reviewing candidates. 5. Tell the user when confidence is low instead of overstating the result. ### Retry and error behavior * On `400`, revise the request before retrying. * On `401` or `403` authentication errors, report that `APIRA_API_KEY` is missing or invalid. * On `403 INSUFFICIENT_CREDITS`, stop retrying and report the credit issue. * On `429`, back off and honor `Retry-After` when present. * On `500`, `502`, or `503`, retry with jitter and a small maximum attempt count. * Do not silently ignore failed searches. ### Test search After creating the skill, test it with this request if `APIRA_API_KEY` is available: ```json { "query": "minimal terminal coding agent harness", "limit": 10, "filters": { "language": "typescript", "categories": ["agent"], "minStars": 5000, "excludeArchived": true, "staleAfterMonths": 12 } } ``` Expected behavior: * The request succeeds when `APIRA_API_KEY` is set. * Results are GitHub repositories relevant to terminal/coding-agent harnesses. * The agent summarizes the top repositories and explains why they are relevant. * The agent reports caveats and recommends which repository to inspect next. ### Follow-on workflows Use Apira first to discover candidate repositories. For companion workflows, see [Follow-on Skills](/guides/follow-on-skills). ## Follow-on Skills These are follow-on skills we have found useful once your coding agent can search with Apira. Start with [Apira for Coding Agents](/guides/apira-for-coding-agents). Apira finds candidate repositories. The skills on this page help the agent inspect selected repositories with more depth. The shared shape is: 1. Use Apira to find candidate repositories. 2. Select one or a few candidates from the evidence. 3. Clone each selected repository locally. 4. The agent inspects the local clone with a focused methodology. 5. Return findings with source paths, caveats, and next actions. Cloning first matters. A local worktree gives the agent normal file tools for reading, grepping, following imports, and citing precise locations instead of relying on shallow web snippets. ### Install these in your agent harness Copy one of the skill recipes below into your coding agent and ask it to create the skill using the harness's native convention. Different harnesses store reusable instructions differently: * Pi uses skill files. * Claude Code may use skills or agent instructions. * Cursor may use rules. * Other agents may use tool registries, memory, or prompt files. Before creating files, the agent should inspect the local harness conventions and adapt the recipe to that format. Preserve the skill name, trigger conditions, workflow, methodology, and output contract. Do not force a specific storage format. If the harness supports named skills with frontmatter, use the suggested name and description. If it uses rules or prompt files, convert the same content into that format. ### Repo deep dive — your personal DeepWiki Use this when the agent needs top-down understanding of a selected repository. `repo-deepdive` clones the repository, explores the local files systematically, and returns an architectural explanation. Use it to understand module maps, design decisions, trade-offs, and how the system fits together before deciding what to copy or adapt. ```text Create a reusable skill named `repo-deepdive`. Use this harness's native skill, rule, or reusable-instruction format. If the harness supports frontmatter, use equivalent metadata: name: repo-deepdive description: Deep-dive on a selected GitHub repository after Apira finds candidate repos; clone locally, inspect top-down, and return architecture, module map, trade-offs, and cited source locations. Purpose: Give the agent top-down understanding of a selected repository after Apira finds candidate repos. Trigger when: - The user wants to understand how a selected repo works. - The user asks for architecture, module map, design trade-offs, extension points, or onboarding. - Apira returned a promising repo and the next step is top-down understanding. Do not use for: - Searching for candidate repos; use `apira` first. - Extracting copy-ready implementation snippets; use `repo-patterns`. - License, security, or dependency-risk review. Workflow: 1. Use `apira` to find repositories that solve a similar architectural problem. 2. Select 1-2 strong candidates based on evidence and maintenance signals. 3. Clone each selected repository locally before analysis. 4. Inspect the local clone with the methodology below. 5. Summarize architecture, module map, trade-offs, extension points, and risks. 6. Use the findings to inform the user's implementation plan. Best for: - Comparing architecture approaches. - Getting unstuck on complex subsystem design. - Understanding mature open-source implementations before building. - Building a top-down mental model of an unfamiliar repo. Methodology: 1. Skeleton pass: - Enumerate the file tree. Prefer `git ls-files`; otherwise use `find . -type f` excluding `.git`, `node_modules`, `dist`, `build`, `.venv`, lock files, and binaries. - If there are no files, stop with Stopping reason `empty repository`. - Read the highest-signal artifacts in one pass: root README plus stack manifests such as `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `build.gradle`, `Gemfile`, or `*.csproj`. - Rank 3-8 candidate files against the user's objective and record deferred candidates for `Files NOT explored`. 2. Focused read pass: - Use the cheapest tool that can answer the question: search paths first, search symbols or patterns next, read files only when needed. - Read as many files as the objective genuinely requires. - Prefer focused ranges for files over roughly 400 lines. - Never read generated artifacts, lock files, or vendored code unless the objective is specifically about them. 3. Synthesis and verification: - Lead with a short TL;DR. - Explain the architecture, key modules, data/control flow, design trade-offs, and risks relevant to the objective. - Cite specific files and lines for load-bearing claims. - Verify the most important cited line numbers with targeted searches before returning. - Be explicit about gaps and files not explored. Stopping behavior: - Stop when the objective is answered with verified citations. - If three consecutive searches or reads produce no new useful file, symbol, or pattern, stop and report the partial answer. Output schema: ### Answer A 2-3 sentence TL;DR, followed by the architectural explanation. Cite `path:LINE` or `path:LINE-LINE` for specific claims; cite whole files for README, manifests, or configs. ### Files explored - `path/to/file` — one-sentence reason ### Files NOT explored - `path/to/file` — one-sentence reason, or `None.` ### Open questions - Follow-ups for the caller, or `None.` ### Stopping reason One sentence: objective answered, no-progress, objective too broad, objective ambiguous, or empty repository. ``` ### Repo patterns — implementation pattern extraction Use this when the agent needs reusable implementation details from a selected repository. `repo-patterns` starts from concrete files and extracts named patterns, snippets, dependencies, and adaptation caveats. It is best when the user is likely to reuse a specific implementation technique. ```text Create a reusable skill named `repo-patterns`. Use this harness's native skill, rule, or reusable-instruction format. If the harness supports frontmatter, use equivalent metadata: name: repo-patterns description: Extract reusable implementation patterns from a selected GitHub repository after Apira finds candidate repos; clone locally, inspect bottom-up, and return named patterns, snippets, dependencies, and reuse caveats. Purpose: Extract reusable implementation patterns from a selected repository after Apira finds candidate repos. Trigger when: - The user wants reusable implementation patterns from a selected repo. - The user asks how a repo implements a specific concern. - Apira returned a promising repo and the next step is extracting snippets or adaptation guidance. Do not use for: - Searching for candidate repos; use `apira` first. - General architecture onboarding; use `repo-deepdive`. - Copying code without license, security, fit, and code-quality review. Workflow: 1. Use `apira` to find repositories matching the implementation pattern or dependency need. 2. Select 1-3 candidates based on evidence, maintenance signals, and ecosystem fit. 3. Clone each selected repository locally before analysis. 4. Inspect the local clone with the methodology below. 5. Extract reusable snippets, module boundaries, dependencies, and adaptation caveats. 6. Explain which patterns are reusable and what must change for the user's codebase. Best for: - Reusing implementation patterns. - Finding concrete snippets to adapt with review. - Understanding how a specific concern is implemented across files. What counts as a reusable pattern: A pattern is worth surfacing only if it passes all four checks: 1. Self-contained — fits in a single function, class, or file with a nameable interface. 2. Clear interface — has inputs and outputs another agent can name without reading the body. 3. Replicable shape — could plausibly be lifted into a different codebase with only type, dependency, or naming adjustments. Assembly patterns count when repo-specific glue wraps a reusable algorithm. 4. Concrete instance — a real symbol at a real path and line, not a paraphrase. If a candidate fails any check, drop it. Quality beats quantity. Methodology: 1. Skeleton pass: - Enumerate the file tree. Prefer `git ls-files`; otherwise use `find . -type f` excluding `.git`, `node_modules`, `dist`, `build`, `.venv`, lock files, and binaries. - If there are no files, stop with Stopping reason `empty repository`. - Read the highest-signal artifacts in one pass: root README plus stack manifests such as `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `build.gradle`, `Gemfile`, or `*.csproj`. - Rank files by likely pattern density. `utils`, `lib`, `helpers`, and single-purpose module-root files rank high; route definitions, dependency-injection wiring, generated code, and config-only files rank low unless they wrap a reusable algorithm. 2. Mining pass: - Use the cheapest useful tool: path search, then pattern search, then file reads. - Search for export shapes such as functions, classes, constants, decorators, and higher-order wrappers. - Skip pure glue, but mine glue when it contains a reusable algorithm or assembly pattern. - Concern-scoped prompts often surface 2-5 patterns from 4-10 files. Broad prompts may surface more, but no pattern should be included unless it passes the four checks. 3. Distill and verify: - For each surviving pattern, capture a short noun-phrase name, location, one-line shape, verbatim snippet, dependencies, variations, and reuse caveat. - For long patterns, show the signature plus the first and last relevant lines with a clear omission marker. - For assembly patterns, show the verbatim core algorithm and identify omitted project-specific wrapper code. - Verify each cited line with a targeted search before returning. If the citation cannot be verified, drop the pattern. Stopping behavior: - Stop when three consecutive mining searches or reads produce no new candidate pattern. - Report this as Stopping reason `yield-exhausted`. Output schema: ### Patterns For each pattern, most copy-worthy first: #### - **Where:** `path:LINE-LINE` - **Shape:** one-line interface description - **Snippet:** verbatim code block - **Dependencies:** packages, sibling modules, non-obvious built-ins, or `none — stdlib only` - **Variations:** related locations, if any - **Reuse caveat:** one sentence If no candidates survive, write `None — see Stopping reason.` ### Files explored - `path/to/file` — one-sentence reason ### Files NOT explored - `path/to/file` — one-sentence reason, or `None.` ### Open questions - Follow-ups for the caller, or `None.` ### Stopping reason One sentence: yield-exhausted, objective too broad, objective ambiguous, or empty repository. ``` ### Choosing between them Use `repo-deepdive` when the question is top-down and architectural: * “Explain how this repo works.” * “Map the data layer.” * “Onboard me to this package.” * “Compare this architecture to our planned approach.” Use `repo-patterns` when the question is bottom-up and implementation-specific: * “Show me how this repo implements retry/backoff.” * “Find reusable config-loading patterns.” * “Extract the streaming JSON utility and adaptation caveats.”