diff --git a/CHANGELOG.md b/CHANGELOG.md index 14d1af6..59a69c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.4.2 + +Generated from the v1 document of 2026-10-04, which prices every read in credits. `PremiumQuote` replaces the `TranscriptPurchaseQuote` type. + ## 0.4.1 Paid reads use credits from your plan, then your on-demand budget. diff --git a/VERSION b/VERSION index 267577d..2b7c5ae 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.1 +0.4.2 diff --git a/fern/openapi.json b/fern/openapi.json index 1984364..0e59269 100644 --- a/fern/openapi.json +++ b/fern/openapi.json @@ -368,7 +368,7 @@ { "code": "alert_not_found", "type": "not_found", - "description": "A referenced alert row does not exist or belongs to another account." + "description": "A referenced alert does not exist or belongs to another account." }, { "code": "api_not_enabled", @@ -531,7 +531,7 @@ "code": "pagination_gated", "type": "permission_error", "gate": "pagination", - "description": "Rows past the free window need a paid plan." + "description": "Results past the free window need a paid plan." }, { "code": "paid_plan_required", @@ -548,7 +548,7 @@ "code": "quota_exceeded", "type": "quota_exceeded", "gate": "rows", - "description": "The row pool is spent. unlock.url upgrades or raises the limit." + "description": "The read needs more credits than your plan, then your on-demand budget, have left. unlock.url upgrades the plan or raises the budget." }, { "code": "rate_limited", @@ -983,7 +983,7 @@ }, "rows": { "type": "integer", - "description": "Rows the whole video uses, 75 rows per 15-minute block." + "description": "Rows the whole video uses, 75 rows per 15-minute block. A row is 4 credits, so Premium uses 300 credits per block." } }, "required": [ @@ -1024,7 +1024,7 @@ "refund_pending", "refunded" ], - "description": "Request status. Values: queued (accepted; audio download not started), downloading (fetching the video audio), transcribing (premium speech-to-text is running), analyzing (entity/commercial analysis is running), complete (premium transcript is servable via GET /v1/transcripts/{video_id}), failed (rejected intent, or a legacy request needing accounting review), refund_pending (refund transaction must still complete), refunded (terminal failure; the charged rows were returned and the unlock this request granted was revoked)." + "description": "Request status. Values: queued (accepted; audio download not started), downloading (fetching the video audio), transcribing (premium speech-to-text is running), analyzing (entity/commercial analysis is running), complete (premium transcript is servable via GET /v1/transcripts/{video_id}), failed (rejected intent, or a legacy request needing accounting review), refund_pending (refund transaction must still complete), refunded (terminal failure; the charge was returned and the unlock this request granted was revoked)." }, "stage": { "type": [ @@ -1267,7 +1267,7 @@ "string", "null" ], - "description": "ISO 8601 time the monthly row pool resets: 00:00 UTC on the first of next month. Null on the free plan, whose rows are a lifetime pool." + "description": "ISO 8601 time the plan credits reset: 00:00 UTC on the first of next month. Null on the free plan, whose 1,000 credits a month reset on usage.credits.plan.resets_at." }, "tier": { "type": "string", @@ -1293,15 +1293,15 @@ "properties": { "rows_used": { "type": "integer", - "description": "Premium rows consumed this period." + "description": "Plan credits used this month, in rows: usage.credits.plan.used divided by 4, rounded up. A row is 4 credits." }, "rows_remaining": { "type": "integer", - "description": "Premium rows left this period." + "description": "Credits left from the plan, grants and top-ups, on-demand excluded, in rows: divided by 4, rounded up. A row is 4 credits." }, "monthly_rows": { "type": "integer", - "description": "Total premium rows included per period." + "description": "The plan credits a month, in rows: usage.credits.plan.credits divided by 4 when the plan has a limit. A row is 4 credits." }, "current_spend_cents": { "type": "integer", @@ -1362,7 +1362,7 @@ "integer", "null" ], - "description": "The on-demand cap in credits, at $0.002 a credit. Null when uncapped or off." + "description": "The on-demand budget in credits. On-demand usage costs $0.002 a credit, so this is the dollar budget divided by 0.002. Null when uncapped or off." }, "used": { "type": "integer", @@ -1383,7 +1383,7 @@ "purchased", "on_demand" ], - "description": "The month in credits (1 credit is $0.001; a row is 4 credits). Present only when the credits ledger decides access." + "description": "The month in credits, the primary measure of usage. Every read uses credits from the plan, then the on-demand budget. An included plan credit is valued at $0.001; on-demand usage costs $0.002 a credit. A row is 4 credits. Present only when the credits ledger decides access." } }, "required": [ @@ -1524,7 +1524,7 @@ }, "rows_allotted": { "type": "integer", - "description": "The pool this key draws on: a free account's lifetime credits, a paid plan's monthly rows." + "description": "On a paid plan, its monthly allowance in rows; a row is 4 credits. On the free plan, the account's row allotment from before credits (1,000 for a new account). The free plan uses 1,000 credits a month, read from usage.credits on GET /v1/me." }, "next": { "type": "string", @@ -1569,7 +1569,7 @@ "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." + "description": "exact: one entity is named q (or the handle, id or alias), and no better-known person carries the name. single_fuzzy: the only entity returned, not an exact name. ambiguous: several exact matches, or an exact match next to a better-known person sharing the name (Jordan the brand vs Michael Jordan). fuzzy: only loose matches. none: no match." }, "best": { "$ref": "#/components/schemas/ResolveCandidate" @@ -1618,14 +1618,14 @@ "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." + "description": "Set when best and suggested are both null and several entities fit: show the options to the user, or check every option id against the data and answer per entity." }, "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." + "description": "Entities considered: exact names first, then initials, whole-word, spelling and substring matches, each by appearance count." }, "note": { "type": "string", @@ -1701,12 +1701,12 @@ }, "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)." + "description": "Entity type. Values: person (an individual), organization (a company or institution; legacy entities 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." + "description": "Number of indexed appearances and mentions. Results are ordered by this, descending." }, "youtube_channel_id": { "type": [ @@ -1720,7 +1720,7 @@ "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." + "description": "One catalog sentence that tells entities with the same name apart, for example \"Common gender-neutral given name or nickname\". Null when the catalog has none." }, "page": { "type": [ @@ -1738,7 +1738,7 @@ "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." + "description": "How the entity'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": [ @@ -1751,7 +1751,7 @@ "page", "match" ], - "description": "The one row q means. Set on exact and single_fuzzy only. Name it in the answer." + "description": "The one entity q means. Set on exact and single_fuzzy only. Name it in the answer." }, "ResolveSuggestion": { "allOf": [ @@ -1773,7 +1773,7 @@ "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." + "description": "Why this entity 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", @@ -1794,7 +1794,7 @@ ] } ], - "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." + "description": "Set when best is null but one entity stands out, with the reason and evidence. Use it and tell the user you assumed it." }, "EntityDetailResponse": { "type": "object", @@ -1827,7 +1827,7 @@ }, "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)." + "description": "Entity type. Values: person (an individual), organization (a company or institution; legacy entities 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": [ @@ -1860,7 +1860,7 @@ "appearance_count": { "type": "integer", "default": 0, - "description": "Number of indexed appearance/mention rows for this entity. 0 when never counted." + "description": "Number of indexed appearances and mentions of this entity. 0 when never counted." }, "owner_entity_id": { "type": [ @@ -1940,11 +1940,11 @@ "properties": { "total_ad_reads": { "type": "integer", - "description": "Total ad_read rows across all channels. 0 when none." + "description": "Total ad_read recommendations across all channels. 0 when none." }, "total_endorsements": { "type": "integer", - "description": "Total endorsement rows across all channels. 0 when none." + "description": "Total endorsement recommendations across all channels. 0 when none." }, "unique_shows": { "type": "integer", @@ -1991,7 +1991,7 @@ }, "has_more": { "type": "boolean", - "description": "True when more rows exist past this page." + "description": "True when more results exist past this page." }, "next_cursor": { "type": [ @@ -2169,7 +2169,7 @@ "number", "null" ], - "description": "Analyzer confidence between 0 and 1. Null for legacy rows analyzed before confidence scoring." + "description": "Analyzer confidence between 0 and 1. Null for legacy mentions analyzed before confidence scoring." }, "sentiment_score": { "type": [ @@ -2254,7 +2254,7 @@ }, "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)." + "description": "Entity type. Values: person (an individual), organization (a company or institution; legacy entities 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": [ @@ -2382,7 +2382,7 @@ }, "has_more": { "type": "boolean", - "description": "True when more rows exist past this page." + "description": "True when more results exist past this page." }, "next_cursor": { "type": [ @@ -2541,11 +2541,11 @@ "number", "null" ], - "description": "Raw sentiment score between -1 and 1, same semantics as sentiment_score on mention rows. Null when not computed." + "description": "Raw sentiment score between -1 and 1, same semantics as sentiment_score on mentions. Null when not computed." }, "confidence": { "type": "number", - "description": "Classifier confidence between 0 and 1. Rows below the min_confidence filter (default 0.7) are excluded from list responses." + "description": "Classifier confidence between 0 and 1. Recommendations below the min_confidence filter (default 0.7) are excluded from list responses." }, "speaker_role": { "type": "string", @@ -2556,7 +2556,7 @@ "string", "null" ], - "description": "Set when community feedback disputes the classification (e.g. \"disputed\"). Null when undisputed. Disputed rows are excluded unless include_disputed=true." + "description": "Set when community feedback disputes the classification (e.g. \"disputed\"). Null when undisputed. Disputed recommendations are excluded unless include_disputed=true." }, "resolution": { "type": [ @@ -2704,7 +2704,7 @@ "properties": { "entity_id": { "type": "string", - "description": "Public id (\"ent_{n}\") of the entity the row should point at." + "description": "Public id (\"ent_{n}\") of the entity the result should point at." }, "entity_name": { "type": "string", @@ -2716,7 +2716,7 @@ } }, "additionalProperties": {}, - "description": "For issue_type wrong_entity (and wrong_person): the entity the row should have been attributed to." + "description": "For issue_type wrong_entity (and wrong_person): the entity the result should have been attributed to." }, "WrongEntityTypeChange": { "type": "object", @@ -2769,7 +2769,7 @@ } }, "additionalProperties": {}, - "description": "For issue_type wrong_classification: the commercial class the row should carry." + "description": "For issue_type wrong_classification: the commercial class the result should carry." }, "StaleMetadataChange": { "type": "object", @@ -2794,15 +2794,15 @@ "properties": { "expected_rank": { "type": "integer", - "description": "Where the row should have ranked (1-based)." + "description": "Where the result should have ranked (1-based)." }, "observed_rank": { "type": "integer", - "description": "Where the row actually ranked (1-based). Most useful on search feedback." + "description": "Where the result actually ranked (1-based). Most useful on search feedback." } }, "additionalProperties": {}, - "description": "For issue_type bad_ranking: the expected and observed positions of the row." + "description": "For issue_type bad_ranking: the expected and observed positions of the result." }, "MissedAlertChange": { "type": "object", @@ -2824,7 +2824,7 @@ "source_url" ], "additionalProperties": {}, - "description": "For issue_type missed_alert: an expectation with no alert row to target. Omit the correction id and describe where the alert should have fired." + "description": "For issue_type missed_alert: an expectation with no alert to target. Omit the correction id and describe where the alert should have fired." }, "DeliveryIssueChange": { "type": "object", @@ -2843,7 +2843,7 @@ "channel" ], "additionalProperties": {}, - "description": "For issue_type delivery_issue: targets the delivery row (the correction id) and names the channel that was wrong or never received." + "description": "For issue_type delivery_issue: targets the alert delivery (the correction id) and names the channel that was wrong or never received." }, "FreeformSuggestedChange": { "type": "object", @@ -2899,7 +2899,7 @@ "items": { "$ref": "#/components/schemas/FeedbackReadbackCorrection" }, - "description": "Per-correction rows with their individual review statuses, in submission order." + "description": "The corrections, each with its own review status, in submission order." } }, "required": [ @@ -2978,7 +2978,7 @@ "string", "null" ], - "description": "When the correction row was created." + "description": "When the correction was created." } }, "required": [ @@ -3224,7 +3224,7 @@ }, "ad_reads": { "type": "integer", - "description": "Number of ad_read recommendation rows for this sponsor on the channel." + "description": "Number of ad_read recommendations for this sponsor on the channel." }, "videos": { "type": "integer", @@ -3673,7 +3673,7 @@ "string", "null" ], - "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)." + "description": "Entity type. Values: person (an individual), organization (a company or institution; legacy entities 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)." } }, "required": [ @@ -5250,14 +5250,14 @@ "string", "null" ], - "description": "Public id (\"ent_{n}\") of the entity that triggered the alert, when recorded. Null on older rows that were written before entity_id was stored on alert_delivery. Resolve the entity through mention_id or the embedded tracker when this is null." + "description": "Public id (\"ent_{n}\") of the entity that triggered the alert, when recorded. Null on older alerts recorded before entity_id was stored. Resolve the entity through mention_id or the embedded tracker when this is null." }, "mention_id": { "type": [ "string", "null" ], - "description": "Public id (\"men_{n}\") of the mention/appearance row that triggered the alert. Joins directly against mention rows (e.g. /v1/mentions). Null when not appearance-scoped." + "description": "Public id (\"men_{n}\") of the mention or appearance that triggered the alert. Matches the id on /v1/mentions results. Null when not appearance-scoped." }, "video_id": { "type": [ @@ -5282,7 +5282,7 @@ "excerpt", null ], - "description": "Which evidence layer was sent. Null on older rows." + "description": "Which evidence layer was sent. Null on older alerts." }, "channel": { "type": "string", @@ -5322,7 +5322,7 @@ }, "created_at": { "type": "string", - "description": "When the alert row was created." + "description": "When the alert was created." }, "tracker": { "type": "object", @@ -5362,7 +5362,7 @@ "entity_type", "display_name" ], - "description": "The tracker the alert belongs to. Fields are null when the tracker row was deleted." + "description": "The tracker the alert belongs to. Fields are null when the tracker was deleted." }, "monitor": { "type": [ @@ -5407,7 +5407,8 @@ "created_at", "tracker", "monitor" - ] + ], + "description": "One delivery of an alert. Each alert uses 25 credits once, however many channels and recipients deliver it." }, "MonitorAddTrackersResponse": { "type": "object", @@ -5906,7 +5907,7 @@ }, "rows_billed": { "type": "integer", - "description": "Caption retrieval rows charged by this call. 0 on a repeat of the same video, quality, language, and range inside the 7 day dedupe window. Premium responses report 0 here even when the read was charged for the whole video; this field does not report Premium charges." + "description": "Rows this captions read used: 1 row per started 15 minutes, and a row is 4 credits. 0 on a repeat of the same video, quality, language, and range inside the 7 day dedupe window. Premium reads report 0, because the Premium transcript job carries their charge." }, "as_of": { "type": [ @@ -6212,7 +6213,7 @@ "number", "null" ], - "description": "Video length in seconds. Null when unknown, which also means the row estimate was unknown." + "description": "Video length in seconds. Null when unknown, which also means the credit estimate was unknown." }, "watch_url": { "type": "string", @@ -6352,7 +6353,7 @@ "job" ] }, - "TranscriptPurchaseQuote": { + "PremiumQuote": { "type": "object", "properties": { "video_id": { @@ -6422,13 +6423,15 @@ ] }, "credits_per_row": { - "type": "number" + "type": "number", + "description": "Credits in a row: 4." }, "max_on_demand_cents": { "type": "number" }, "on_demand_cents_per_unit": { - "type": "number" + "type": "number", + "description": "What one unit of charge.unit costs as on-demand usage, in US cents: 0.2 a credit ($0.002)." }, "refund_policy": { "type": "string" @@ -6621,7 +6624,7 @@ ], "operationId": "get_me", "summary": "Current API key context", - "description": "Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, row usage with period_resets_at, and account settings. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it.", + "description": "Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, usage with period_resets_at, and account settings. usage.credits is the primary measure: credits from the plan, then the on-demand budget. The row fields restate it at 4 credits a row. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it.", "security": [ { "bearerAuth": [] @@ -6887,7 +6890,7 @@ ], "operationId": "verify_signup", "summary": "Exchange a verification code for an account key", - "description": "Consumes the code POST /v1/signups sent, creates the account when the address has none, and mints an arc_sk_ key on it: the read scope, the free tier's lifetime row pool, no expiry. A wrong, expired, or spent code is 400 signup_code_invalid on param code, naming the attempts left; its unlock action is a new send. Send { \"email\": \"agent@example.com\", \"code\": \"482913\" }.", + "description": "Consumes the code POST /v1/signups sent, creates the account when the address has none, and mints an arc_sk_ key on it: the read scope, the free plan's 1,000 credits a month, no expiry. A wrong, expired, or spent code is 400 signup_code_invalid on param code, naming the attempts left; its unlock action is a new send. Send { \"email\": \"agent@example.com\", \"code\": \"482913\" }.", "security": [], "requestBody": { "content": { @@ -6973,7 +6976,7 @@ ], "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.", + "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 entity: use it and name it), suggested (no entity is certain but one stands out, with reason and evidence: use it and tell the user you assumed it), or ask (several entities fit: show ask.options, or check every option id and answer per entity). For a show pass type=channel and use the youtube_channel_id; for a brand or a person use the id. Free; uses no credits.", "security": [ { "bearerAuth": [] @@ -7180,7 +7183,7 @@ ], "operationId": "list_mentions", "summary": "Search mentions across media", - "description": "Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan.", + "description": "Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing mentions remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan.", "security": [ { "bearerAuth": [] @@ -7271,10 +7274,10 @@ { "schema": { "type": "string", - "description": "Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive." + "description": "Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. Needs a paid plan: the free plan refuses it with filter_requires_paid. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive." }, "required": false, - "description": "Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive.", + "description": "Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. Needs a paid plan: the free plan refuses it with filter_requires_paid. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive.", "name": "before", "in": "query" }, @@ -7362,7 +7365,7 @@ ], "operationId": "list_recommendations", "summary": "Search recommendations across media", - "description": "Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds).", + "description": "Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing recommendations remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds).", "security": [ { "bearerAuth": [] @@ -7541,7 +7544,7 @@ ], "operationId": "submit_feedback", "summary": "Submit feedback and corrections for a prior API query", - "description": "Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status \"logged\"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alert rows: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert row id, and every referenced alert row must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with no row to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a row: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query.", + "description": "Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status \"logged\"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alerts: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert id, and every referenced alert must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with nothing to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a result: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query.", "security": [ { "bearerAuth": [] @@ -7612,7 +7615,7 @@ "search", "experience" ], - "description": "The surface being reviewed. Values: recommendations (/v1/recommendations rows by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions rows by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos rows), monitor_alert (fired alert rows from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert row id), appearances (person appearance rows from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one row: requires category and notes, takes no corrections, and query is optional)." + "description": "The surface being reviewed. Values: recommendations (/v1/recommendations results by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions results by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos results), monitor_alert (fired alerts from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert id), appearances (person appearances from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one result: requires category and notes, takes no corrections, and query is optional)." }, "query": { "type": "object", @@ -7658,7 +7661,7 @@ "id": { "type": "string", "minLength": 1, - "description": "Public id of the row being corrected, from the response you received: men_* (mentions, appearances), com_* (recommendations), ent_* (entities, sponsors), or the alert row id (monitor_alert). Omit for missed_alert and missing_result corrections, which have no row to target." + "description": "Public id of the result being corrected, from the response you received: men_* (mentions, appearances), com_* (recommendations), ent_* (entities, sponsors), or the alert id (monitor_alert). Omit for missed_alert and missing_result corrections, which have nothing to target." }, "class": { "type": "string", @@ -7667,7 +7670,7 @@ "organic", "mention" ], - "description": "On recommendations feedback, the class the row should carry. Values: sponsored (an ad-style promotion heard at that moment: a paid sponsor read, promo code, affiliate plug, thanks for supplied goods or venue, or a show promoting its own product as an ad), organic (an unpaid personal recommendation), mention (a neutral commercial mention)." + "description": "On recommendations feedback, the class the result should carry. Values: sponsored (an ad-style promotion heard at that moment: a paid sponsor read, promo code, affiliate plug, thanks for supplied goods or venue, or a show promoting its own product as an ad), organic (an unpaid personal recommendation), mention (a neutral commercial mention)." }, "reason": { "type": "string", @@ -7703,7 +7706,7 @@ "wrong_appearance_role", "other" ], - "description": "Issue classification for the correction. Entity-family values: wrong_entity_type (right entity, wrong type), wrong_entity (the row points at the wrong canonical entity), duplicate_entity (results split across variants of the same entity), merge_suggestion (propose the canonical merge for split variants), missing_result (a result you know should exist is absent), stale_metadata (name/website/channel metadata is outdated), wrong_classification (class-level error on a commercial row), bad_ranking (duplicates or aliases ranking above the canonical entity). monitor_alert values: false_positive_alert (the alert should not have fired), wrong_media (fired against the wrong video), wrong_timestamp (fired at the wrong position in the video), duplicate_alert (the same occurrence fired more than once), missed_alert (an expectation: an alert that should have fired but did not; no row to target), delivery_issue (the delivery itself was wrong: wrong channel, not received). appearances values: person_not_present (the person does not appear in the media), wrong_person (the appearance is attributed to the wrong person), wrong_appearance_role (right person, wrong role, e.g. guest vs host). other (escape hatch; detail in notes)." + "description": "Issue classification for the correction. Entity-family values: wrong_entity_type (right entity, wrong type), wrong_entity (the result points at the wrong canonical entity), duplicate_entity (results split across variants of the same entity), merge_suggestion (propose the canonical merge for split variants), missing_result (a result you know should exist is absent), stale_metadata (name/website/channel metadata is outdated), wrong_classification (class-level error on a commercial result), bad_ranking (duplicates or aliases ranking above the canonical entity). monitor_alert values: false_positive_alert (the alert should not have fired), wrong_media (fired against the wrong video), wrong_timestamp (fired at the wrong position in the video), duplicate_alert (the same occurrence fired more than once), missed_alert (an expectation: an alert that should have fired but did not; nothing to target), delivery_issue (the delivery itself was wrong: wrong channel, not received). appearances values: person_not_present (the person does not appear in the media), wrong_person (the appearance is attributed to the wrong person), wrong_appearance_role (right person, wrong role, e.g. guest vs host). other (escape hatch; detail in notes)." }, "suggested_change": { "anyOf": [ @@ -7747,7 +7750,7 @@ } }, "maxItems": 100, - "description": "Per-row corrections. Not allowed when type is experience." + "description": "Per-result corrections. Not allowed when type is experience." }, "category": { "type": "string", @@ -7759,7 +7762,7 @@ "confusing", "other" ], - "description": "What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a row or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience." + "description": "What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a result or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience." }, "mcp_call_id": { "type": "string", @@ -7848,7 +7851,7 @@ ], "operationId": "get_feedback", "summary": "Read back a feedback submission and its review status", - "description": "Returns the submission (id, type, query, notes, created_at) plus its per-correction rows, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403).", + "description": "Returns the submission (id, type, query, notes, created_at) plus its corrections, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403).", "security": [ { "bearerAuth": [] @@ -8052,7 +8055,7 @@ ], "operationId": "search", "summary": "Retrieve spoken transcript slices for one topic", - "description": "Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per chunk returned. 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.", + "description": "Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per chunk returned past the first 5. 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": [] @@ -8272,7 +8275,7 @@ ], "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.", + "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. Free; uses no credits. 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": [] @@ -8362,7 +8365,7 @@ ], "operationId": "get_channel_coverage", "summary": "What the index holds for a channel", - "description": "How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free (0 rows). 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.", + "description": "How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free; uses no credits. 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": [] @@ -8449,7 +8452,7 @@ ], "operationId": "list_channel_videos", "summary": "Newest indexed videos of a channel", - "description": "The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing rows remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Bills one row per video returned. 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.", + "description": "The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing videos remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Uses 4 credits per video returned past the first 5. 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": [] @@ -8582,7 +8585,7 @@ ], "operationId": "count_mentions", "summary": "Ranked catalog counts of who a set of channels mention", - "description": "A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per table row returned. 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.", + "description": "A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per ranked entry returned past the first 5. 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": [] @@ -8811,7 +8814,7 @@ ], "operationId": "create_monitor", "summary": "Create monitor", - "description": "Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint.", + "description": "Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. Creating monitors and trackers is free. Each alert uses 25 credits once, however many channels and recipients deliver it: credits from your plan, then your on-demand budget. When the account is out of credits, alerts wait instead of sending.", "security": [ { "bearerAuth": [] @@ -10524,7 +10527,7 @@ ], "operationId": "get_transcript", "summary": "Get a video transcript", - "description": "Caption reads use one row per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at zero rows. Otherwise this call starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision.", + "description": "Caption reads use 4 credits per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at no charge. Otherwise this call starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision.", "security": [ { "bearerAuth": [] @@ -10548,10 +10551,10 @@ "captions", "premium" ], - "description": "captions reads creator or automatic captions at 1 row per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at zero rows. Otherwise the read starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings." + "description": "captions reads creator or automatic captions at 4 credits per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at no charge. Otherwise the read starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings." }, "required": false, - "description": "captions reads creator or automatic captions at 1 row per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at zero rows. Otherwise the read starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings.", + "description": "captions reads creator or automatic captions at 4 credits per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at no charge. Otherwise the read starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings.", "name": "quality", "in": "query" }, @@ -10788,7 +10791,7 @@ ], "operationId": "quote_transcription", "summary": "Quote a whole-video Premium transcript", - "description": "Optional free quote: what a Premium read of this video would use right now, as rows and credits, where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id.", + "description": "Optional free quote: what a Premium read of this video would use right now, as rows and credits (a row is 4 credits), where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id.", "security": [ { "bearerAuth": [] @@ -10829,7 +10832,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TranscriptPurchaseQuote" + "$ref": "#/components/schemas/PremiumQuote" } } } diff --git a/reference.md b/reference.md index bbbf5ce..3de0fea 100644 --- a/reference.md +++ b/reference.md @@ -62,7 +62,7 @@ client.health.check()
-Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, row usage with period_resets_at, and account settings. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it. +Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, usage with period_resets_at, and account settings. usage.credits is the primary measure: credits from the plan, then the on-demand budget. The row fields restate it at 4 credits a row. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it.
@@ -200,7 +200,7 @@ client.me.update_settings(
-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. +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 entity: use it and name it), suggested (no entity is certain but one stands out, with reason and evidence: use it and tell the user you assumed it), or ask (several entities fit: show ask.options, or check every option id and answer per entity). For a show pass type=channel and use the youtube_channel_id; for a brand or a person use the id. Free; uses no credits.
@@ -370,7 +370,7 @@ client.entities.get(
-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. +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. Free; uses no credits. 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.
@@ -444,7 +444,7 @@ client.entities.momentum(
-Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan. +Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing mentions remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan.
@@ -549,7 +549,7 @@ client.mentions.list(
-**before:** `typing.Optional[str]` — Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. +**before:** `typing.Optional[str]` — Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. Needs a paid plan: the free plan refuses it with filter_requires_paid. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive.
@@ -589,7 +589,7 @@ client.mentions.list(
-A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per table row returned. 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. +A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per ranked entry returned past the first 5. 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.
@@ -717,7 +717,7 @@ client.mentions.count()
-Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds). +Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing recommendations remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds).
@@ -855,7 +855,7 @@ client.recommendations.list(
-Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alert rows: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert row id, and every referenced alert row must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with no row to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a row: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query. +Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alerts: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert id, and every referenced alert must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with nothing to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a result: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query.
@@ -897,7 +897,7 @@ client.feedback.submit(
-**type:** `SubmitFeedbackRequestType` — The surface being reviewed. Values: recommendations (/v1/recommendations rows by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions rows by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos rows), monitor_alert (fired alert rows from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert row id), appearances (person appearance rows from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one row: requires category and notes, takes no corrections, and query is optional). +**type:** `SubmitFeedbackRequestType` — The surface being reviewed. Values: recommendations (/v1/recommendations results by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions results by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos results), monitor_alert (fired alerts from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert id), appearances (person appearances from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one result: requires category and notes, takes no corrections, and query is optional).
@@ -969,7 +969,7 @@ client.feedback.submit(
-**corrections:** `typing.Optional[typing.List[SubmitFeedbackRequestCorrectionsItem]]` — Per-row corrections. Not allowed when type is experience. +**corrections:** `typing.Optional[typing.List[SubmitFeedbackRequestCorrectionsItem]]` — Per-result corrections. Not allowed when type is experience.
@@ -977,7 +977,7 @@ client.feedback.submit(
-**category:** `typing.Optional[SubmitFeedbackRequestCategory]` — What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a row or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience. +**category:** `typing.Optional[SubmitFeedbackRequestCategory]` — What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a result or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience.
@@ -1017,7 +1017,7 @@ client.feedback.submit(
-Returns the submission (id, type, query, notes, created_at) plus its per-correction rows, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403). +Returns the submission (id, type, query, notes, created_at) plus its corrections, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403).
@@ -1091,7 +1091,7 @@ client.feedback.get(
-Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per chunk returned. 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. +Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per chunk returned past the first 5. 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.
@@ -1244,7 +1244,7 @@ client.transcripts.search(
-Caption reads use one row per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at zero rows. Otherwise this call starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision. +Caption reads use 4 credits per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at no charge. Otherwise this call starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision.
@@ -1293,7 +1293,7 @@ client.transcripts.get(
-**quality:** `typing.Optional[GetTranscriptsRequestQuality]` — captions reads creator or automatic captions at 1 row per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at zero rows. Otherwise the read starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings. +**quality:** `typing.Optional[GetTranscriptsRequestQuality]` — captions reads creator or automatic captions at 4 credits per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at no charge. Otherwise the read starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings.
@@ -1361,7 +1361,7 @@ client.transcripts.get( -
client.transcripts.quote(...) -> TranscriptPurchaseQuote +
client.transcripts.quote(...) -> PremiumQuote
@@ -1373,7 +1373,7 @@ client.transcripts.get(
-Optional free quote: what a Premium read of this video would use right now, as rows and credits, where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id. +Optional free quote: what a Premium read of this video would use right now, as rows and credits (a row is 4 credits), where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id.
@@ -1534,7 +1534,7 @@ client.transcripts.list_requests()
-How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free (0 rows). 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. +How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free; uses no credits. 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.
@@ -1671,7 +1671,7 @@ client.monitors.list()
-Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. +Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. Creating monitors and trackers is free. Each alert uses 25 credits once, however many channels and recipients deliver it: credits from your plan, then your on-demand budget. When the account is out of credits, alerts wait instead of sending.
@@ -2737,7 +2737,7 @@ client.channels.sponsors.list(
-The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing rows remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Bills one row per video returned. 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. +The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing videos remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Uses 4 credits per video returned past the first 5. 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.
diff --git a/src/arcmira/__init__.py b/src/arcmira/__init__.py index 1a93e08..ca13815 100644 --- a/src/arcmira/__init__.py +++ b/src/arcmira/__init__.py @@ -154,6 +154,12 @@ OpenApiDocumentInfo, OpenApiDocumentInfoContact, OpenApiDocumentServersItem, + PremiumQuote, + PremiumQuoteBillingScope, + PremiumQuoteCharge, + PremiumQuoteChargeFrom, + PremiumQuoteChargeUnit, + PremiumQuoteUpgrade, PublicationWindow, Recommendation, RecommendationClass, @@ -195,12 +201,6 @@ TranscriptJobStatus, TranscriptPending, TranscriptPendingQuality, - TranscriptPurchaseQuote, - TranscriptPurchaseQuoteBillingScope, - TranscriptPurchaseQuoteCharge, - TranscriptPurchaseQuoteChargeFrom, - TranscriptPurchaseQuoteChargeUnit, - TranscriptPurchaseQuoteUpgrade, TranscriptQuote, TranscriptRequestListResponse, TranscriptRequestListResponseRequestsItem, @@ -461,6 +461,12 @@ "OpenApiDocumentInfoContact": ".types", "OpenApiDocumentServersItem": ".types", "PaymentRequiredError": ".errors", + "PremiumQuote": ".types", + "PremiumQuoteBillingScope": ".types", + "PremiumQuoteCharge": ".types", + "PremiumQuoteChargeFrom": ".types", + "PremiumQuoteChargeUnit": ".types", + "PremiumQuoteUpgrade": ".types", "PublicationWindow": ".types", "Recommendation": ".types", "RecommendationClass": ".types", @@ -514,12 +520,6 @@ "TranscriptJobStatus": ".types", "TranscriptPending": ".types", "TranscriptPendingQuality": ".types", - "TranscriptPurchaseQuote": ".types", - "TranscriptPurchaseQuoteBillingScope": ".types", - "TranscriptPurchaseQuoteCharge": ".types", - "TranscriptPurchaseQuoteChargeFrom": ".types", - "TranscriptPurchaseQuoteChargeUnit": ".types", - "TranscriptPurchaseQuoteUpgrade": ".types", "TranscriptQuote": ".types", "TranscriptRequestListResponse": ".types", "TranscriptRequestListResponseRequestsItem": ".types", @@ -771,6 +771,12 @@ def __dir__(): "OpenApiDocumentInfoContact", "OpenApiDocumentServersItem", "PaymentRequiredError", + "PremiumQuote", + "PremiumQuoteBillingScope", + "PremiumQuoteCharge", + "PremiumQuoteChargeFrom", + "PremiumQuoteChargeUnit", + "PremiumQuoteUpgrade", "PublicationWindow", "Recommendation", "RecommendationClass", @@ -824,12 +830,6 @@ def __dir__(): "TranscriptJobStatus", "TranscriptPending", "TranscriptPendingQuality", - "TranscriptPurchaseQuote", - "TranscriptPurchaseQuoteBillingScope", - "TranscriptPurchaseQuoteCharge", - "TranscriptPurchaseQuoteChargeFrom", - "TranscriptPurchaseQuoteChargeUnit", - "TranscriptPurchaseQuoteUpgrade", "TranscriptQuote", "TranscriptRequestListResponse", "TranscriptRequestListResponseRequestsItem", diff --git a/src/arcmira/_package.py b/src/arcmira/_package.py index e6ad8e4..8278610 100644 --- a/src/arcmira/_package.py +++ b/src/arcmira/_package.py @@ -1,5 +1,5 @@ # Written by scripts/install-generated.py from VERSION. -__version__ = '0.4.1' +__version__ = '0.4.2' homepage = "https://arcmira.com" docs = "https://arcmira.com/docs" api_base = "https://api.arcmira.com/v1" diff --git a/src/arcmira/channels/client.py b/src/arcmira/channels/client.py index 9f24572..6447b53 100644 --- a/src/arcmira/channels/client.py +++ b/src/arcmira/channels/client.py @@ -36,7 +36,7 @@ def coverage( self, channel_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ChannelCoverageResponse: """ - How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free (0 rows). 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. + How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free; uses no credits. 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. Parameters ---------- @@ -104,7 +104,7 @@ async def coverage( self, channel_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ChannelCoverageResponse: """ - How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free (0 rows). 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. + How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free; uses no credits. 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. Parameters ---------- diff --git a/src/arcmira/channels/raw_client.py b/src/arcmira/channels/raw_client.py index 9c7ae90..448ff8c 100644 --- a/src/arcmira/channels/raw_client.py +++ b/src/arcmira/channels/raw_client.py @@ -29,7 +29,7 @@ def coverage( self, channel_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[ChannelCoverageResponse]: """ - How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free (0 rows). 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. + How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free; uses no credits. 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. Parameters ---------- @@ -143,7 +143,7 @@ async def coverage( self, channel_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[ChannelCoverageResponse]: """ - How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free (0 rows). 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. + How many videos of a YouTube channel are searchable, the newest publish date among them, and the split by transcript source class. Call it when a search or mention lookup came back empty, before telling anyone we do not cover a show, and cite indexed_through as the as-of date for mentions and search_indexed_through for transcript search. It cannot request indexing; channel backfill is not available yet. Free; uses no credits. 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. Parameters ---------- diff --git a/src/arcmira/channels/videos/client.py b/src/arcmira/channels/videos/client.py index 78dc85a..6f2889a 100644 --- a/src/arcmira/channels/videos/client.py +++ b/src/arcmira/channels/videos/client.py @@ -36,7 +36,7 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ChannelVideosResponseEpisodesItem, ChannelVideosResponse]: """ - The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing rows remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Bills one row per video returned. 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. + The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing videos remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Uses 4 credits per video returned past the first 5. 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. Parameters ---------- @@ -110,7 +110,7 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ChannelVideosResponseEpisodesItem, ChannelVideosResponse]: """ - The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing rows remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Bills one row per video returned. 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. + The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing videos remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Uses 4 credits per video returned past the first 5. 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. Parameters ---------- diff --git a/src/arcmira/channels/videos/raw_client.py b/src/arcmira/channels/videos/raw_client.py index 48a9d96..e6c03ac 100644 --- a/src/arcmira/channels/videos/raw_client.py +++ b/src/arcmira/channels/videos/raw_client.py @@ -38,7 +38,7 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[ChannelVideosResponseEpisodesItem, ChannelVideosResponse]: """ - The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing rows remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Bills one row per video returned. 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. + The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing videos remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Uses 4 credits per video returned past the first 5. 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. Parameters ---------- @@ -199,7 +199,7 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[ChannelVideosResponseEpisodesItem, ChannelVideosResponse]: """ - The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing rows remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Bills one row per video returned. 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. + The indexed videos of a YouTube channel, newest first, each with its video_id, title, publish date, duration, view count, and watch_url on arcmira.com. Pass next_cursor as cursor to continue. The signed token binds the route, filters, caller and visibility; invalid or old tokens return invalid_cursor. A first-page media ID fence excludes later insertions, including old-date backfills; edits and deletions to existing videos remain live. Call it for the latest or most recent episode of a show, or to list what a show published in a window, then pass a video_id to GET /v1/mentions/counts video_ids for what that episode mentions or to GET /v1/transcripts/{video_id} to read it. indexed_through is the newest date we hold for the channel. An empty list means nothing is indexed; channel backfill is not available yet. Uses 4 credits per video returned past the first 5. 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. Parameters ---------- diff --git a/src/arcmira/core/client_wrapper.py b/src/arcmira/core/client_wrapper.py index 9643212..cc8ad8a 100644 --- a/src/arcmira/core/client_wrapper.py +++ b/src/arcmira/core/client_wrapper.py @@ -33,7 +33,7 @@ def get_headers(self) -> typing.Dict[str, str]: import platform headers: typing.Dict[str, str] = { - "User-Agent": "arcmira/0.4.1", + "User-Agent": "arcmira/0.4.2", "X-Fern-Language": "Python", "X-Fern-Runtime": f"python/{platform.python_version()}", "X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}", diff --git a/src/arcmira/entities/client.py b/src/arcmira/entities/client.py index fe25e1b..35cc3f2 100644 --- a/src/arcmira/entities/client.py +++ b/src/arcmira/entities/client.py @@ -36,7 +36,7 @@ def resolve( request_options: typing.Optional[RequestOptions] = None, ) -> EntityResolveResponse: """ - 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. + 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 entity: use it and name it), suggested (no entity is certain but one stands out, with reason and evidence: use it and tell the user you assumed it), or ask (several entities fit: show ask.options, or check every option id and answer per entity). For a show pass type=channel and use the youtube_channel_id; for a brand or a person use the id. Free; uses no credits. Parameters ---------- @@ -109,7 +109,7 @@ def get(self, id: str, *, request_options: typing.Optional[RequestOptions] = Non def momentum(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EntityMomentumResponse: """ - 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. + 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. Free; uses no credits. 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. Parameters ---------- @@ -164,7 +164,7 @@ async def resolve( request_options: typing.Optional[RequestOptions] = None, ) -> EntityResolveResponse: """ - 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. + 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 entity: use it and name it), suggested (no entity is certain but one stands out, with reason and evidence: use it and tell the user you assumed it), or ask (several entities fit: show ask.options, or check every option id and answer per entity). For a show pass type=channel and use the youtube_channel_id; for a brand or a person use the id. Free; uses no credits. Parameters ---------- @@ -255,7 +255,7 @@ async def momentum( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> EntityMomentumResponse: """ - 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. + 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. Free; uses no credits. 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. Parameters ---------- diff --git a/src/arcmira/entities/raw_client.py b/src/arcmira/entities/raw_client.py index 4fb0210..731bf28 100644 --- a/src/arcmira/entities/raw_client.py +++ b/src/arcmira/entities/raw_client.py @@ -39,7 +39,7 @@ def resolve( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[EntityResolveResponse]: """ - 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. + 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 entity: use it and name it), suggested (no entity is certain but one stands out, with reason and evidence: use it and tell the user you assumed it), or ask (several entities fit: show ask.options, or check every option id and answer per entity). For a show pass type=channel and use the youtube_channel_id; for a brand or a person use the id. Free; uses no credits. Parameters ---------- @@ -283,7 +283,7 @@ def momentum( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[EntityMomentumResponse]: """ - 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. + 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. Free; uses no credits. 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. Parameters ---------- @@ -414,7 +414,7 @@ async def resolve( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[EntityResolveResponse]: """ - 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. + 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 entity: use it and name it), suggested (no entity is certain but one stands out, with reason and evidence: use it and tell the user you assumed it), or ask (several entities fit: show ask.options, or check every option id and answer per entity). For a show pass type=channel and use the youtube_channel_id; for a brand or a person use the id. Free; uses no credits. Parameters ---------- @@ -658,7 +658,7 @@ async def momentum( self, id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[EntityMomentumResponse]: """ - 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. + 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. Free; uses no credits. 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. Parameters ---------- diff --git a/src/arcmira/feedback/client.py b/src/arcmira/feedback/client.py index 29068f2..f9cd42b 100644 --- a/src/arcmira/feedback/client.py +++ b/src/arcmira/feedback/client.py @@ -49,12 +49,12 @@ def submit( request_options: typing.Optional[RequestOptions] = None, ) -> FeedbackResponse: """ - Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alert rows: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert row id, and every referenced alert row must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with no row to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a row: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query. + Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alerts: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert id, and every referenced alert must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with nothing to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a result: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query. Parameters ---------- type : SubmitFeedbackRequestType - The surface being reviewed. Values: recommendations (/v1/recommendations rows by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions rows by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos rows), monitor_alert (fired alert rows from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert row id), appearances (person appearance rows from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one row: requires category and notes, takes no corrections, and query is optional). + The surface being reviewed. Values: recommendations (/v1/recommendations results by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions results by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos results), monitor_alert (fired alerts from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert id), appearances (person appearances from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one result: requires category and notes, takes no corrections, and query is optional). idempotency_key : typing.Optional[str] 1 to 255 printable ASCII characters (0x21 to 0x7E); anything else is 400 invalid_idempotency_key. Persist a unique key and the exact request before sending a logical mutation. A retry returns its stored response with Idempotency-Replayed: true. A changed intent under a finalized key returns 409 idempotency_conflict. Keys belong to the authenticated owner, credential and mutation domain. Current authorization still applies. Receipts have no general 24-hour expiry; signing-secret recovery alone expires after 24 hours or when the secret is displaced. @@ -76,10 +76,10 @@ def submit( Free text for the reviewer. Required when type is experience: say what the user asked for and what went wrong, slow, or missing. corrections : typing.Optional[typing.Sequence[SubmitFeedbackRequestCorrectionsItem]] - Per-row corrections. Not allowed when type is experience. + Per-result corrections. Not allowed when type is experience. category : typing.Optional[SubmitFeedbackRequestCategory] - What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a row or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience. + What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a result or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience. mcp_call_id : typing.Optional[str] The MCP tool call this feedback is about, as the Arcmira MCP server names it (mcpc_ and 32 hex digits). Joins the feedback to that call in product analytics. @@ -125,7 +125,7 @@ def get( self, feedback_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> FeedbackReadbackResponse: """ - Returns the submission (id, type, query, notes, created_at) plus its per-correction rows, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403). + Returns the submission (id, type, query, notes, created_at) plus its corrections, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403). Parameters ---------- @@ -188,12 +188,12 @@ async def submit( request_options: typing.Optional[RequestOptions] = None, ) -> FeedbackResponse: """ - Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alert rows: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert row id, and every referenced alert row must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with no row to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a row: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query. + Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alerts: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert id, and every referenced alert must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with nothing to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a result: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query. Parameters ---------- type : SubmitFeedbackRequestType - The surface being reviewed. Values: recommendations (/v1/recommendations rows by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions rows by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos rows), monitor_alert (fired alert rows from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert row id), appearances (person appearance rows from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one row: requires category and notes, takes no corrections, and query is optional). + The surface being reviewed. Values: recommendations (/v1/recommendations results by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions results by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos results), monitor_alert (fired alerts from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert id), appearances (person appearances from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one result: requires category and notes, takes no corrections, and query is optional). idempotency_key : typing.Optional[str] 1 to 255 printable ASCII characters (0x21 to 0x7E); anything else is 400 invalid_idempotency_key. Persist a unique key and the exact request before sending a logical mutation. A retry returns its stored response with Idempotency-Replayed: true. A changed intent under a finalized key returns 409 idempotency_conflict. Keys belong to the authenticated owner, credential and mutation domain. Current authorization still applies. Receipts have no general 24-hour expiry; signing-secret recovery alone expires after 24 hours or when the secret is displaced. @@ -215,10 +215,10 @@ async def submit( Free text for the reviewer. Required when type is experience: say what the user asked for and what went wrong, slow, or missing. corrections : typing.Optional[typing.Sequence[SubmitFeedbackRequestCorrectionsItem]] - Per-row corrections. Not allowed when type is experience. + Per-result corrections. Not allowed when type is experience. category : typing.Optional[SubmitFeedbackRequestCategory] - What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a row or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience. + What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a result or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience. mcp_call_id : typing.Optional[str] The MCP tool call this feedback is about, as the Arcmira MCP server names it (mcpc_ and 32 hex digits). Joins the feedback to that call in product analytics. @@ -272,7 +272,7 @@ async def get( self, feedback_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> FeedbackReadbackResponse: """ - Returns the submission (id, type, query, notes, created_at) plus its per-correction rows, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403). + Returns the submission (id, type, query, notes, created_at) plus its corrections, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403). Parameters ---------- diff --git a/src/arcmira/feedback/raw_client.py b/src/arcmira/feedback/raw_client.py index 3f100c7..3441465 100644 --- a/src/arcmira/feedback/raw_client.py +++ b/src/arcmira/feedback/raw_client.py @@ -53,12 +53,12 @@ def submit( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[FeedbackResponse]: """ - Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alert rows: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert row id, and every referenced alert row must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with no row to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a row: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query. + Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alerts: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert id, and every referenced alert must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with nothing to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a result: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query. Parameters ---------- type : SubmitFeedbackRequestType - The surface being reviewed. Values: recommendations (/v1/recommendations rows by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions rows by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos rows), monitor_alert (fired alert rows from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert row id), appearances (person appearance rows from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one row: requires category and notes, takes no corrections, and query is optional). + The surface being reviewed. Values: recommendations (/v1/recommendations results by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions results by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos results), monitor_alert (fired alerts from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert id), appearances (person appearances from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one result: requires category and notes, takes no corrections, and query is optional). idempotency_key : typing.Optional[str] 1 to 255 printable ASCII characters (0x21 to 0x7E); anything else is 400 invalid_idempotency_key. Persist a unique key and the exact request before sending a logical mutation. A retry returns its stored response with Idempotency-Replayed: true. A changed intent under a finalized key returns 409 idempotency_conflict. Keys belong to the authenticated owner, credential and mutation domain. Current authorization still applies. Receipts have no general 24-hour expiry; signing-secret recovery alone expires after 24 hours or when the secret is displaced. @@ -80,10 +80,10 @@ def submit( Free text for the reviewer. Required when type is experience: say what the user asked for and what went wrong, slow, or missing. corrections : typing.Optional[typing.Sequence[SubmitFeedbackRequestCorrectionsItem]] - Per-row corrections. Not allowed when type is experience. + Per-result corrections. Not allowed when type is experience. category : typing.Optional[SubmitFeedbackRequestCategory] - What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a row or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience. + What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a result or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience. mcp_call_id : typing.Optional[str] The MCP tool call this feedback is about, as the Arcmira MCP server names it (mcpc_ and 32 hex digits). Joins the feedback to that call in product analytics. @@ -223,7 +223,7 @@ def get( self, feedback_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[FeedbackReadbackResponse]: """ - Returns the submission (id, type, query, notes, created_at) plus its per-correction rows, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403). + Returns the submission (id, type, query, notes, created_at) plus its corrections, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403). Parameters ---------- @@ -351,12 +351,12 @@ async def submit( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[FeedbackResponse]: """ - Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alert rows: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert row id, and every referenced alert row must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with no row to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a row: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query. + Attach corrections to the exact query you ran: pass the feedback type, the query object you sent, and optional per-item corrections. Public submissions are recorded for human review (status "logged"); nothing is auto-applied. Read the review status back later via GET /v1/feedback/{feedback_id}. recommendations and channel_sponsors feedback types require a Pro+ plan; every other type needs read. monitor_alert feedback targets fired alerts: query carries monitor_id and/or tracker_id and/or alert_id, corrections target the alert id, and every referenced alert must belong to the caller (otherwise 404 alert_not_found). missed_alert corrections are expectations with nothing to target: omit the correction id and put { source_url, approximate_timestamp_seconds?, entity_id? } in suggested_change. delivery_issue corrections may carry { channel } in suggested_change. experience feedback says how a task went as a whole rather than correcting a result: it requires category and notes, refuses corrections (400 invalid_feedback_request), and needs no query. category and mcp_call_id, when sent, are recorded in the stored query. Parameters ---------- type : SubmitFeedbackRequestType - The surface being reviewed. Values: recommendations (/v1/recommendations rows by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions rows by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos rows), monitor_alert (fired alert rows from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert row id), appearances (person appearance rows from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one row: requires category and notes, takes no corrections, and query is optional). + The surface being reviewed. Values: recommendations (/v1/recommendations results by com_* id; requires a Pro+ plan), channel_sponsors (sponsor entities on a channel; requires a Pro+ plan), mentions (/v1/mentions results by men_* id), entities_search (/v1/entities/resolve candidates), entities (/v1/entities/{id} payloads), channels (/v1/channels/{channel_id}/videos results), monitor_alert (fired alerts from /v1/monitors/{id}/alerts or /v1/trackers/{id}/alerts; corrections target the alert id), appearances (person appearances from /v1/mentions with is_appearance=true), search (/v1/search passages), experience (how a task went as a whole, not one result: requires category and notes, takes no corrections, and query is optional). idempotency_key : typing.Optional[str] 1 to 255 printable ASCII characters (0x21 to 0x7E); anything else is 400 invalid_idempotency_key. Persist a unique key and the exact request before sending a logical mutation. A retry returns its stored response with Idempotency-Replayed: true. A changed intent under a finalized key returns 409 idempotency_conflict. Keys belong to the authenticated owner, credential and mutation domain. Current authorization still applies. Receipts have no general 24-hour expiry; signing-secret recovery alone expires after 24 hours or when the secret is displaced. @@ -378,10 +378,10 @@ async def submit( Free text for the reviewer. Required when type is experience: say what the user asked for and what went wrong, slow, or missing. corrections : typing.Optional[typing.Sequence[SubmitFeedbackRequestCorrectionsItem]] - Per-row corrections. Not allowed when type is experience. + Per-result corrections. Not allowed when type is experience. category : typing.Optional[SubmitFeedbackRequestCategory] - What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a row or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience. + What kind of problem this is. Values: wrong_entity (a name resolved to the wrong person, company or thing), bad_data (a result or field is wrong), missing (something that should exist was not found), slow (the task took too long), confusing (the answer or an error was hard to act on), other (anything else; say what in notes). Required when type is experience. mcp_call_id : typing.Optional[str] The MCP tool call this feedback is about, as the Arcmira MCP server names it (mcpc_ and 32 hex digits). Joins the feedback to that call in product analytics. @@ -521,7 +521,7 @@ async def get( self, feedback_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[FeedbackReadbackResponse]: """ - Returns the submission (id, type, query, notes, created_at) plus its per-correction rows, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403). + Returns the submission (id, type, query, notes, created_at) plus its corrections, each with a review status in the public vocabulary: pending_review, needs_information, accepted, accepted_with_changes, rejected, withdrawn, applied, reverted (accepted means a reviewer agreed; applied means the change is live in the index). Only the submitting user's keys can read a submission; unknown ids and other users' submissions both return 404 (never 403). Parameters ---------- diff --git a/src/arcmira/feedback/types/submit_feedback_request_corrections_item.py b/src/arcmira/feedback/types/submit_feedback_request_corrections_item.py index dcca580..1bdbfb7 100644 --- a/src/arcmira/feedback/types/submit_feedback_request_corrections_item.py +++ b/src/arcmira/feedback/types/submit_feedback_request_corrections_item.py @@ -17,7 +17,7 @@ class SubmitFeedbackRequestCorrectionsItem(UniversalBaseModel): id: typing.Optional[str] = pydantic.Field(default=None) """ - Public id of the row being corrected, from the response you received: men_* (mentions, appearances), com_* (recommendations), ent_* (entities, sponsors), or the alert row id (monitor_alert). Omit for missed_alert and missing_result corrections, which have no row to target. + Public id of the result being corrected, from the response you received: men_* (mentions, appearances), com_* (recommendations), ent_* (entities, sponsors), or the alert id (monitor_alert). Omit for missed_alert and missing_result corrections, which have nothing to target. """ class_: typing_extensions.Annotated[ @@ -25,17 +25,17 @@ class SubmitFeedbackRequestCorrectionsItem(UniversalBaseModel): FieldMetadata(alias="class"), pydantic.Field( alias="class", - description="On recommendations feedback, the class the row should carry. Values: sponsored (an ad-style promotion heard at that moment: a paid sponsor read, promo code, affiliate plug, thanks for supplied goods or venue, or a show promoting its own product as an ad), organic (an unpaid personal recommendation), mention (a neutral commercial mention).", + description="On recommendations feedback, the class the result should carry. Values: sponsored (an ad-style promotion heard at that moment: a paid sponsor read, promo code, affiliate plug, thanks for supplied goods or venue, or a show promoting its own product as an ad), organic (an unpaid personal recommendation), mention (a neutral commercial mention).", ), ] = None """ - On recommendations feedback, the class the row should carry. Values: sponsored (an ad-style promotion heard at that moment: a paid sponsor read, promo code, affiliate plug, thanks for supplied goods or venue, or a show promoting its own product as an ad), organic (an unpaid personal recommendation), mention (a neutral commercial mention). + On recommendations feedback, the class the result should carry. Values: sponsored (an ad-style promotion heard at that moment: a paid sponsor read, promo code, affiliate plug, thanks for supplied goods or venue, or a show promoting its own product as an ad), organic (an unpaid personal recommendation), mention (a neutral commercial mention). """ reason: typing.Optional[SubmitFeedbackRequestCorrectionsItemReason] = None issue_type: typing.Optional[SubmitFeedbackRequestCorrectionsItemIssueType] = pydantic.Field(default=None) """ - Issue classification for the correction. Entity-family values: wrong_entity_type (right entity, wrong type), wrong_entity (the row points at the wrong canonical entity), duplicate_entity (results split across variants of the same entity), merge_suggestion (propose the canonical merge for split variants), missing_result (a result you know should exist is absent), stale_metadata (name/website/channel metadata is outdated), wrong_classification (class-level error on a commercial row), bad_ranking (duplicates or aliases ranking above the canonical entity). monitor_alert values: false_positive_alert (the alert should not have fired), wrong_media (fired against the wrong video), wrong_timestamp (fired at the wrong position in the video), duplicate_alert (the same occurrence fired more than once), missed_alert (an expectation: an alert that should have fired but did not; no row to target), delivery_issue (the delivery itself was wrong: wrong channel, not received). appearances values: person_not_present (the person does not appear in the media), wrong_person (the appearance is attributed to the wrong person), wrong_appearance_role (right person, wrong role, e.g. guest vs host). other (escape hatch; detail in notes). + Issue classification for the correction. Entity-family values: wrong_entity_type (right entity, wrong type), wrong_entity (the result points at the wrong canonical entity), duplicate_entity (results split across variants of the same entity), merge_suggestion (propose the canonical merge for split variants), missing_result (a result you know should exist is absent), stale_metadata (name/website/channel metadata is outdated), wrong_classification (class-level error on a commercial result), bad_ranking (duplicates or aliases ranking above the canonical entity). monitor_alert values: false_positive_alert (the alert should not have fired), wrong_media (fired against the wrong video), wrong_timestamp (fired at the wrong position in the video), duplicate_alert (the same occurrence fired more than once), missed_alert (an expectation: an alert that should have fired but did not; nothing to target), delivery_issue (the delivery itself was wrong: wrong channel, not received). appearances values: person_not_present (the person does not appear in the media), wrong_person (the appearance is attributed to the wrong person), wrong_appearance_role (right person, wrong role, e.g. guest vs host). other (escape hatch; detail in notes). """ suggested_change: typing.Optional[SubmitFeedbackRequestCorrectionsItemSuggestedChange] = pydantic.Field( diff --git a/src/arcmira/me/client.py b/src/arcmira/me/client.py index 264e0ed..8b91d24 100644 --- a/src/arcmira/me/client.py +++ b/src/arcmira/me/client.py @@ -30,7 +30,7 @@ def with_raw_response(self) -> RawMeClient: def get(self, *, request_options: typing.Optional[RequestOptions] = None) -> MeResponse: """ - Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, row usage with period_resets_at, and account settings. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it. + Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, usage with period_resets_at, and account settings. usage.credits is the primary measure: credits from the plan, then the on-demand budget. The row fields restate it at 4 credits a row. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it. Parameters ---------- @@ -109,7 +109,7 @@ def with_raw_response(self) -> AsyncRawMeClient: async def get(self, *, request_options: typing.Optional[RequestOptions] = None) -> MeResponse: """ - Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, row usage with period_resets_at, and account settings. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it. + Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, usage with period_resets_at, and account settings. usage.credits is the primary measure: credits from the plan, then the on-demand budget. The row fields restate it at 4 credits a row. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it. Parameters ---------- diff --git a/src/arcmira/me/raw_client.py b/src/arcmira/me/raw_client.py index 551ee67..59de49c 100644 --- a/src/arcmira/me/raw_client.py +++ b/src/arcmira/me/raw_client.py @@ -32,7 +32,7 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def get(self, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[MeResponse]: """ - Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, row usage with period_resets_at, and account settings. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it. + Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, usage with period_resets_at, and account settings. usage.credits is the primary measure: credits from the plan, then the on-demand budget. The row fields restate it at 4 credits a row. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it. Parameters ---------- @@ -262,7 +262,7 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def get(self, *, request_options: typing.Optional[RequestOptions] = None) -> AsyncHttpResponse[MeResponse]: """ - Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, row usage with period_resets_at, and account settings. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it. + Available even when the account has exhausted its usage allowance. Returns the credential making the request (key_id, key_label, credential_kind), the masked account email, the tier, scopes, rate limit, usage with period_resets_at, and account settings. usage.credits is the primary measure: credits from the plan, then the on-demand budget. The row fields restate it at 4 credits a row. settings.transcripts is what a transcript request that names no parameter of its own receives: every key of the account resolves against it. Parameters ---------- diff --git a/src/arcmira/mentions/client.py b/src/arcmira/mentions/client.py index 224f23d..cec7213 100644 --- a/src/arcmira/mentions/client.py +++ b/src/arcmira/mentions/client.py @@ -45,7 +45,7 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Mention, MentionListResponse]: """ - Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan. + Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing mentions remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan. Parameters ---------- @@ -70,7 +70,7 @@ def list( Only media published at or after this instant. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. before : typing.Optional[str] - Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. + Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. Needs a paid plan: the free plan refuses it with filter_requires_paid. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. details : typing.Optional[ListMentionsRequestDetails] @@ -126,7 +126,7 @@ def count( request_options: typing.Optional[RequestOptions] = None, ) -> MentionCountsResponse: """ - A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per table row returned. 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. + A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per ranked entry returned past the first 5. 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. Parameters ---------- @@ -216,7 +216,7 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Mention, MentionListResponse]: """ - Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan. + Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing mentions remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan. Parameters ---------- @@ -241,7 +241,7 @@ async def list( Only media published at or after this instant. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. before : typing.Optional[str] - Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. + Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. Needs a paid plan: the free plan refuses it with filter_requires_paid. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. details : typing.Optional[ListMentionsRequestDetails] @@ -306,7 +306,7 @@ async def count( request_options: typing.Optional[RequestOptions] = None, ) -> MentionCountsResponse: """ - A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per table row returned. 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. + A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per ranked entry returned past the first 5. 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. Parameters ---------- diff --git a/src/arcmira/mentions/raw_client.py b/src/arcmira/mentions/raw_client.py index b44a564..bd30d7c 100644 --- a/src/arcmira/mentions/raw_client.py +++ b/src/arcmira/mentions/raw_client.py @@ -47,7 +47,7 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Mention, MentionListResponse]: """ - Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan. + Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing mentions remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan. Parameters ---------- @@ -72,7 +72,7 @@ def list( Only media published at or after this instant. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. before : typing.Optional[str] - Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. + Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. Needs a paid plan: the free plan refuses it with filter_requires_paid. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. details : typing.Optional[ListMentionsRequestDetails] @@ -227,7 +227,7 @@ def count( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[MentionCountsResponse]: """ - A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per table row returned. 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. + A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per ranked entry returned past the first 5. 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. Parameters ---------- @@ -395,7 +395,7 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Mention, MentionListResponse]: """ - Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan. + Cursor-paginated mentions filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), text query, sentiment, appearance flag, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing mentions remain live. Positions are start_seconds and end_seconds (integer seconds; 0 means full episode). is_appearance filtering applies to person entities only; passing is_appearance=true for any other type returns a 400 (appearances_person_only). details=full attaches per-mention commercial recommendations and requires a Pro+ plan. Parameters ---------- @@ -420,7 +420,7 @@ async def list( Only media published at or after this instant. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. before : typing.Optional[str] - Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. + Only media published before this instant, so before=2026-09-02 includes all of 2026-09-01. Needs a paid plan: the free plan refuses it with filter_requires_paid. An ISO 8601 date (2026-09-01) or datetime with offset (2026-09-01T00:00:00Z), read in UTC. The window is half-open: after is inclusive, before is exclusive. details : typing.Optional[ListMentionsRequestDetails] @@ -578,7 +578,7 @@ async def count( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[MentionCountsResponse]: """ - A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per table row returned. 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. + A small ranked table of entity and channel counts, all-time unless after is set. Pass channel_ids for what shows talk about and entity_types to match the question (topic for subjects, person for guests, organization,product for brands). Pass video_ids with one id from GET /v1/channels/{channel_id}/videos for what a single episode mentions. Two or more channel_ids also return shared, the entities on more than one of them ranked by the smallest per-channel count, which is true overlap. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per ranked entry returned past the first 5. 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. Parameters ---------- diff --git a/src/arcmira/monitors/client.py b/src/arcmira/monitors/client.py index 79f3fa6..5342ad4 100644 --- a/src/arcmira/monitors/client.py +++ b/src/arcmira/monitors/client.py @@ -85,7 +85,7 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> MonitorMutationResponse: """ - Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. + Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. Creating monitors and trackers is free. Each alert uses 25 credits once, however many channels and recipients deliver it: credits from your plan, then your on-demand budget. When the account is out of credits, alerts wait instead of sending. Parameters ---------- @@ -442,7 +442,7 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> MonitorMutationResponse: """ - Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. + Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. Creating monitors and trackers is free. Each alert uses 25 credits once, however many channels and recipients deliver it: credits from your plan, then your on-demand budget. When the account is out of credits, alerts wait instead of sending. Parameters ---------- diff --git a/src/arcmira/monitors/raw_client.py b/src/arcmira/monitors/raw_client.py index 47b9e7a..6b946ce 100644 --- a/src/arcmira/monitors/raw_client.py +++ b/src/arcmira/monitors/raw_client.py @@ -156,7 +156,7 @@ def create( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[MonitorMutationResponse]: """ - Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. + Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. Creating monitors and trackers is free. Each alert uses 25 credits once, however many channels and recipients deliver it: credits from your plan, then your on-demand budget. When the account is out of credits, alerts wait instead of sending. Parameters ---------- @@ -901,7 +901,7 @@ async def create( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[MonitorMutationResponse]: """ - Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. + Creating with notify_webhook: true and a webhook_url enables HMAC-signed webhook delivery and returns the signing secret (monitor.webhook_secret) in this response. Store it securely. A retry with the original Idempotency-Key recovers the same secret for up to 24 hours while it remains the current secret or the valid previous secret. An expired or displaced secret returns 409 idempotency_result_expired without rotating again. Reads do not expose the secret. All subsequent reads expose only webhook_secret_set and webhook_secret_hint. Creating monitors and trackers is free. Each alert uses 25 credits once, however many channels and recipients deliver it: credits from your plan, then your on-demand budget. When the account is out of credits, alerts wait instead of sending. Parameters ---------- diff --git a/src/arcmira/recommendations/client.py b/src/arcmira/recommendations/client.py index 754e86f..be57d06 100644 --- a/src/arcmira/recommendations/client.py +++ b/src/arcmira/recommendations/client.py @@ -41,7 +41,7 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Recommendation, RecommendationListResponse]: """ - Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds). + Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing recommendations remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds). Parameters ---------- @@ -137,7 +137,7 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Recommendation, RecommendationListResponse]: """ - Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds). + Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing recommendations remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds). Parameters ---------- diff --git a/src/arcmira/recommendations/raw_client.py b/src/arcmira/recommendations/raw_client.py index 85bb569..db42fdc 100644 --- a/src/arcmira/recommendations/raw_client.py +++ b/src/arcmira/recommendations/raw_client.py @@ -42,7 +42,7 @@ def list( request_options: typing.Optional[RequestOptions] = None, ) -> SyncPager[Recommendation, RecommendationListResponse]: """ - Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds). + Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing recommendations remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds). Parameters ---------- @@ -225,7 +225,7 @@ async def list( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncPager[Recommendation, RecommendationListResponse]: """ - Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing rows remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds). + Cursor-paginated commercial mentions (sponsored, organic and neutral mentions) filtered by entity (entity_id is required; resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter), channel (channel_id), class, confidence, and publication window [after, before). The signed continuation binds the route, filters, caller and visibility; invalid or old cursors return invalid_cursor. A first-page ID fence excludes later insertions, including old-date backfills. Edits and deletions to existing recommendations remain live. Requires a Pro+ plan. Positions are start_seconds and end_seconds (integer seconds). Parameters ---------- diff --git a/src/arcmira/transcripts/client.py b/src/arcmira/transcripts/client.py index a65cc3d..3ee874e 100644 --- a/src/arcmira/transcripts/client.py +++ b/src/arcmira/transcripts/client.py @@ -5,7 +5,7 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.pagination import AsyncPager, SyncPager from ..core.request_options import RequestOptions -from ..types.transcript_purchase_quote import TranscriptPurchaseQuote +from ..types.premium_quote import PremiumQuote from ..types.transcript_request_list_response import TranscriptRequestListResponse from ..types.transcript_request_list_response_requests_item import TranscriptRequestListResponseRequestsItem from ..types.transcript_result import TranscriptResult @@ -47,7 +47,7 @@ def search( request_options: typing.Optional[RequestOptions] = None, ) -> TranscriptSearchResponse: """ - Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per chunk returned. 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. + Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per chunk returned past the first 5. 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. Parameters ---------- @@ -133,7 +133,7 @@ def get( request_options: typing.Optional[RequestOptions] = None, ) -> TranscriptResult: """ - Caption reads use one row per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at zero rows. Otherwise this call starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision. + Caption reads use 4 credits per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at no charge. Otherwise this call starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision. Parameters ---------- @@ -141,7 +141,7 @@ def get( YouTube video id, 11 characters. quality : typing.Optional[GetTranscriptsRequestQuality] - captions reads creator or automatic captions at 1 row per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at zero rows. Otherwise the read starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings. + captions reads creator or automatic captions at 4 credits per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at no charge. Otherwise the read starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings. language : typing.Optional[str] Comma-separated caption language priority list, at most 5, tried in order (e.g. "de,en"). Use asr for the first automatic track and asr- for a specific one. Default en. languages[] in the response lists every track the video offers. @@ -193,11 +193,9 @@ def get( ) return _response.data - def quote( - self, video_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> TranscriptPurchaseQuote: + def quote(self, video_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> PremiumQuote: """ - Optional free quote: what a Premium read of this video would use right now, as rows and credits, where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id. + Optional free quote: what a Premium read of this video would use right now, as rows and credits (a row is 4 credits), where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id. Parameters ---------- @@ -209,7 +207,7 @@ def quote( Returns ------- - TranscriptPurchaseQuote + PremiumQuote Success Examples @@ -307,7 +305,7 @@ async def search( request_options: typing.Optional[RequestOptions] = None, ) -> TranscriptSearchResponse: """ - Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per chunk returned. 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. + Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per chunk returned past the first 5. 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. Parameters ---------- @@ -401,7 +399,7 @@ async def get( request_options: typing.Optional[RequestOptions] = None, ) -> TranscriptResult: """ - Caption reads use one row per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at zero rows. Otherwise this call starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision. + Caption reads use 4 credits per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at no charge. Otherwise this call starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision. Parameters ---------- @@ -409,7 +407,7 @@ async def get( YouTube video id, 11 characters. quality : typing.Optional[GetTranscriptsRequestQuality] - captions reads creator or automatic captions at 1 row per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at zero rows. Otherwise the read starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings. + captions reads creator or automatic captions at 4 credits per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at no charge. Otherwise the read starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings. language : typing.Optional[str] Comma-separated caption language priority list, at most 5, tried in order (e.g. "de,en"). Use asr for the first automatic track and asr- for a specific one. Default en. languages[] in the response lists every track the video offers. @@ -469,11 +467,9 @@ async def main() -> None: ) return _response.data - async def quote( - self, video_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> TranscriptPurchaseQuote: + async def quote(self, video_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> PremiumQuote: """ - Optional free quote: what a Premium read of this video would use right now, as rows and credits, where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id. + Optional free quote: what a Premium read of this video would use right now, as rows and credits (a row is 4 credits), where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id. Parameters ---------- @@ -485,7 +481,7 @@ async def quote( Returns ------- - TranscriptPurchaseQuote + PremiumQuote Success Examples diff --git a/src/arcmira/transcripts/raw_client.py b/src/arcmira/transcripts/raw_client.py index c582ff4..ade787e 100644 --- a/src/arcmira/transcripts/raw_client.py +++ b/src/arcmira/transcripts/raw_client.py @@ -20,7 +20,7 @@ from ..errors.too_many_requests_error import TooManyRequestsError from ..errors.unauthorized_error import UnauthorizedError from ..types.error import Error -from ..types.transcript_purchase_quote import TranscriptPurchaseQuote +from ..types.premium_quote import PremiumQuote from ..types.transcript_request_list_response import TranscriptRequestListResponse from ..types.transcript_request_list_response_requests_item import TranscriptRequestListResponseRequestsItem from ..types.transcript_result import TranscriptResult @@ -51,7 +51,7 @@ def search( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[TranscriptSearchResponse]: """ - Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per chunk returned. 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. + Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per chunk returned past the first 5. 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. Parameters ---------- @@ -235,7 +235,7 @@ def get( request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[TranscriptResult]: """ - Caption reads use one row per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at zero rows. Otherwise this call starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision. + Caption reads use 4 credits per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at no charge. Otherwise this call starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision. Parameters ---------- @@ -243,7 +243,7 @@ def get( YouTube video id, 11 characters. quality : typing.Optional[GetTranscriptsRequestQuality] - captions reads creator or automatic captions at 1 row per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at zero rows. Otherwise the read starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings. + captions reads creator or automatic captions at 4 credits per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at no charge. Otherwise the read starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings. language : typing.Optional[str] Comma-separated caption language priority list, at most 5, tried in order (e.g. "de,en"). Use asr for the first automatic track and asr- for a specific one. Default en. languages[] in the response lists every track the video offers. @@ -394,9 +394,9 @@ def get( def quote( self, video_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[TranscriptPurchaseQuote]: + ) -> HttpResponse[PremiumQuote]: """ - Optional free quote: what a Premium read of this video would use right now, as rows and credits, where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id. + Optional free quote: what a Premium read of this video would use right now, as rows and credits (a row is 4 credits), where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id. Parameters ---------- @@ -408,7 +408,7 @@ def quote( Returns ------- - HttpResponse[TranscriptPurchaseQuote] + HttpResponse[PremiumQuote] Success """ _response = self._client_wrapper.httpx_client.request( @@ -419,9 +419,9 @@ def quote( try: if 200 <= _response.status_code < 300: _data = typing.cast( - TranscriptPurchaseQuote, + PremiumQuote, parse_obj_as( - type_=TranscriptPurchaseQuote, # type: ignore + type_=PremiumQuote, # type: ignore object_=_response.json(), ), ) @@ -657,7 +657,7 @@ async def search( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[TranscriptSearchResponse]: """ - Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Bills one row per chunk returned. 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. + Search indexed YouTube and podcast transcripts for short spoken slices. Each result includes spoken text, a watch URL, and a publish date. Scope with channel_ids (or channel) and entity_ids (a person id filters to that person's appearances); narrow to passages about entities with about, to a speaker with by, and to sponsored, organic or mention passages with kind. Every filter takes ids, never names: resolve a name first with GET /v1/entities/resolve, or the call answers 400 id_required naming the parameter. Results carry names beside ids (filters.about, filters.by, chunk about and speakers_by). Use one topic per call. Search results include text on every plan within the plan's publication-date window. Explicitly requesting source=arcmira_premium on a plan without Premium transcripts is refused with filter_requires_paid. An after later than the plan's freshness gate is refused with freshness_requires_paid rather than widened. Uses 4 credits per chunk returned past the first 5. 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. Parameters ---------- @@ -841,7 +841,7 @@ async def get( request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[TranscriptResult]: """ - Caption reads use one row per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at zero rows. Otherwise this call starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision. + Caption reads use 4 credits per started 15 minutes. quality=premium is one read. An owned transcript answers 200 ready at no charge. Otherwise this call starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and answers 202 pending with the job and Retry-After until the transcript is ready. Read again after Retry-After; repeated reads join the same job and never charge twice. When the last Premium transcript for the video failed, the read answers 200 state failed with the job and last_attempt and charges nothing; retry=true starts a new one. When the plan or the budget blocks, 403 paid_plan_required (with unlock) or 402 quota_exceeded or spend_limit_exceeded carries the price in quote and nothing is charged. A default-premium account with nothing owned reads captions with a note. start/end only trim the returned content; language selects caption tracks, timestamps=false returns paragraphs. Premium lines carry speaker and index, and the body carries speakers and revision. Parameters ---------- @@ -849,7 +849,7 @@ async def get( YouTube video id, 11 characters. quality : typing.Optional[GetTranscriptsRequestQuality] - captions reads creator or automatic captions at 1 row per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at zero rows. Otherwise the read starts a Premium transcript of the whole video, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings. + captions reads creator or automatic captions at 4 credits per started 15 minutes. premium is one read. An owned transcript returns 200 state ready at no charge. Otherwise the read starts a Premium transcript of the whole video, 300 credits per started 15 minutes, using credits from the account's plan first and then the account's on-demand budget up to its limit, and returns 202 state pending with the job until it is ready. When the last Premium transcript for the video failed it answers 200 state failed and starts a new one only with retry=true. 402 quota_exceeded or spend_limit_exceeded and 403 paid_plan_required carry the price in quote. It never substitutes captions. Default captions unless changed in account settings. language : typing.Optional[str] Comma-separated caption language priority list, at most 5, tried in order (e.g. "de,en"). Use asr for the first automatic track and asr- for a specific one. Default en. languages[] in the response lists every track the video offers. @@ -1000,9 +1000,9 @@ async def get( async def quote( self, video_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[TranscriptPurchaseQuote]: + ) -> AsyncHttpResponse[PremiumQuote]: """ - Optional free quote: what a Premium read of this video would use right now, as rows and credits, where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id. + Optional free quote: what a Premium read of this video would use right now, as rows and credits (a row is 4 credits), where the credits would come from, and max_on_demand_cents, the on-demand budget the read would need beyond the plan's credits within the account limit. It does not reserve credits or budget and does not start a transcript. A video with no known duration, or one past the 12 hour cap, answers 400 invalid_query with param video_id. Parameters ---------- @@ -1014,7 +1014,7 @@ async def quote( Returns ------- - AsyncHttpResponse[TranscriptPurchaseQuote] + AsyncHttpResponse[PremiumQuote] Success """ _response = await self._client_wrapper.httpx_client.request( @@ -1025,9 +1025,9 @@ async def quote( try: if 200 <= _response.status_code < 300: _data = typing.cast( - TranscriptPurchaseQuote, + PremiumQuote, parse_obj_as( - type_=TranscriptPurchaseQuote, # type: ignore + type_=PremiumQuote, # type: ignore object_=_response.json(), ), ) diff --git a/src/arcmira/types/__init__.py b/src/arcmira/types/__init__.py index 86e85f4..5fdc1df 100644 --- a/src/arcmira/types/__init__.py +++ b/src/arcmira/types/__init__.py @@ -155,6 +155,12 @@ from .open_api_document_info import OpenApiDocumentInfo from .open_api_document_info_contact import OpenApiDocumentInfoContact from .open_api_document_servers_item import OpenApiDocumentServersItem + from .premium_quote import PremiumQuote + from .premium_quote_billing_scope import PremiumQuoteBillingScope + from .premium_quote_charge import PremiumQuoteCharge + from .premium_quote_charge_from import PremiumQuoteChargeFrom + from .premium_quote_charge_unit import PremiumQuoteChargeUnit + from .premium_quote_upgrade import PremiumQuoteUpgrade from .publication_window import PublicationWindow from .recommendation import Recommendation from .recommendation_class import RecommendationClass @@ -198,12 +204,6 @@ from .transcript_job_status import TranscriptJobStatus from .transcript_pending import TranscriptPending from .transcript_pending_quality import TranscriptPendingQuality - from .transcript_purchase_quote import TranscriptPurchaseQuote - from .transcript_purchase_quote_billing_scope import TranscriptPurchaseQuoteBillingScope - from .transcript_purchase_quote_charge import TranscriptPurchaseQuoteCharge - from .transcript_purchase_quote_charge_from import TranscriptPurchaseQuoteChargeFrom - from .transcript_purchase_quote_charge_unit import TranscriptPurchaseQuoteChargeUnit - from .transcript_purchase_quote_upgrade import TranscriptPurchaseQuoteUpgrade from .transcript_quote import TranscriptQuote from .transcript_request_list_response import TranscriptRequestListResponse from .transcript_request_list_response_requests_item import TranscriptRequestListResponseRequestsItem @@ -398,6 +398,12 @@ "OpenApiDocumentInfo": ".open_api_document_info", "OpenApiDocumentInfoContact": ".open_api_document_info_contact", "OpenApiDocumentServersItem": ".open_api_document_servers_item", + "PremiumQuote": ".premium_quote", + "PremiumQuoteBillingScope": ".premium_quote_billing_scope", + "PremiumQuoteCharge": ".premium_quote_charge", + "PremiumQuoteChargeFrom": ".premium_quote_charge_from", + "PremiumQuoteChargeUnit": ".premium_quote_charge_unit", + "PremiumQuoteUpgrade": ".premium_quote_upgrade", "PublicationWindow": ".publication_window", "Recommendation": ".recommendation", "RecommendationClass": ".recommendation_class", @@ -439,12 +445,6 @@ "TranscriptJobStatus": ".transcript_job_status", "TranscriptPending": ".transcript_pending", "TranscriptPendingQuality": ".transcript_pending_quality", - "TranscriptPurchaseQuote": ".transcript_purchase_quote", - "TranscriptPurchaseQuoteBillingScope": ".transcript_purchase_quote_billing_scope", - "TranscriptPurchaseQuoteCharge": ".transcript_purchase_quote_charge", - "TranscriptPurchaseQuoteChargeFrom": ".transcript_purchase_quote_charge_from", - "TranscriptPurchaseQuoteChargeUnit": ".transcript_purchase_quote_charge_unit", - "TranscriptPurchaseQuoteUpgrade": ".transcript_purchase_quote_upgrade", "TranscriptQuote": ".transcript_quote", "TranscriptRequestListResponse": ".transcript_request_list_response", "TranscriptRequestListResponseRequestsItem": ".transcript_request_list_response_requests_item", @@ -661,6 +661,12 @@ def __dir__(): "OpenApiDocumentInfo", "OpenApiDocumentInfoContact", "OpenApiDocumentServersItem", + "PremiumQuote", + "PremiumQuoteBillingScope", + "PremiumQuoteCharge", + "PremiumQuoteChargeFrom", + "PremiumQuoteChargeUnit", + "PremiumQuoteUpgrade", "PublicationWindow", "Recommendation", "RecommendationClass", @@ -702,12 +708,6 @@ def __dir__(): "TranscriptJobStatus", "TranscriptPending", "TranscriptPendingQuality", - "TranscriptPurchaseQuote", - "TranscriptPurchaseQuoteBillingScope", - "TranscriptPurchaseQuoteCharge", - "TranscriptPurchaseQuoteChargeFrom", - "TranscriptPurchaseQuoteChargeUnit", - "TranscriptPurchaseQuoteUpgrade", "TranscriptQuote", "TranscriptRequestListResponse", "TranscriptRequestListResponseRequestsItem", diff --git a/src/arcmira/types/alert.py b/src/arcmira/types/alert.py index 0509201..b7cca8d 100644 --- a/src/arcmira/types/alert.py +++ b/src/arcmira/types/alert.py @@ -10,6 +10,10 @@ class Alert(UniversalBaseModel): + """ + One delivery of an alert. Each alert uses 25 credits once, however many channels and recipients deliver it. + """ + id: str = pydantic.Field() """ Alert delivery id. @@ -27,12 +31,12 @@ class Alert(UniversalBaseModel): entity_id: typing.Optional[str] = pydantic.Field(default=None) """ - Public id ("ent_{n}") of the entity that triggered the alert, when recorded. Null on older rows that were written before entity_id was stored on alert_delivery. Resolve the entity through mention_id or the embedded tracker when this is null. + Public id ("ent_{n}") of the entity that triggered the alert, when recorded. Null on older alerts recorded before entity_id was stored. Resolve the entity through mention_id or the embedded tracker when this is null. """ mention_id: typing.Optional[str] = pydantic.Field(default=None) """ - Public id ("men_{n}") of the mention/appearance row that triggered the alert. Joins directly against mention rows (e.g. /v1/mentions). Null when not appearance-scoped. + Public id ("men_{n}") of the mention or appearance that triggered the alert. Matches the id on /v1/mentions results. Null when not appearance-scoped. """ video_id: typing.Optional[str] = pydantic.Field(default=None) @@ -47,7 +51,7 @@ class Alert(UniversalBaseModel): evidence_kind: typing.Optional[AlertEvidenceKind] = pydantic.Field(default=None) """ - Which evidence layer was sent. Null on older rows. + Which evidence layer was sent. Null on older alerts. """ channel: str = pydantic.Field() @@ -82,12 +86,12 @@ class Alert(UniversalBaseModel): created_at: str = pydantic.Field() """ - When the alert row was created. + When the alert was created. """ tracker: AlertTracker = pydantic.Field() """ - The tracker the alert belongs to. Fields are null when the tracker row was deleted. + The tracker the alert belongs to. Fields are null when the tracker was deleted. """ monitor: typing.Optional[AlertMonitor] = pydantic.Field(default=None) diff --git a/src/arcmira/types/alert_tracker.py b/src/arcmira/types/alert_tracker.py index 777f6ac..246e9ee 100644 --- a/src/arcmira/types/alert_tracker.py +++ b/src/arcmira/types/alert_tracker.py @@ -8,7 +8,7 @@ class AlertTracker(UniversalBaseModel): """ - The tracker the alert belongs to. Fields are null when the tracker row was deleted. + The tracker the alert belongs to. Fields are null when the tracker was deleted. """ id: typing.Optional[str] = pydantic.Field(default=None) diff --git a/src/arcmira/types/bad_ranking_change.py b/src/arcmira/types/bad_ranking_change.py index 6befc87..3bf6da3 100644 --- a/src/arcmira/types/bad_ranking_change.py +++ b/src/arcmira/types/bad_ranking_change.py @@ -8,17 +8,17 @@ class BadRankingChange(UniversalBaseModel): """ - For issue_type bad_ranking: the expected and observed positions of the row. + For issue_type bad_ranking: the expected and observed positions of the result. """ expected_rank: typing.Optional[int] = pydantic.Field(default=None) """ - Where the row should have ranked (1-based). + Where the result should have ranked (1-based). """ observed_rank: typing.Optional[int] = pydantic.Field(default=None) """ - Where the row actually ranked (1-based). Most useful on search feedback. + Where the result actually ranked (1-based). Most useful on search feedback. """ if IS_PYDANTIC_V2: diff --git a/src/arcmira/types/channel_sponsor.py b/src/arcmira/types/channel_sponsor.py index 99af5fa..a04df9d 100644 --- a/src/arcmira/types/channel_sponsor.py +++ b/src/arcmira/types/channel_sponsor.py @@ -12,7 +12,7 @@ class ChannelSponsor(UniversalBaseModel): entity: EntityRef ad_reads: int = pydantic.Field() """ - Number of ad_read recommendation rows for this sponsor on the channel. + Number of ad_read recommendations for this sponsor on the channel. """ videos: int = pydantic.Field() diff --git a/src/arcmira/types/delivery_issue_change.py b/src/arcmira/types/delivery_issue_change.py index 47a84bf..563c001 100644 --- a/src/arcmira/types/delivery_issue_change.py +++ b/src/arcmira/types/delivery_issue_change.py @@ -9,7 +9,7 @@ class DeliveryIssueChange(UniversalBaseModel): """ - For issue_type delivery_issue: targets the delivery row (the correction id) and names the channel that was wrong or never received. + For issue_type delivery_issue: targets the alert delivery (the correction id) and names the channel that was wrong or never received. """ channel: DeliveryIssueChangeChannel = pydantic.Field() diff --git a/src/arcmira/types/entity.py b/src/arcmira/types/entity.py index f6f0afb..01c4345 100644 --- a/src/arcmira/types/entity.py +++ b/src/arcmira/types/entity.py @@ -24,7 +24,7 @@ class Entity(UniversalBaseModel): type: str = pydantic.Field() """ - 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). + Entity type. Values: person (an individual), organization (a company or institution; legacy entities 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: typing.Optional[str] = pydantic.Field(default=None) @@ -49,7 +49,7 @@ class Entity(UniversalBaseModel): appearance_count: typing.Optional[int] = pydantic.Field(default=None) """ - Number of indexed appearance/mention rows for this entity. 0 when never counted. + Number of indexed appearances and mentions of this entity. 0 when never counted. """ owner_entity_id: typing.Optional[str] = pydantic.Field(default=None) diff --git a/src/arcmira/types/entity_detail_recommendations_summary.py b/src/arcmira/types/entity_detail_recommendations_summary.py index e975a88..7393e9c 100644 --- a/src/arcmira/types/entity_detail_recommendations_summary.py +++ b/src/arcmira/types/entity_detail_recommendations_summary.py @@ -13,12 +13,12 @@ class EntityDetailRecommendationsSummary(UniversalBaseModel): total_ad_reads: int = pydantic.Field() """ - Total ad_read rows across all channels. 0 when none. + Total ad_read recommendations across all channels. 0 when none. """ total_endorsements: int = pydantic.Field() """ - Total endorsement rows across all channels. 0 when none. + Total endorsement recommendations across all channels. 0 when none. """ unique_shows: int = pydantic.Field() diff --git a/src/arcmira/types/entity_ref.py b/src/arcmira/types/entity_ref.py index dedce5c..150c7c5 100644 --- a/src/arcmira/types/entity_ref.py +++ b/src/arcmira/types/entity_ref.py @@ -19,7 +19,7 @@ class EntityRef(UniversalBaseModel): type: str = pydantic.Field() """ - 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). + Entity type. Values: person (an individual), organization (a company or institution; legacy entities 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: typing.Optional[str] = pydantic.Field(default=None) diff --git a/src/arcmira/types/entity_resolve_response.py b/src/arcmira/types/entity_resolve_response.py index a9a352f..ce7bd88 100644 --- a/src/arcmira/types/entity_resolve_response.py +++ b/src/arcmira/types/entity_resolve_response.py @@ -23,19 +23,19 @@ class EntityResolveResponse(UniversalBaseModel): confidence: EntityResolveResponseConfidence = pydantic.Field() """ - 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. + exact: one entity is named q (or the handle, id or alias), and no better-known person carries the name. single_fuzzy: the only entity returned, not an exact name. ambiguous: several exact matches, or an exact match next to a better-known person sharing the name (Jordan the brand vs Michael Jordan). fuzzy: only loose matches. none: no match. """ best: typing.Optional[ResolveCandidate] = None suggested: typing.Optional[ResolveSuggestion] = None ask: typing.Optional[EntityResolveResponseAsk] = pydantic.Field(default=None) """ - 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. + Set when best and suggested are both null and several entities fit: show the options to the user, or check every option id against the data and answer per entity. """ candidates: typing.List[typing.Optional[ResolveCandidate]] = pydantic.Field() """ - Rows considered: exact names first, then initials, whole-word, spelling and substring matches, each by appearance count. + Entities considered: exact names first, then initials, whole-word, spelling and substring matches, each by appearance count. """ note: str = pydantic.Field() diff --git a/src/arcmira/types/entity_resolve_response_ask.py b/src/arcmira/types/entity_resolve_response_ask.py index 6ac9834..1b307b4 100644 --- a/src/arcmira/types/entity_resolve_response_ask.py +++ b/src/arcmira/types/entity_resolve_response_ask.py @@ -9,7 +9,7 @@ class EntityResolveResponseAsk(UniversalBaseModel): """ - 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. + Set when best and suggested are both null and several entities fit: show the options to the user, or check every option id against the data and answer per entity. """ question: str diff --git a/src/arcmira/types/feedback_readback_correction.py b/src/arcmira/types/feedback_readback_correction.py index 12389c6..2861a45 100644 --- a/src/arcmira/types/feedback_readback_correction.py +++ b/src/arcmira/types/feedback_readback_correction.py @@ -50,7 +50,7 @@ class FeedbackReadbackCorrection(UniversalBaseModel): created_at: typing.Optional[str] = pydantic.Field(default=None) """ - When the correction row was created. + When the correction was created. """ if IS_PYDANTIC_V2: diff --git a/src/arcmira/types/feedback_readback_response.py b/src/arcmira/types/feedback_readback_response.py index 62de539..d104af5 100644 --- a/src/arcmira/types/feedback_readback_response.py +++ b/src/arcmira/types/feedback_readback_response.py @@ -41,7 +41,7 @@ class FeedbackReadbackResponse(UniversalBaseModel): corrections: typing.List[FeedbackReadbackCorrection] = pydantic.Field() """ - Per-correction rows with their individual review statuses, in submission order. + The corrections, each with its own review status, in submission order. """ if IS_PYDANTIC_V2: diff --git a/src/arcmira/types/me_response.py b/src/arcmira/types/me_response.py index 6b829be..c0677c2 100644 --- a/src/arcmira/types/me_response.py +++ b/src/arcmira/types/me_response.py @@ -37,7 +37,7 @@ class MeResponse(UniversalBaseModel): period_resets_at: typing.Optional[str] = pydantic.Field(default=None) """ - ISO 8601 time the monthly row pool resets: 00:00 UTC on the first of next month. Null on the free plan, whose rows are a lifetime pool. + ISO 8601 time the plan credits reset: 00:00 UTC on the first of next month. Null on the free plan, whose 1,000 credits a month reset on usage.credits.plan.resets_at. """ tier: str = pydantic.Field() diff --git a/src/arcmira/types/me_response_usage.py b/src/arcmira/types/me_response_usage.py index 5817d44..5af0757 100644 --- a/src/arcmira/types/me_response_usage.py +++ b/src/arcmira/types/me_response_usage.py @@ -10,17 +10,17 @@ class MeResponseUsage(UniversalBaseModel): rows_used: int = pydantic.Field() """ - Premium rows consumed this period. + Plan credits used this month, in rows: usage.credits.plan.used divided by 4, rounded up. A row is 4 credits. """ rows_remaining: int = pydantic.Field() """ - Premium rows left this period. + Credits left from the plan, grants and top-ups, on-demand excluded, in rows: divided by 4, rounded up. A row is 4 credits. """ monthly_rows: int = pydantic.Field() """ - Total premium rows included per period. + The plan credits a month, in rows: usage.credits.plan.credits divided by 4 when the plan has a limit. A row is 4 credits. """ current_spend_cents: int = pydantic.Field() @@ -30,7 +30,7 @@ class MeResponseUsage(UniversalBaseModel): credits: typing.Optional[MeResponseUsageCredits] = pydantic.Field(default=None) """ - The month in credits (1 credit is $0.001; a row is 4 credits). Present only when the credits ledger decides access. + The month in credits, the primary measure of usage. Every read uses credits from the plan, then the on-demand budget. An included plan credit is valued at $0.001; on-demand usage costs $0.002 a credit. A row is 4 credits. Present only when the credits ledger decides access. """ if IS_PYDANTIC_V2: diff --git a/src/arcmira/types/me_response_usage_credits.py b/src/arcmira/types/me_response_usage_credits.py index d8dd699..053c72b 100644 --- a/src/arcmira/types/me_response_usage_credits.py +++ b/src/arcmira/types/me_response_usage_credits.py @@ -10,7 +10,7 @@ class MeResponseUsageCredits(UniversalBaseModel): """ - The month in credits (1 credit is $0.001; a row is 4 credits). Present only when the credits ledger decides access. + The month in credits, the primary measure of usage. Every read uses credits from the plan, then the on-demand budget. An included plan credit is valued at $0.001; on-demand usage costs $0.002 a credit. A row is 4 credits. Present only when the credits ledger decides access. """ available: typing.Optional[int] = pydantic.Field(default=None) diff --git a/src/arcmira/types/me_response_usage_credits_on_demand.py b/src/arcmira/types/me_response_usage_credits_on_demand.py index cea57b6..579102e 100644 --- a/src/arcmira/types/me_response_usage_credits_on_demand.py +++ b/src/arcmira/types/me_response_usage_credits_on_demand.py @@ -14,7 +14,7 @@ class MeResponseUsageCreditsOnDemand(UniversalBaseModel): cap_credits: typing.Optional[int] = pydantic.Field(default=None) """ - The on-demand cap in credits, at $0.002 a credit. Null when uncapped or off. + The on-demand budget in credits. On-demand usage costs $0.002 a credit, so this is the dollar budget divided by 0.002. Null when uncapped or off. """ used: int = pydantic.Field() diff --git a/src/arcmira/types/mention.py b/src/arcmira/types/mention.py index a5df6a8..dc0b785 100644 --- a/src/arcmira/types/mention.py +++ b/src/arcmira/types/mention.py @@ -40,7 +40,7 @@ class Mention(UniversalBaseModel): confidence: typing.Optional[float] = pydantic.Field(default=None) """ - Analyzer confidence between 0 and 1. Null for legacy rows analyzed before confidence scoring. + Analyzer confidence between 0 and 1. Null for legacy mentions analyzed before confidence scoring. """ sentiment_score: typing.Optional[float] = pydantic.Field(default=None) diff --git a/src/arcmira/types/mention_list_response.py b/src/arcmira/types/mention_list_response.py index d3ee6fc..7d0a027 100644 --- a/src/arcmira/types/mention_list_response.py +++ b/src/arcmira/types/mention_list_response.py @@ -18,7 +18,7 @@ class MentionListResponse(UniversalBaseModel): has_more: bool = pydantic.Field() """ - True when more rows exist past this page. + True when more results exist past this page. """ next_cursor: typing.Optional[str] = pydantic.Field(default=None) diff --git a/src/arcmira/types/missed_alert_change.py b/src/arcmira/types/missed_alert_change.py index c270e6d..70056e0 100644 --- a/src/arcmira/types/missed_alert_change.py +++ b/src/arcmira/types/missed_alert_change.py @@ -8,7 +8,7 @@ class MissedAlertChange(UniversalBaseModel): """ - For issue_type missed_alert: an expectation with no alert row to target. Omit the correction id and describe where the alert should have fired. + For issue_type missed_alert: an expectation with no alert to target. Omit the correction id and describe where the alert should have fired. """ source_url: str = pydantic.Field() diff --git a/src/arcmira/types/named_entity_ref.py b/src/arcmira/types/named_entity_ref.py index 81a946c..cb47280 100644 --- a/src/arcmira/types/named_entity_ref.py +++ b/src/arcmira/types/named_entity_ref.py @@ -19,7 +19,7 @@ class NamedEntityRef(UniversalBaseModel): type: typing.Optional[str] = pydantic.Field(default=None) """ - 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). + Entity type. Values: person (an individual), organization (a company or institution; legacy entities 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). """ if IS_PYDANTIC_V2: diff --git a/src/arcmira/types/transcript_purchase_quote.py b/src/arcmira/types/premium_quote.py similarity index 57% rename from src/arcmira/types/transcript_purchase_quote.py rename to src/arcmira/types/premium_quote.py index 83e63cc..4e12faf 100644 --- a/src/arcmira/types/transcript_purchase_quote.py +++ b/src/arcmira/types/premium_quote.py @@ -4,28 +4,36 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .transcript_purchase_quote_billing_scope import TranscriptPurchaseQuoteBillingScope -from .transcript_purchase_quote_charge import TranscriptPurchaseQuoteCharge -from .transcript_purchase_quote_upgrade import TranscriptPurchaseQuoteUpgrade +from .premium_quote_billing_scope import PremiumQuoteBillingScope +from .premium_quote_charge import PremiumQuoteCharge +from .premium_quote_upgrade import PremiumQuoteUpgrade from .transcript_quote import TranscriptQuote -class TranscriptPurchaseQuote(UniversalBaseModel): +class PremiumQuote(UniversalBaseModel): video_id: str duration_seconds: float - billing_scope: TranscriptPurchaseQuoteBillingScope + billing_scope: PremiumQuoteBillingScope owned: bool eligible: bool - upgrade: typing.Optional[TranscriptPurchaseQuoteUpgrade] = pydantic.Field(default=None) + upgrade: typing.Optional[PremiumQuoteUpgrade] = pydantic.Field(default=None) """ Present when eligible is false. Names the plan that includes Premium transcripts, as a button label and an absolute link to its checkout. """ quote: TranscriptQuote - charge: TranscriptPurchaseQuoteCharge - credits_per_row: float + charge: PremiumQuoteCharge + credits_per_row: float = pydantic.Field() + """ + Credits in a row: 4. + """ + max_on_demand_cents: float - on_demand_cents_per_unit: float + on_demand_cents_per_unit: float = pydantic.Field() + """ + What one unit of charge.unit costs as on-demand usage, in US cents: 0.2 a credit ($0.002). + """ + refund_policy: str if IS_PYDANTIC_V2: diff --git a/src/arcmira/types/premium_quote_billing_scope.py b/src/arcmira/types/premium_quote_billing_scope.py new file mode 100644 index 0000000..d171520 --- /dev/null +++ b/src/arcmira/types/premium_quote_billing_scope.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +PremiumQuoteBillingScope = typing.Union[typing.Literal["full_video"], typing.Any] diff --git a/src/arcmira/types/transcript_purchase_quote_charge.py b/src/arcmira/types/premium_quote_charge.py similarity index 72% rename from src/arcmira/types/transcript_purchase_quote_charge.py rename to src/arcmira/types/premium_quote_charge.py index 1738421..3b21376 100644 --- a/src/arcmira/types/transcript_purchase_quote_charge.py +++ b/src/arcmira/types/premium_quote_charge.py @@ -6,15 +6,15 @@ import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from ..core.serialization import FieldMetadata -from .transcript_purchase_quote_charge_from import TranscriptPurchaseQuoteChargeFrom -from .transcript_purchase_quote_charge_unit import TranscriptPurchaseQuoteChargeUnit +from .premium_quote_charge_from import PremiumQuoteChargeFrom +from .premium_quote_charge_unit import PremiumQuoteChargeUnit -class TranscriptPurchaseQuoteCharge(UniversalBaseModel): - unit: TranscriptPurchaseQuoteChargeUnit +class PremiumQuoteCharge(UniversalBaseModel): + unit: PremiumQuoteChargeUnit amount: float from_: typing_extensions.Annotated[ - TranscriptPurchaseQuoteChargeFrom, + PremiumQuoteChargeFrom, FieldMetadata(alias="from"), pydantic.Field(alias="from", description="Where the charge would come from at the current balance."), ] diff --git a/src/arcmira/types/premium_quote_charge_from.py b/src/arcmira/types/premium_quote_charge_from.py new file mode 100644 index 0000000..9907a8d --- /dev/null +++ b/src/arcmira/types/premium_quote_charge_from.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +PremiumQuoteChargeFrom = typing.Union[typing.Literal["included", "on_demand", "mixed"], typing.Any] diff --git a/src/arcmira/types/premium_quote_charge_unit.py b/src/arcmira/types/premium_quote_charge_unit.py new file mode 100644 index 0000000..7720fcf --- /dev/null +++ b/src/arcmira/types/premium_quote_charge_unit.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +PremiumQuoteChargeUnit = typing.Union[typing.Literal["rows", "credits"], typing.Any] diff --git a/src/arcmira/types/transcript_purchase_quote_upgrade.py b/src/arcmira/types/premium_quote_upgrade.py similarity index 91% rename from src/arcmira/types/transcript_purchase_quote_upgrade.py rename to src/arcmira/types/premium_quote_upgrade.py index c6f63ae..8f2ac5f 100644 --- a/src/arcmira/types/transcript_purchase_quote_upgrade.py +++ b/src/arcmira/types/premium_quote_upgrade.py @@ -6,7 +6,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -class TranscriptPurchaseQuoteUpgrade(UniversalBaseModel): +class PremiumQuoteUpgrade(UniversalBaseModel): """ Present when eligible is false. Names the plan that includes Premium transcripts, as a button label and an absolute link to its checkout. """ diff --git a/src/arcmira/types/recommendation.py b/src/arcmira/types/recommendation.py index 4f86de9..94aa5db 100644 --- a/src/arcmira/types/recommendation.py +++ b/src/arcmira/types/recommendation.py @@ -63,12 +63,12 @@ class Recommendation(UniversalBaseModel): sentiment_score: typing.Optional[float] = pydantic.Field(default=None) """ - Raw sentiment score between -1 and 1, same semantics as sentiment_score on mention rows. Null when not computed. + Raw sentiment score between -1 and 1, same semantics as sentiment_score on mentions. Null when not computed. """ confidence: float = pydantic.Field() """ - Classifier confidence between 0 and 1. Rows below the min_confidence filter (default 0.7) are excluded from list responses. + Classifier confidence between 0 and 1. Recommendations below the min_confidence filter (default 0.7) are excluded from list responses. """ speaker_role: str = pydantic.Field() @@ -78,7 +78,7 @@ class Recommendation(UniversalBaseModel): conflict_status: typing.Optional[str] = pydantic.Field(default=None) """ - Set when community feedback disputes the classification (e.g. "disputed"). Null when undisputed. Disputed rows are excluded unless include_disputed=true. + Set when community feedback disputes the classification (e.g. "disputed"). Null when undisputed. Disputed recommendations are excluded unless include_disputed=true. """ resolution: typing.Optional[str] = pydantic.Field(default=None) diff --git a/src/arcmira/types/recommendation_list_response.py b/src/arcmira/types/recommendation_list_response.py index c5b72c3..c300282 100644 --- a/src/arcmira/types/recommendation_list_response.py +++ b/src/arcmira/types/recommendation_list_response.py @@ -17,7 +17,7 @@ class RecommendationListResponse(UniversalBaseModel): has_more: bool = pydantic.Field() """ - True when more rows exist past this page. + True when more results exist past this page. """ next_cursor: typing.Optional[str] = pydantic.Field(default=None) diff --git a/src/arcmira/types/resolve_candidate.py b/src/arcmira/types/resolve_candidate.py index 0aba140..aadf7a0 100644 --- a/src/arcmira/types/resolve_candidate.py +++ b/src/arcmira/types/resolve_candidate.py @@ -9,7 +9,7 @@ class ResolveCandidate(UniversalBaseModel): """ - The one row q means. Set on exact and single_fuzzy only. Name it in the answer. + The one entity q means. Set on exact and single_fuzzy only. Name it in the answer. """ id: str = pydantic.Field() @@ -29,12 +29,12 @@ class ResolveCandidate(UniversalBaseModel): type: str = pydantic.Field() """ - 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). + Entity type. Values: person (an individual), organization (a company or institution; legacy entities 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: typing.Optional[int] = pydantic.Field(default=None) """ - Number of indexed appearance/mention rows. Results are ordered by this, descending. + Number of indexed appearances and mentions. Results are ordered by this, descending. """ youtube_channel_id: typing.Optional[str] = pydantic.Field(default=None) @@ -44,7 +44,7 @@ class ResolveCandidate(UniversalBaseModel): description: typing.Optional[str] = pydantic.Field(default=None) """ - 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. + One catalog sentence that tells entities with the same name apart, for example "Common gender-neutral given name or nickname". Null when the catalog has none. """ page: typing.Optional[str] = pydantic.Field(default=None) @@ -54,7 +54,7 @@ class ResolveCandidate(UniversalBaseModel): match: ResolveCandidateMatch = pydantic.Field() """ - 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. + How the entity'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. """ if IS_PYDANTIC_V2: diff --git a/src/arcmira/types/resolve_suggestion.py b/src/arcmira/types/resolve_suggestion.py index e185c08..b99d831 100644 --- a/src/arcmira/types/resolve_suggestion.py +++ b/src/arcmira/types/resolve_suggestion.py @@ -10,7 +10,7 @@ class ResolveSuggestion(UniversalBaseModel): """ - Set when best is null but one row stands out, with the reason and evidence. Use it and tell the user you assumed it. + Set when best is null but one entity stands out, with the reason and evidence. Use it and tell the user you assumed it. """ id: str = pydantic.Field() @@ -30,12 +30,12 @@ class ResolveSuggestion(UniversalBaseModel): type: str = pydantic.Field() """ - 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). + Entity type. Values: person (an individual), organization (a company or institution; legacy entities 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: typing.Optional[int] = pydantic.Field(default=None) """ - Number of indexed appearance/mention rows. Results are ordered by this, descending. + Number of indexed appearances and mentions. Results are ordered by this, descending. """ youtube_channel_id: typing.Optional[str] = pydantic.Field(default=None) @@ -45,7 +45,7 @@ class ResolveSuggestion(UniversalBaseModel): description: typing.Optional[str] = pydantic.Field(default=None) """ - 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. + One catalog sentence that tells entities with the same name apart, for example "Common gender-neutral given name or nickname". Null when the catalog has none. """ page: typing.Optional[str] = pydantic.Field(default=None) @@ -55,12 +55,12 @@ class ResolveSuggestion(UniversalBaseModel): match: ResolveSuggestionMatch = pydantic.Field() """ - 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. + How the entity'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. """ reason: ResolveSuggestionReason = pydantic.Field() """ - 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. + Why this entity stands out: dominant (10x the appearances of the next match), only_word_match, context (the context parameter points at it), acronym, spelling. """ evidence: str = pydantic.Field() diff --git a/src/arcmira/types/signup_verified_response.py b/src/arcmira/types/signup_verified_response.py index 7601771..2c31bcb 100644 --- a/src/arcmira/types/signup_verified_response.py +++ b/src/arcmira/types/signup_verified_response.py @@ -34,7 +34,7 @@ class SignupVerifiedResponse(UniversalBaseModel): rows_allotted: int = pydantic.Field() """ - The pool this key draws on: a free account's lifetime credits, a paid plan's monthly rows. + On a paid plan, its monthly allowance in rows; a row is 4 credits. On the free plan, the account's row allotment from before credits (1,000 for a new account). The free plan uses 1,000 credits a month, read from usage.credits on GET /v1/me. """ next: str = pydantic.Field() diff --git a/src/arcmira/types/transcript_job.py b/src/arcmira/types/transcript_job.py index 5a76d6d..8d89d66 100644 --- a/src/arcmira/types/transcript_job.py +++ b/src/arcmira/types/transcript_job.py @@ -32,7 +32,7 @@ class TranscriptJob(UniversalBaseModel): status: TranscriptJobStatus = pydantic.Field() """ - Request status. Values: queued (accepted; audio download not started), downloading (fetching the video audio), transcribing (premium speech-to-text is running), analyzing (entity/commercial analysis is running), complete (premium transcript is servable via GET /v1/transcripts/{video_id}), failed (rejected intent, or a legacy request needing accounting review), refund_pending (refund transaction must still complete), refunded (terminal failure; the charged rows were returned and the unlock this request granted was revoked). + Request status. Values: queued (accepted; audio download not started), downloading (fetching the video audio), transcribing (premium speech-to-text is running), analyzing (entity/commercial analysis is running), complete (premium transcript is servable via GET /v1/transcripts/{video_id}), failed (rejected intent, or a legacy request needing accounting review), refund_pending (refund transaction must still complete), refunded (terminal failure; the charge was returned and the unlock this request granted was revoked). """ stage: typing.Optional[TranscriptJobStage] = pydantic.Field(default=None) diff --git a/src/arcmira/types/transcript_purchase_quote_billing_scope.py b/src/arcmira/types/transcript_purchase_quote_billing_scope.py deleted file mode 100644 index 9185db7..0000000 --- a/src/arcmira/types/transcript_purchase_quote_billing_scope.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -TranscriptPurchaseQuoteBillingScope = typing.Union[typing.Literal["full_video"], typing.Any] diff --git a/src/arcmira/types/transcript_purchase_quote_charge_from.py b/src/arcmira/types/transcript_purchase_quote_charge_from.py deleted file mode 100644 index edd9bbd..0000000 --- a/src/arcmira/types/transcript_purchase_quote_charge_from.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -TranscriptPurchaseQuoteChargeFrom = typing.Union[typing.Literal["included", "on_demand", "mixed"], typing.Any] diff --git a/src/arcmira/types/transcript_purchase_quote_charge_unit.py b/src/arcmira/types/transcript_purchase_quote_charge_unit.py deleted file mode 100644 index f24a10e..0000000 --- a/src/arcmira/types/transcript_purchase_quote_charge_unit.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -TranscriptPurchaseQuoteChargeUnit = typing.Union[typing.Literal["rows", "credits"], typing.Any] diff --git a/src/arcmira/types/transcript_quote.py b/src/arcmira/types/transcript_quote.py index 622bb4e..f7d91b6 100644 --- a/src/arcmira/types/transcript_quote.py +++ b/src/arcmira/types/transcript_quote.py @@ -14,7 +14,7 @@ class TranscriptQuote(UniversalBaseModel): rows: int = pydantic.Field() """ - Rows the whole video uses, 75 rows per 15-minute block. + Rows the whole video uses, 75 rows per 15-minute block. A row is 4 credits, so Premium uses 300 credits per block. """ if IS_PYDANTIC_V2: diff --git a/src/arcmira/types/transcript_response.py b/src/arcmira/types/transcript_response.py index dcc7b59..d47880e 100644 --- a/src/arcmira/types/transcript_response.py +++ b/src/arcmira/types/transcript_response.py @@ -65,7 +65,7 @@ class TranscriptResponse(UniversalBaseModel): rows_billed: int = pydantic.Field() """ - Caption retrieval rows charged by this call. 0 on a repeat of the same video, quality, language, and range inside the 7 day dedupe window. Premium responses report 0 here even when the read was charged for the whole video; this field does not report Premium charges. + Rows this captions read used: 1 row per started 15 minutes, and a row is 4 credits. 0 on a repeat of the same video, quality, language, and range inside the 7 day dedupe window. Premium reads report 0, because the Premium transcript job carries their charge. """ as_of: typing.Optional[str] = pydantic.Field(default=None) diff --git a/src/arcmira/types/transcript_video.py b/src/arcmira/types/transcript_video.py index 05fe0a2..3cce9ed 100644 --- a/src/arcmira/types/transcript_video.py +++ b/src/arcmira/types/transcript_video.py @@ -30,7 +30,7 @@ class TranscriptVideo(UniversalBaseModel): duration_seconds: typing.Optional[float] = pydantic.Field(default=None) """ - Video length in seconds. Null when unknown, which also means the row estimate was unknown. + Video length in seconds. Null when unknown, which also means the credit estimate was unknown. """ watch_url: str = pydantic.Field() diff --git a/src/arcmira/types/wrong_classification_change.py b/src/arcmira/types/wrong_classification_change.py index d4c7aa0..9bef2cb 100644 --- a/src/arcmira/types/wrong_classification_change.py +++ b/src/arcmira/types/wrong_classification_change.py @@ -11,7 +11,7 @@ class WrongClassificationChange(UniversalBaseModel): """ - For issue_type wrong_classification: the commercial class the row should carry. + For issue_type wrong_classification: the commercial class the result should carry. """ class_: typing_extensions.Annotated[ diff --git a/src/arcmira/types/wrong_entity_change.py b/src/arcmira/types/wrong_entity_change.py index b403b78..3df1aaa 100644 --- a/src/arcmira/types/wrong_entity_change.py +++ b/src/arcmira/types/wrong_entity_change.py @@ -8,12 +8,12 @@ class WrongEntityChange(UniversalBaseModel): """ - For issue_type wrong_entity (and wrong_person): the entity the row should have been attributed to. + For issue_type wrong_entity (and wrong_person): the entity the result should have been attributed to. """ entity_id: typing.Optional[str] = pydantic.Field(default=None) """ - Public id ("ent_{n}") of the entity the row should point at. + Public id ("ent_{n}") of the entity the result should point at. """ entity_name: typing.Optional[str] = pydantic.Field(default=None)