# Arcmira

> Arcmira is an SF-based AI company and the search engine for the spoken web.

This repo is the `arcmira` Python SDK for the Arcmira API: synchronous and asynchronous clients, typed responses and cursor pagination. The live agent index is on the website. Fetch that for product, API and citation rules, not a copy inside this package.

## Tasks

Use Arcmira to pull YouTube transcripts, find quotes with timestamps, research podcast sponsors, and monitor company mentions. Start with the README examples. Keep source links beside quotes, preserve the reported coverage window, and distinguish captions from Premium transcripts. For agent tasks, connect the MCP server; for an application, use this SDK.

## Install

```sh
pip install arcmira
```

Set `ARCMIRA_API_KEY` or pass `api_key` to the client.

## Ids first

Reads take ids, never names. Resolve a name, then read with the id.

```python
from arcmira import Arcmira

client = Arcmira()
match = client.entities.resolve(q="Ramp", type="organization", context="the corporate card")
ramp = match.best or match.suggested
for mention in client.mentions.list(entity_id=ramp.id, after="2026-09-01", before="2026-10-01"):
    print(mention.media.video_id, mention.start_seconds)
```

- `entities.resolve` answers `best` (certain), `suggested` (likeliest, with a reason; tell the user you assumed it) or `ask` (several fit; show `ask.options`).
- Entity ids look like `ent_14`. Channel ids are YouTube ids, `UC` plus 22 characters. For a show, pass `type="channel"` and use `best.youtube_channel_id`.
- A name where an id belongs raises `BadRequestError` with code `id_required`, naming the parameter.
- Dates are `after` and `before`, half-open `[after, before)`, as an ISO date or a datetime with offset. The body echoes them in `window`.

## Premium transcripts

`client.transcripts.get(video_id, quality="premium")` is one read. It answers `state == "ready"` (200) with the transcript, or `state == "pending"` (202) with `job` and a `Retry-After` header. Read again after `Retry-After` or `job.next_poll_seconds`. Repeated reads join the same job and never use credits twice. A read of a video not transcribed yet uses credits from the plan, then the account's on-demand budget. `client.transcripts.quote(video_id)` is free and shows how many credits the read uses. Use `client.transcripts.with_raw_response.get(...)` for the status code and headers.

## Errors

A refusal raises a typed error from `arcmira.errors` (`BadRequestError`, `PaymentRequiredError`, `ForbiddenError`, `NotFoundError`, `ConflictError`, `TooManyRequestsError` and others), each derived from `arcmira.core.api_error.ApiError`. `body.error` holds `type`, `code`, `message`, `param`, `gate`, `unlock` and `details`. A priced refusal (402 `quota_exceeded` or `spend_limit_exceeded`, 403 `paid_plan_required`) carries the price in `error.details.quote` and charges nothing.

## Methods

- `entities`: `resolve`, `get`, `momentum`.
- `mentions`: `list` (requires `entity_id`), `count`.
- `recommendations`: `list` (requires `entity_id`; `class_` is `sponsored`, `organic` or `mention`).
- `transcripts`: `search` (spoken passages, `GET /v1/search`), `get`, `quote`, `list_requests`.
- `channels`: `coverage`, `videos.list`, `sponsors.list`.
- `monitors`: `list`, `create`, `update`, `delete`, `rotate_webhook_secret`, `trackers.list`, `trackers.add`, `entities.add`, `alerts.list`.
- `trackers`: `list`, `update`, `delete`, `alerts.list`. Trackers are created in a monitor with `monitors.entities.add`.
- `integrations`: `slack.list`.
- `feedback`: `submit`, `get`.
- `me`: `get`, `update_settings`. `health`: `check`.

Follow an entity you have an id for with `monitors.entities.add(monitor_id, entity_ids=[...])`. Watch an exact name before it is indexed with `monitors.entities.add(monitor_id, names=[AddEntitiesRequestNamesItem(name=..., type=...)])`. `me.get()` carries `account` and `role`.

## Clients and pagination

- `Arcmira` is synchronous. `AsyncArcmira` has the same methods to await.
- `mentions.list`, `recommendations.list`, `channels.videos.list` and `transcripts.list_requests` return pagers that follow `next_cursor`. Cursors are opaque. Keep filters the same between pages. Async pagers are async iterators after you await the first page.

## Canonical

- [Site llms.txt](https://arcmira.com/llms.txt): Fetch this first. Product, API, citation rules.
- [Docs index](https://arcmira.com/docs/llms.txt): Catalog of every docs page.
- [OpenAPI](https://api.arcmira.com/v1/openapi.json): HTTP JSON contract at https://api.arcmira.com/v1
- [MCP server](https://github.com/arcmira/mcp): Remote MCP server at https://mcp.arcmira.com/mcp.
- [Arcmira MCP](https://arcmira.com/mcp): What the MCP server does.
- [Connect your AI](https://arcmira.com/agent-setup): Setup for each MCP host.
- [Homepage](https://arcmira.com)
- [Pricing](https://arcmira.com/pricing)
- [Contact](mailto:hi@arcmira.com): hi@arcmira.com
- [Changelog](CHANGELOG.md): What changed from 0.3, method by method.

Apache-2.0. See LICENSE.
