openapi: 3.2.0 info: title: Arcmira Entities API description: 'Search YouTube transcripts for timestamped passages. Find mentions of people, organizations, products and topics; research channel sponsors and recommendations; retrieve creator captions or Premium transcripts with speaker identification; and monitor entities for new mentions. Official API guides: https://arcmira.com/docs. Explicit Premium retrieval can purchase within the account plan and budget.' version: 1.0.0 contact: name: Arcmira url: https://arcmira.com servers: - url: https://api.arcmira.com tags: - name: Entities paths: /v1/entities/resolve: get: tags: - Entities operationId: resolve_entity summary: A name to one id, before any filter description: 'Call this before passing an id to about, by, entity_ids, channel_ids or channel; those filters refuse names with id_required. Pass context with the user''s own words about the name ("the startup bank", "on My First Million"). The answer is one of three: best (the name means one row: use it and name it), suggested (no row is certain but one stands out, with reason and evidence: use it and tell the user you assumed it), or ask (several rows fit: show ask.options, or check every option id and answer per row). For a show pass type=channel and use the youtube_channel_id; for a brand or a person use the id. Free; bills no rows.' security: - bearerAuth: [] parameters: - schema: type: string minLength: 2 description: A name, @handle, YouTube URL or channel id (UC...). One thing per call. required: true description: A name, @handle, YouTube URL or channel id (UC...). One thing per call. name: q in: query - schema: type: string enum: - person - organization - product - topic - channel description: Restrict candidates to one type. Pass channel for a show and read best.youtube_channel_id. required: false description: Restrict candidates to one type. Pass channel for a show and read best.youtube_channel_id. name: type in: query - schema: type: integer minimum: 1 maximum: 15 default: 8 description: Candidates to return, 1 to 15. Default 8. required: false description: Candidates to return, 1 to 15. Default 8. name: limit in: query - schema: type: string minLength: 2 maxLength: 300 description: What the user said about the name, in their words ("the startup bank", "Canada's prime minister", "on My First Million"). Ranks candidates by their description and by the episodes they share with what the context names; a clear winner comes back as suggested with reason context. required: false description: What the user said about the name, in their words ("the startup bank", "Canada's prime minister", "on My First Million"). Ranks candidates by their description and by the episodes they share with what the context names; a clear winner comes back as suggested with reason context. name: context in: query - schema: type: string enum: - mcp-tool description: The surface making this call. The Arcmira MCP server sends mcp-tool so every unlock link in a gate attributes to the directory install. Omit from your own client. required: false description: The surface making this call. The Arcmira MCP server sends mcp-tool so every unlock link in a gate attributes to the directory install. Omit from your own client. name: src in: query responses: '200': description: Success headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' content: application/json: schema: $ref: '#/components/schemas/EntityResolveResponse' '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/AuthenticationError' '403': $ref: '#/components/responses/PermissionError' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/ServerError' /v1/entities/{id}: get: tags: - Entities operationId: get_entity summary: Get canonical entity metadata description: Returns the canonical entity envelope for an ent_{n} or numeric id, following merge redirects. For organization and product entities, callers with Recommendations API access (a Pro+ plan) also receive a recommendations_summary commercial-intelligence rollup when a brand profile exists. security: - bearerAuth: [] parameters: - schema: type: string description: Entity id, ent_{n} or the numeric id. Merged ids follow their redirect. required: true description: Entity id, ent_{n} or the numeric id. Merged ids follow their redirect. name: id in: path responses: '200': description: Success headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' content: application/json: schema: $ref: '#/components/schemas/EntityDetailResponse' '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/AuthenticationError' '402': $ref: '#/components/responses/QuotaExceeded' '403': $ref: '#/components/responses/PermissionError' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/ServerError' /v1/entities/{id}/momentum: get: tags: - Entities operationId: get_entity_momentum summary: Spoken-web heat for one entity description: Mentions in the last 7 and 30 days against the prior 30, an absolute-delta verdict (accelerating, flat, fading, none), the newest media date, and the top shows in the window. It counts the shows we index, not the whole internet, and it is a count, not a score. On a Pro+ plan the card also carries paid_vs_organic; otherwise that field is absent and access names the gate. Bills one row. Every gate is a typed error whose error.unlock.url names the plan that lifts it; pass src=mcp-tool only from the Arcmira MCP server. security: - bearerAuth: [] parameters: - schema: type: string description: Entity id, ent_{n} or the numeric id. Merged ids follow their redirect. required: true description: Entity id, ent_{n} or the numeric id. Merged ids follow their redirect. name: id in: path - schema: type: string enum: - mcp-tool description: The surface making this call. The Arcmira MCP server sends mcp-tool so every unlock link in a gate attributes to the directory install. Omit from your own client. required: false description: The surface making this call. The Arcmira MCP server sends mcp-tool so every unlock link in a gate attributes to the directory install. Omit from your own client. name: src in: query responses: '200': description: Success headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' content: application/json: schema: $ref: '#/components/schemas/EntityMomentumResponse' '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/AuthenticationError' '402': $ref: '#/components/responses/QuotaExceeded' '403': $ref: '#/components/responses/PermissionError' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/ServerError' components: responses: RateLimited: description: Rate limit exceeded. Retry-After carries the wait. headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' RateLimit-Limit: $ref: '#/components/headers/RateLimit-Limit' RateLimit-Remaining: $ref: '#/components/headers/RateLimit-Remaining' RateLimit-Reset: $ref: '#/components/headers/RateLimit-Reset' Retry-After: $ref: '#/components/headers/Retry-After' content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: Not found headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' content: application/json: schema: $ref: '#/components/schemas/Error' InvalidRequest: description: Invalid request headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' content: application/json: schema: $ref: '#/components/schemas/Error' QuotaExceeded: description: Quota exceeded headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' content: application/json: schema: $ref: '#/components/schemas/Error' ServerError: description: Server error headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' content: application/json: schema: $ref: '#/components/schemas/Error' AuthenticationError: description: Authentication error headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' content: application/json: schema: $ref: '#/components/schemas/Error' PermissionError: description: Permission error headers: X-Request-Id: $ref: '#/components/headers/X-Request-Id' X-Arcmira-Version: $ref: '#/components/headers/X-Arcmira-Version' content: application/json: schema: $ref: '#/components/schemas/Error' schemas: ErrorResource: oneOf: - type: object properties: kind: type: string enum: - media_rows beyond_row: type: integer required: - kind - beyond_row - type: object properties: kind: type: string enum: - fresh_media window_days: type: integer cutoff: type: - string - 'null' required: - kind - window_days - cutoff - type: object properties: kind: type: string enum: - sidebar_rows section: type: string enum: - topics - entities beyond_row: type: integer required: - kind - section - beyond_row - type: object properties: kind: type: string enum: - counts required: - kind - type: object properties: kind: type: string enum: - chart required: - kind - type: object properties: kind: type: string enum: - pagination param: type: - string - 'null' enum: - offset - cursor - null required: - kind - param - type: object properties: kind: type: string enum: - premium_transcript required: - kind - type: object properties: kind: type: string enum: - filter param: type: string required: - kind - param - type: object properties: kind: type: string enum: - commercial what: type: string enum: - sponsors - recommendations - mention_details - community_review - paid_split required: - kind - what - type: object properties: kind: type: string enum: - feature feature: type: string enum: - api - export required: - kind - feature - type: object properties: kind: type: string enum: - rows requested: type: - integer - 'null' remaining: type: - integer - 'null' required: - kind - requested - remaining - type: object properties: kind: type: string enum: - key scope: type: - string - 'null' enum: - read - monitors:write - trackers:write - recommendations:read - null required: - kind - scope - type: object properties: kind: type: string enum: - requests required: - kind description: The value the boundary withheld, not the reason it refused. kind is a closed vocabulary and the fields beside it are fixed per kind; see https://arcmira.com/docs/errors#resource-kinds. ResolveCandidate: type: - object - 'null' properties: id: type: string description: Public entity id in the form "ent_{n}". name: type: string description: Entity name. slug: type: - string - 'null' description: URL slug. Null when the entity has never been slugged. type: type: string description: 'Entity type. Values: person (an individual), organization (a company or institution; legacy rows may read company or brand), product (a product or service), topic (a subject or theme), channel (a media source such as a YouTube channel), unknown (type was never classified).' appearance_count: type: integer default: 0 description: Number of indexed appearance/mention rows. Results are ordered by this, descending. youtube_channel_id: type: - string - 'null' description: YouTube channel id for channel entities. Null for every other type. description: type: - string - 'null' description: One catalog sentence that tells rows with the same name apart, for example "Common gender-neutral given name or nickname". Null when the catalog has none. page: type: - string - 'null' description: The entity's page on arcmira.com, absolute. Link the name to it when you write the entity into an answer. Null for a type the site has no page for. match: type: string enum: - exact - word - substring - acronym - spelling description: 'How the row''s name relates to q: the whole name, a run of its words (Michael Jordan for Jordan), characters inside a word, the show''s initials (My First Million for MFM), or a near spelling.' required: - id - name - slug - type - youtube_channel_id - description - page - match description: The one row q means. Set on exact and single_fuzzy only. Name it in the answer. EntityRef: type: object properties: id: type: string description: Public entity id in the form "ent_{n}". name: type: string description: Canonical entity name. type: type: string description: 'Entity type. Values: person (an individual), organization (a company or institution; legacy rows may read company or brand), product (a product or service), topic (a subject or theme), channel (a media source such as a YouTube channel), unknown (type was never classified).' slug: type: - string - 'null' description: URL slug, the site's canonical id for every type but channel. Null when never slugged. page: type: - string - 'null' description: The entity's page on arcmira.com, absolute. Link the name to it when you write the entity into an answer. Null for a type the site has no page for. required: - id - name - type - slug - page EntityDetailResponse: type: object properties: entity: $ref: '#/components/schemas/Entity' recommendations_summary: $ref: '#/components/schemas/EntityDetailRecommendationsSummary' required: - entity ResolveSuggestion: allOf: - $ref: '#/components/schemas/ResolveCandidate' - type: - object - 'null' properties: reason: type: string enum: - dominant - only_word_match - context - acronym - spelling description: 'Why this row stands out: dominant (10x the appearances of the next match), only_word_match, context (the context parameter points at it), acronym, spelling.' evidence: type: string description: The numbers or words behind the reason, to repeat to the user. assumed: type: boolean enum: - true description: 'Always true: this is an assumption the answer must state.' required: - reason - evidence - assumed description: Set when best is null but one row stands out, with the reason and evidence. Use it and tell the user you assumed it. Entity: type: object properties: id: type: string description: Public entity id in the form "ent_{n}". Always the canonical entity id. canonical_id: type: string description: Public id of the canonical entity. Identical to id. name: type: string description: Canonical entity name. type: type: string description: 'Entity type. Values: person (an individual), organization (a company or institution; legacy rows may read company or brand), product (a product or service), topic (a subject or theme), channel (a media source such as a YouTube channel), unknown (type was never classified).' platform: type: - string - 'null' description: Source platform for channel entities, e.g. "youtube". Null unless the entity is platform-bound. url: type: - string - 'null' description: Canonical external URL for the entity. Null when none is known. image_url: type: - string - 'null' description: Entity image URL. Null until an image has been resolved. image_checked_at: type: - string - 'null' description: Timestamp of the last image resolution attempt. Null until the image pipeline has visited this entity. appearance_count: type: integer default: 0 description: Number of indexed appearance/mention rows for this entity. 0 when never counted. owner_entity_id: type: - string - 'null' description: Public id ("ent_{n}") of the owning entity, e.g. the organization behind a product. Null unless an ownership link exists. is_canonical: type: boolean description: True when the id you supplied is the canonical entity. False when your id was merged into this canonical record. merged_from_id: type: - string - 'null' description: Public id you supplied when it differs from the canonical entity, i.e. your id was merged into this record. Null unless a merge redirect happened. slug: type: - string - 'null' description: URL slug, the site's canonical id for every type but channel. Null when never slugged. route: type: - string - 'null' description: Site-relative route of this entity's page on arcmira.com, e.g. "/org/ramp", "/person/jane-doe", "/yt/@TBPNLive". Null for a type the site has no page for. page: type: - string - 'null' description: The entity's page on arcmira.com, absolute. Link the name to it when you write the entity into an answer. Null for a type the site has no page for. appearances_page: type: - string - 'null' description: For a person, the list of their appearances on arcmira.com (their page opens on it). Null for every other type. mentions_page: type: - string - 'null' description: 'For a person, the list of mentions of them on arcmira.com, page/mentions. Null for every other type: their page is the mentions list already.' required: - id - canonical_id - name - type - platform - url - image_url - image_checked_at - owner_entity_id - is_canonical - merged_from_id - slug - route - page - appearances_page - mentions_page Error: type: object properties: error: type: object properties: type: type: string enum: - invalid_request_error - authentication_error - permission_error - quota_exceeded - rate_limit_error - not_found - conflict_error - server_error description: 'The error class. It fixes the HTTP status: invalid_request_error 400, authentication_error 401, quota_exceeded 402, permission_error 403, not_found 404, conflict_error 409, rate_limit_error 429, server_error 500. Switch on it for retry and gate handling.' code: type: string description: 'The specific condition, stable and snake_case; doc_url anchors on it. x-arcmira-codes on this schema lists every code with its type, gate and meaning. The list is open: new codes may appear inside an existing type, so switch on type and gate first.' reason: type: string enum: - no_credential - invalid - revoked description: 'Only on invalid_api_key. no_credential: nothing was sent. invalid: a credential was sent and is unknown or malformed. revoked: the key exists and is no longer usable.' message: type: string description: One plain line. Names the fix or the unlock. param: type: string description: The query or body parameter the gate refused, when one did. gate: type: string enum: - rows - key - plan - freshness - exposure_law - rate - pagination description: Which boundary refused. Present on every gate error; switch on it without parsing the message. resource: $ref: '#/components/schemas/ErrorResource' unlock: type: object properties: tier: type: string description: The plan that lifts the gate. url: type: string description: Absolute upgrade or sign-up URL carrying its ?src= attribution. Use it verbatim. offer: type: 'null' description: Reserved for the agent-discount offer. Always null today. action: type: object properties: kind: type: string description: What the call does. send_signup_code sends a verification code to an address for an account key. method: type: string description: HTTP method to use. url: type: string description: Absolute endpoint carrying its ?src= attribution. Call it verbatim. required: - kind - method - url description: The request that lifts the gate with no human, present when the caller can fix this itself. A key gate carries the signup send here; a plan or quota gate has no action and its url is a page a person opens. required: - tier - url - offer description: How to lift the gate. Present when the gate has an unlock. retry_after_seconds: type: integer description: Present on rate gates. Mirrors the Retry-After header. details: type: object properties: quote: $ref: '#/components/schemas/RefusedQuote' existing_id: type: string description: On tracker_already_exists, the existing tracker id. Reuse it instead of creating another tracker. limit: type: integer description: On tracker_limit, the trackers the plan holds. count: type: integer description: On tracker_limit, the trackers the account holds now. description: Machine data the refusal carries for you to act on. Present only on the codes that name a field here. doc_url: type: string request_id: type: string required: - type - code - message - doc_url - request_id required: - error x-arcmira-codes: - code: alert_not_found type: not_found description: A referenced alert row does not exist or belongs to another account. - code: api_not_enabled type: permission_error gate: plan description: The plan does not include API access. unlock.url names the plan that does. - code: appearances_person_only type: invalid_request_error description: Appearance filtering applies to person entities only. - code: channel_not_found type: not_found description: No channel matches the id or slug. - code: email_verification_required type: permission_error description: Verify the account email before adding recipients. - code: entity_not_found type: not_found description: No entity matches the id, slug, or name. - code: feature_not_available type: permission_error gate: plan description: The plan does not include this feature. unlock.url names the plan that does. - code: feedback_not_found type: not_found description: No feedback submission with this id for this account. - code: filter_requires_paid type: permission_error gate: plan description: The parameter in param needs a paid plan; omit it for the free answer. - code: forbidden type: permission_error description: The caller may not perform this operation on this resource. - code: freshness_requires_paid type: permission_error gate: freshness description: The date window is newer than the plan serves; move it before the cutoff or upgrade. - code: id_required type: invalid_request_error description: A filter in param received a name where it takes an id (ent_{n} or UC...). Resolve the name first with GET /v1/entities/resolve and pass best.id or best.youtube_channel_id. - code: idempotency_conflict type: conflict_error description: The Idempotency-Key was sent before with a different request body. Send a new key for a new request. - code: idempotency_result_expired type: conflict_error description: The original one-time signing secret is no longer valid. Use a new request key for a new rotation. - code: insufficient_scope type: permission_error gate: key description: The key lacks the scope this route needs. - code: invalid_api_key type: authentication_error gate: key description: No usable credential. reason says whether none was sent, it is unknown, or it was revoked. - code: invalid_body type: invalid_request_error description: The JSON body failed validation; message names the field. - code: invalid_cursor type: invalid_request_error description: The continuation is invalid, expired, or belongs to another query. Restart without cursor. - code: invalid_email_recipients type: invalid_request_error description: Email recipients failed validation. - code: invalid_feedback_request type: invalid_request_error description: The feedback query or corrections do not fit the feedback type. - code: invalid_idempotency_key type: invalid_request_error description: Idempotency-Key must be 1 to 255 printable ASCII characters (0x21 to 0x7E). param is Idempotency-Key. - code: invalid_query type: invalid_request_error description: A query parameter failed validation; message names it. - code: invalid_slack_integration type: invalid_request_error description: Choose an active Slack integration owned by the account. - code: invalid_video_id type: invalid_request_error description: The video_id path segment is not an 11-character YouTube id. - code: job_requires_account type: authentication_error gate: key description: Transcription jobs belong to an account; sign up for a key. - code: monitor_creation_unavailable type: server_error description: Monitor creation is temporarily unavailable. Retry the same request with the same key. - code: monitor_creation_unconfirmed type: server_error description: Monitor creation could not be confirmed. Retry the same request with the same key. - code: monitor_not_found type: not_found description: No monitor with this id on the account. - code: not_found type: not_found description: No route or resource at this path. - code: owner_only type: permission_error description: Only the team owner may change or test a team monitor's webhook, rotate its secret, or delete it. - code: owner_plan_required type: permission_error description: A team monitor follows the team owner's plan, which does not include this. The owner can upgrade; a member's own plan does not apply. - code: pagination_gated type: permission_error gate: pagination description: Rows past the free window need a paid plan. - code: paid_plan_required type: permission_error description: The operation needs a paid plan. unlock.url names the plan that does. - code: premium_transcript_requested type: permission_error gate: exposure_law description: Premium transcript text needs a plan with Premium transcripts. - code: quota_exceeded type: quota_exceeded gate: rows description: The row pool is spent. unlock.url upgrades or raises the limit. - code: rate_limited type: rate_limit_error gate: rate description: Too many requests in the window. Retry-After carries the wait. - code: recipient_upgrade_required type: permission_error description: The requested email recipient count exceeds the plan allowance. - code: recommendations_not_enabled type: permission_error gate: plan description: Commercial data needs a Pro+ plan. - code: resource_conflict type: conflict_error description: The operation conflicts with existing resource state. - code: scope_too_broad type: invalid_request_error description: The requested exact video scope exceeds the search filename cap; narrow by channel or date. - code: search_unavailable type: server_error description: Transcript search is unavailable (HTTP 503). Retry-After carries the wait. - code: server_error type: server_error description: Unexpected failure. Retry with backoff and quote request_id if it persists. - code: signup_code_invalid type: invalid_request_error description: The signup code is wrong, expired, or spent; message names the attempts left. - code: signup_send_limited type: rate_limit_error description: Verification code sends hit a per-address, per-IP, or per-client cap. Retry-After carries the wait. - code: spend_limit_exceeded type: quota_exceeded description: The purchase would take on-demand spending past the account or seat spend limit this period. Nothing was charged. Raise the limit or wait for the next period, then send a new intent. - code: team_not_found type: not_found description: No team with this id that the caller belongs to. - code: tracker_already_exists type: conflict_error description: The account already tracks this entity. error.details.existing_id identifies the existing tracker. - code: tracker_limit type: permission_error description: The plan's tracker limit is reached. error.details carries limit and count. - code: tracker_not_found type: not_found description: No tracker with this id on the account. - code: transcript_fetching type: server_error description: The caption track is being fetched now (HTTP 503). Retry-After carries the wait; nothing was charged. - code: transcript_requires_account type: authentication_error gate: key description: Full transcripts need an account key; unlock.action sends a signup code. - code: transcript_unavailable type: not_found description: The video has no transcript in the requested lane or language; languages lists what exists. - code: unknown_entity type: invalid_request_error description: An explicit entity_ids value does not resolve to a searchable entity. - code: webhook_not_configured type: conflict_error description: The monitor has no webhook to rotate a secret for. Set webhook_url first. TranscriptQuote: type: object properties: quarters: type: integer description: Number of 15-minute blocks in the video, ceiling'd, minimum 1. rows: type: integer description: 'Total unlock cost in rows: 75 rows per 15-minute block.' required: - quarters - rows EntityMomentumResponse: type: object properties: entity: $ref: '#/components/schemas/EntityRef' verdict: type: string enum: - accelerating - flat - fading - none description: Absolute delta of the last 30 days against the prior 30. none when the entity has no mentions at all. as_of: type: - string - 'null' description: Newest indexed media that mentions the entity. Lead with it; it is the date the verdict is true as of. coverage: type: string description: What the count measures. Always the shows we index, never the whole internet. volume: type: object properties: mentions_7d: type: integer mentions_30d: type: integer mentions_prior_30d: type: integer delta_30d_absolute: type: integer delta_30d_pct: type: - number - 'null' description: Percent change against the prior 30 days. Null when the prior window was zero. mentions_90d: type: integer total: type: integer description: All-time mentions in the index. required: - mentions_7d - mentions_30d - mentions_prior_30d - delta_30d_absolute - delta_30d_pct - mentions_90d - total top_shows: type: array items: type: object properties: channel_id: type: - string - 'null' channel_name: type: - string - 'null' channel_page: type: - string - 'null' description: The channel's page on arcmira.com, absolute. Null when no channel is known. mentions: type: integer required: - channel_id - channel_name - channel_page - mentions description: Up to five channels by mentions in the last 30 days. paid_vs_organic: type: object properties: ad_reads: type: integer endorsements: type: integer organic: type: integer required: - ad_reads - endorsements - organic description: Commercial split for the last 30 days. Present only on a Pro+ plan; otherwise access names the gate. access: type: object properties: type: type: string enum: - invalid_request_error - authentication_error - permission_error - quota_exceeded - rate_limit_error - not_found - conflict_error - server_error description: 'The error class. It fixes the HTTP status: invalid_request_error 400, authentication_error 401, quota_exceeded 402, permission_error 403, not_found 404, conflict_error 409, rate_limit_error 429, server_error 500. Switch on it for retry and gate handling.' code: type: string description: 'The specific condition, stable and snake_case; doc_url anchors on it. x-arcmira-codes on this schema lists every code with its type, gate and meaning. The list is open: new codes may appear inside an existing type, so switch on type and gate first.' reason: type: string enum: - no_credential - invalid - revoked description: 'Only on invalid_api_key. no_credential: nothing was sent. invalid: a credential was sent and is unknown or malformed. revoked: the key exists and is no longer usable.' message: type: string description: One plain line. Names the fix or the unlock. param: type: string description: The query or body parameter the gate refused, when one did. gate: type: string enum: - rows - key - plan - freshness - exposure_law - rate - pagination description: Which boundary refused. Present on every gate error; switch on it without parsing the message. resource: $ref: '#/components/schemas/ErrorResource' unlock: type: object properties: tier: type: string description: The plan that lifts the gate. url: type: string description: Absolute upgrade or sign-up URL carrying its ?src= attribution. Use it verbatim. offer: type: 'null' description: Reserved for the agent-discount offer. Always null today. action: type: object properties: kind: type: string description: What the call does. send_signup_code sends a verification code to an address for an account key. method: type: string description: HTTP method to use. url: type: string description: Absolute endpoint carrying its ?src= attribution. Call it verbatim. required: - kind - method - url description: The request that lifts the gate with no human, present when the caller can fix this itself. A key gate carries the signup send here; a plan or quota gate has no action and its url is a page a person opens. required: - tier - url - offer description: How to lift the gate. Present when the gate has an unlock. retry_after_seconds: type: integer description: Present on rate gates. Mirrors the Retry-After header. details: type: object properties: quote: $ref: '#/components/schemas/RefusedQuote' existing_id: type: string description: On tracker_already_exists, the existing tracker id. Reuse it instead of creating another tracker. limit: type: integer description: On tracker_limit, the trackers the plan holds. count: type: integer description: On tracker_limit, the trackers the account holds now. description: Machine data the refusal carries for you to act on. Present only on the codes that name a field here. doc_url: type: string request_id: type: string required: - type - code - message - doc_url - request_id description: The gate that reduced this response. Present only when something was withheld; carries the same code, gate, and unlock an outright refusal would. note: type: string description: One steering sentence for the agent reading this. required: - entity - verdict - as_of - coverage - volume - top_shows - note example: entity: id: ent_14 name: Ramp type: organization slug: ramp page: https://arcmira.com/org/ramp verdict: accelerating as_of: '2026-08-28T17:00:00.000Z' coverage: Shows we index, not the whole internet. volume: mentions_7d: 6 mentions_30d: 23 mentions_prior_30d: 11 delta_30d_absolute: 12 delta_30d_pct: 109.1 mentions_90d: 41 total: 188 top_shows: - channel_id: UC-DRzaGnL_vtBUpCFH5M0tg channel_name: TBPN channel_page: https://arcmira.com/yt/@TBPNLive mentions: 17 - channel_id: UClWkDGXEzsh77GAhs90wpXw channel_name: Moment of Truth channel_page: https://arcmira.com/yt/@MomentofTruthShow mentions: 3 access: type: permission_error code: recommendations_not_enabled message: The paid versus organic split requires Pro+. Open unlock.url to start Pro+. gate: plan resource: kind: commercial what: paid_split unlock: tier: pro_plus url: https://arcmira.com/pricing?src=mcp-tool offer: null doc_url: https://arcmira.com/docs/errors#recommendations_not_enabled request_id: req_7f3c2a note: Lead with verdict and as_of. Then volume and shows. The paid vs organic split needs a plan that carries it; card.access says so. Search transcripts second for quotes. Never invent a heat score. RefusedQuote: allOf: - $ref: '#/components/schemas/TranscriptQuote' - type: object properties: charge: type: object properties: unit: type: string enum: - rows - credits amount: type: number from: type: string enum: - included - on_demand - mixed description: Where the charge would come from at the current balance. required: - unit - amount - from description: What the purchase would charge at the current balance. Absent when no current price could be read. max_on_demand_cents: type: integer description: The on-demand money, in whole cents, this purchase needs beyond included credits at the current balance. description: 'The refused price, on a priced refusal: quota_exceeded, spend_limit_exceeded and paid_plan_required.' EntityDetailRecommendationsSummary: type: object properties: total_ad_reads: type: integer description: Total ad_read rows across all channels. 0 when none. total_endorsements: type: integer description: Total endorsement rows across all channels. 0 when none. unique_shows: type: integer description: Number of distinct shows/channels with commercial mentions of this entity. first_seen_at: type: - string - 'null' description: Timestamp of the earliest commercial mention. Null until the brand profile has been computed. last_seen_at: type: - string - 'null' description: Timestamp of the most recent commercial mention. Null until the brand profile has been computed. channels_as_sponsor: type: integer description: Number of channels where this entity appears in the curated known-advertisers dataset. required: - total_ad_reads - total_endorsements - unique_shows - first_seen_at - last_seen_at - channels_as_sponsor description: Commercial-intelligence rollup. Only present for organization and product entities when the caller has Recommendations API access (a Pro+ plan) and a brand profile exists. EntityResolveResponse: type: object properties: query: type: string description: The q parameter echoed back. context: type: - string - 'null' description: The context parameter echoed back. confidence: type: string enum: - exact - single_fuzzy - ambiguous - fuzzy - none description: 'exact: one row is named q (or the handle, id or alias), and no better-known person carries the name. single_fuzzy: the only row returned, not an exact name. ambiguous: several exact rows, or an exact row next to a better-known person sharing the name (Jordan the brand vs Michael Jordan). fuzzy: only loose matches. none: no row.' best: $ref: '#/components/schemas/ResolveCandidate' suggested: $ref: '#/components/schemas/ResolveSuggestion' ask: type: - object - 'null' properties: question: type: string options: type: array items: type: object properties: id: type: string name: type: string type: type: string label: type: string description: 'One line to show the user: name, type, description, appearance count.' required: - id - name - type - label required: - question - options description: 'Set when best and suggested are both null and several rows fit: show the options to the user, or check every option id against the data and answer per row.' candidates: type: array items: $ref: '#/components/schemas/ResolveCandidate' description: 'Rows considered: exact names first, then initials, whole-word, spelling and substring matches, each by appearance count.' note: type: string description: One steering sentence for the agent reading this. required: - query - context - confidence - best - suggested - ask - candidates - note example: query: Sam context: null confidence: ambiguous best: null suggested: id: ent_124463 name: Sam Altman slug: sam-altman type: person appearance_count: 4399 youtube_channel_id: null description: CEO of OpenAI and former president of Y Combinator. page: https://arcmira.com/person/sam-altman match: word reason: dominant evidence: it has 4,399 appearances, 11x the next match (Sam Dunning, 397) assumed: true ask: null candidates: - id: ent_123696 name: Sam slug: sam type: person appearance_count: 265 youtube_channel_id: null description: Common gender-neutral given name or nickname page: https://arcmira.com/person/sam match: exact note: No row is certain. suggested is Sam Altman (person) because it has 4,399 appearances, 11x the next match (Sam Dunning, 397). Use it and tell the user you assumed it. headers: X-Arcmira-Version: description: The API version that answered. Always v1. schema: type: string enum: - v1 RateLimit-Remaining: description: Requests left in the current window. schema: type: integer RateLimit-Reset: description: Unix time in seconds when the current window ends. schema: type: integer RateLimit-Limit: description: Requests allowed per 60-second window for this credential, as GET /v1/me rate_limit reports. schema: type: integer Retry-After: description: Seconds to wait before retrying. error.retry_after_seconds carries the same value on an error. schema: type: integer X-Request-Id: description: The request id, echoed from an X-Request-Id request header or minted as req_. error.request_id carries the same value. Quote it when reporting a problem. schema: type: string securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: arc_sk_* externalDocs: description: Official Arcmira API documentation url: https://arcmira.com/docs