openapi: 3.2.0 info: title: Plainrouter Action Read API version: 0.5.0 description: 'Operations tagged ActionReadApi across 2 of this provider''s published API definitions: dev-plainrouter-openapi.json, plainrouter-openapi.json. Each path carries the servers of the definition it was published in.' servers: - url: https://plainrouter.com/api/v1 description: Production security: - workspaceSecret: [] tags: - name: ActionReadApi paths: /agent/workspaces/{workspace}/actions: get: operationId: actions.api.index description: Read persisted Actions data for an account available to this workspace key. An unbound key selects account_id; a bound key stays limited to its own account. summary: List actions tags: - ActionReadApi parameters: - name: workspace in: path required: true description: The workspace ID schema: type: integer - name: status in: query schema: type: string enum: - pending - approved_without_execution - rejected - executing - executed_pending_verification - compensating - measuring - verified - failed - execution_uncertain - rolled_back - blocked - name: page in: query schema: type: integer minimum: 1 - name: account_id in: query description: Optional positive account ID. A bound key may name only its own account; any other value returns 422. An unbound key may name only an active account with an active connection in its workspace, and must name one when the workspace has more than one. schema: type: integer minimum: 1 responses: '200': description: Authorized Actions resource. content: application/json: schema: $ref: '#/components/schemas/ActionListRead' '401': description: Missing, invalid, or expired workspace key. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '403': description: The key lacks the read-actions grant. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: Workspace, account, or Actions resource not found. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Request validation failed. content: application/json: schema: $ref: '#/components/schemas/ValidationError' security: - workspaceActionKey: [] servers: - url: https://plainrouter.com/api/v1 description: Production /agent/workspaces/{workspace}/actions/policy: get: operationId: actions.api.policy description: Read persisted Actions data for an account available to this workspace key. An unbound key selects account_id; a bound key stays limited to its own account. summary: Get action policy tags: - ActionReadApi parameters: - name: workspace in: path required: true description: The workspace ID schema: type: integer - name: account_id in: query description: Optional positive account ID. A bound key may name only its own account; any other value returns 422. An unbound key may name only an active account with an active connection in its workspace, and must name one when the workspace has more than one. schema: type: integer minimum: 1 responses: '200': description: Authorized Actions resource. content: application/json: schema: $ref: '#/components/schemas/ActionPolicyRead' '401': description: Missing, invalid, or expired workspace key. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '403': description: The key lacks the read-actions grant. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: Workspace, account, or Actions resource not found. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Request validation failed. content: application/json: schema: $ref: '#/components/schemas/ValidationError' security: - workspaceActionKey: [] servers: - url: https://plainrouter.com/api/v1 description: Production /agent/workspaces/{workspace}/actions/{action}/decision-receipt: get: operationId: actions.api.decision-receipt description: Read persisted Actions data for an account available to this workspace key. An unbound key selects account_id; a bound key stays limited to its own account. summary: Get decision receipt tags: - ActionReadApi parameters: - name: workspace in: path required: true description: The workspace ID schema: type: integer - name: action in: path required: true schema: type: string - name: account_id in: query description: Optional positive account ID. A bound key may name only its own account; any other value returns 422. An unbound key may name only an active account with an active connection in its workspace, and must name one when the workspace has more than one. schema: type: integer minimum: 1 responses: '200': description: Authorized Actions resource. content: application/json: schema: $ref: '#/components/schemas/ActionDecisionReceiptRead' '401': description: Missing, invalid, or expired workspace key. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '403': description: The key lacks the read-actions grant. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: Workspace, account, or Actions resource not found. A visible action without an execution receipt returns error.code receipt_not_available and error.message "No execution receipt exists for this action because it was not executed." content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Request validation failed. content: application/json: schema: $ref: '#/components/schemas/ValidationError' security: - workspaceActionKey: [] servers: - url: https://plainrouter.com/api/v1 description: Production /agent/workspaces/{workspace}/actions/{action}: get: operationId: actions.api.show description: Read persisted Actions data for an account available to this workspace key. An unbound key selects account_id; a bound key stays limited to its own account. summary: Get action tags: - ActionReadApi parameters: - name: workspace in: path required: true description: The workspace ID schema: type: integer - name: action in: path required: true schema: type: string - name: account_id in: query description: Optional positive account ID. A bound key may name only its own account; any other value returns 422. An unbound key may name only an active account with an active connection in its workspace, and must name one when the workspace has more than one. schema: type: integer minimum: 1 responses: '200': description: Authorized Actions resource. content: application/json: schema: $ref: '#/components/schemas/ActionDetailRead' '401': description: Missing, invalid, or expired workspace key. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '403': description: The key lacks the read-actions grant. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: Workspace, account, or Actions resource not found. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Request validation failed. content: application/json: schema: $ref: '#/components/schemas/ValidationError' security: - workspaceActionKey: [] servers: - url: https://plainrouter.com/api/v1 description: Production /agent/workspaces/{workspace}/action-batches/{actionBatch}: get: operationId: actions.api.batch description: Read persisted Actions data for an account available to this workspace key. An unbound key selects account_id; a bound key stays limited to its own account. summary: Get action batch tags: - ActionReadApi parameters: - name: workspace in: path required: true description: The workspace ID schema: type: integer - name: actionBatch in: path required: true schema: type: string - name: account_id in: query description: Optional positive account ID. A bound key may name only its own account; any other value returns 422. An unbound key may name only an active account with an active connection in its workspace, and must name one when the workspace has more than one. schema: type: integer minimum: 1 responses: '200': description: Authorized Actions resource. content: application/json: schema: $ref: '#/components/schemas/ActionBatchRead' '401': description: Missing, invalid, or expired workspace key. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '403': description: The key lacks the read-actions grant. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: Workspace, account, or Actions resource not found. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Request validation failed. content: application/json: schema: $ref: '#/components/schemas/ValidationError' security: - workspaceActionKey: [] servers: - url: https://plainrouter.com/api/v1 description: Production components: schemas: ActionBatchRead: type: object properties: data: type: object properties: id: type: string workspace_id: type: integer platform_ad_account_id: type: integer status: type: string enum: - pending - approved - approved_without_execution - auto_approved - rejected - executing - executed_pending_verification - compensating - measuring - completed - failed - rolled_back - rollback_incomplete - blocked - halted batch_status: type: string enum: - pending - approved - approved_without_execution - auto_approved - rejected - executing - executed_pending_verification - compensating - measuring - completed - failed - rolled_back - rollback_incomplete - blocked - halted restoration_summary: type: - string - 'null' enum: - all_receipts_compensated_late - null policy_decision: type: - string - 'null' enum: - allow - require_approval - block - null policy_reasons: type: array items: type: string rationale: type: string idempotency_key: type: string actions: type: array items: $ref: '#/components/schemas/ActionReadItem' required: - id - workspace_id - platform_ad_account_id - status - batch_status - restoration_summary - policy_decision - policy_reasons - rationale - idempotency_key - actions required: - data title: ActionBatchRead ActionPolicyResult: type: object properties: id: type: string policy_id: type: string policy_version: type: integer phase: type: string enum: - proposal - approval - execution outcome: type: string enum: - allowed - approval_required - blocked reasons: type: array items: type: string reason_details: type: - array - 'null' items: type: string requested_minor: type: - integer - 'null' evaluated_at: type: string format: date-time required: - id - policy_id - policy_version - phase - outcome - reasons - reason_details - requested_minor - evaluated_at title: ActionPolicyResult ActionPolicyRead: type: object properties: data: type: object properties: id: type: - integer - 'null' workspace_id: type: integer execution_mode: type: string enum: - ask - full outcome_check_after_hours: type: integer anomaly_threshold_percent: type: string required: - id - workspace_id - execution_mode - outcome_check_after_hours - anomaly_threshold_percent required: - data title: ActionPolicyRead ValidationError: type: object properties: message: type: string errors: type: object additionalProperties: type: array items: type: string required: - message - errors title: ValidationError ActionListRead: type: object properties: data: type: array items: $ref: '#/components/schemas/ActionReadItem' meta: type: object properties: current_page: type: integer last_page: type: integer per_page: type: integer total: type: integer required: - current_page - last_page - per_page - total required: - data - meta title: ActionListRead ActionDetailRead: type: object properties: data: $ref: '#/components/schemas/ActionReadItem' required: - data title: ActionDetailRead ActionReadItem: type: object properties: id: type: string batch_id: type: string workspace_id: type: integer type: type: string enum: - increase_budget - decrease_budget - pause - resume - replace_creative - shift_spend - rollback - create_campaign - create_ad_set - create_ad - upload_asset - adjust_budget - set_status - duplicate_ad_with_creative - duplicate_adset - duplicate_ad_with_creative_v2 target_entity_type: type: string target_entity_id: type: string target_entity_name: type: - string - 'null' params: anyOf: - type: object additionalProperties: {} - type: array items: {} rationale: type: string proposer: type: object properties: type: type: string enum: - user - agent - system name: type: string description: PlainRouter for a system proposer; omitted for people and agents. required: - type evidence: description: System evidence cites either the original action and its counted outcome or the rule, revision, run and decision. anyOf: - type: object properties: original_action_id: type: string outcome: type: object description: Write-once outcome. Management comparisons use PlainRouter counted arrivals and Inventory spend. Resume compares the target after the change with the rest of the same account over those same days. Pause is not judged. Missing data never yields a verdict. Other action types retain their existing payloads. properties: status: type: string enum: - measurable - not_measurable - unavailable observed_at: type: string format: date-time reason_code: type: - string - 'null' reason: type: - string - 'null' baseline: anyOf: - type: object properties: scope: type: string enum: - target - rest_of_account days: type: array description: Three whole days in the ad account timezone; excludes the change day. items: type: string format: date currency: type: - string - 'null' timezone: type: string spend_minor: type: - string - 'null' description: Decimal spend in ISO currency minor units; null when daily mirror data is missing. counted_arrivals: type: - integer - 'null' description: Arrivals counted by PlainRouter through Signals, never provider conversions. cost_per_counted_arrival_minor: type: - string - 'null' description: Spend divided by counted arrivals, in ISO currency minor units, displayed to six decimal places. - type: array items: type: string metrics: anyOf: - type: object properties: scope: type: string enum: - target - rest_of_account days: type: array description: Three whole days in the ad account timezone; excludes the change day. items: type: string format: date currency: type: - string - 'null' timezone: type: string spend_minor: type: - string - 'null' description: Decimal spend in ISO currency minor units; null when daily mirror data is missing. counted_arrivals: type: - integer - 'null' description: Arrivals counted by PlainRouter through Signals, never provider conversions. cost_per_counted_arrival_minor: type: - string - 'null' description: Spend divided by counted arrivals, in ISO currency minor units, displayed to six decimal places. verdict: type: - string - 'null' enum: - held - lost - not_judged - null loss_threshold_percent: type: string - type: array items: type: string inverse: type: object properties: status: type: string enum: - proposed - inverse_not_proposed batch_id: type: string reason_code: type: string required: - status additionalProperties: {} required: - original_action_id - outcome - type: object properties: rule_id: type: string revision_id: type: string run_id: type: string decision_id: type: string required: - rule_id - revision_id - run_id - decision_id - type: object description: System evidence from a completed Test cites its Test, verdict and selected winner member. properties: test_id: type: string verdict_id: type: string winner_member_id: type: string required: - test_id - verdict_id - winner_member_id status: type: string enum: - pending - approved_without_execution - rejected - executing - executed_pending_verification - compensating - measuring - verified - failed - execution_uncertain - rolled_back - blocked batch_status: type: string enum: - pending - approved - approved_without_execution - auto_approved - rejected - executing - executed_pending_verification - compensating - measuring - completed - failed - rolled_back - rollback_incomplete - blocked - halted disposition: $ref: '#/components/schemas/ActionCurrentDisposition' policy_decision: type: - string - 'null' enum: - allow - require_approval - block - null policy_reasons: type: array items: type: string policy_result: anyOf: - $ref: '#/components/schemas/ActionPolicyResult' - type: 'null' policy_results: type: array items: $ref: '#/components/schemas/ActionPolicyResult' required: - id - batch_id - workspace_id - type - target_entity_type - target_entity_id - target_entity_name - params - rationale - status - batch_status - disposition - policy_decision - policy_reasons - policy_result - policy_results title: ActionReadItem ActionCurrentDisposition: type: object properties: receipt_status: type: - string - 'null' enum: - pending - attempting - reconciliation_required - committed - executed_pending_verification - measuring - verified - compensating - compensated - compensation_failed - irreversible - failed - reconciliation_exhausted - null outcome_payload: type: - object - 'null' description: Write-once outcome. Management comparisons use PlainRouter counted arrivals and Inventory spend. Resume compares the target after the change with the rest of the same account over those same days. Pause is not judged. Missing data never yields a verdict. Other action types retain their existing payloads. properties: status: type: string enum: - measurable - not_measurable - unavailable observed_at: type: string format: date-time reason_code: type: - string - 'null' reason: type: - string - 'null' baseline: anyOf: - type: object properties: scope: type: string enum: - target - rest_of_account days: type: array description: Three whole days in the ad account timezone; excludes the change day. items: type: string format: date currency: type: - string - 'null' timezone: type: string spend_minor: type: - string - 'null' description: Decimal spend in ISO currency minor units; null when daily mirror data is missing. counted_arrivals: type: - integer - 'null' description: Arrivals counted by PlainRouter through Signals, never provider conversions. cost_per_counted_arrival_minor: type: - string - 'null' description: Spend divided by counted arrivals, in ISO currency minor units, displayed to six decimal places. - type: array items: type: string metrics: anyOf: - type: object properties: scope: type: string enum: - target - rest_of_account days: type: array description: Three whole days in the ad account timezone; excludes the change day. items: type: string format: date currency: type: - string - 'null' timezone: type: string spend_minor: type: - string - 'null' description: Decimal spend in ISO currency minor units; null when daily mirror data is missing. counted_arrivals: type: - integer - 'null' description: Arrivals counted by PlainRouter through Signals, never provider conversions. cost_per_counted_arrival_minor: type: - string - 'null' description: Spend divided by counted arrivals, in ISO currency minor units, displayed to six decimal places. verdict: type: - string - 'null' enum: - held - lost - not_judged - null loss_threshold_percent: type: string - type: array items: type: string inverse: type: object properties: status: type: string enum: - proposed - inverse_not_proposed batch_id: type: string reason_code: type: string required: - status additionalProperties: {} outcome_status: type: - string - 'null' enum: - measurable - not_measurable - unavailable - null outcome_reason_code: type: - string - 'null' outcome_checked_at: type: - string - 'null' format: date-time compensation_reason_code: type: - string - 'null' recovery_disposition: type: - string - 'null' enum: - no_compensation - restored - unrestored - contradictory - irreversible - uncertain - null late_restored: type: boolean required: - receipt_status - outcome_status - outcome_reason_code - outcome_checked_at - outcome_payload - compensation_reason_code - recovery_disposition - late_restored title: ActionCurrentDisposition ErrorMessage: type: object properties: message: type: string required: - message title: ErrorMessage ActionDecisionReceiptRead: type: object properties: document: type: object additionalProperties: {} document_sha256: type: string chain_entry: type: object properties: sequence: type: integer hash: type: string required: - sequence - hash disposition: $ref: '#/components/schemas/ActionCurrentDisposition' required: - document - document_sha256 - chain_entry - disposition title: ActionDecisionReceiptRead ActionBatchRead_2: type: object properties: data: type: object description: Complete projection rows are paged within 80,000 JSON bytes, accounting for both MCP representations. Defaults are bounded. Follow next_cursor with the same scope and filters. One oversized row is explicitly refused; fields are never silently clipped. properties: id: type: string workspace_id: type: integer platform_ad_account_id: type: integer status: type: string enum: - pending - approved - approved_without_execution - auto_approved - rejected - executing - executed_pending_verification - compensating - measuring - completed - failed - rolled_back - rollback_incomplete - blocked - halted batch_status: type: string enum: - pending - approved - approved_without_execution - auto_approved - rejected - executing - executed_pending_verification - compensating - measuring - completed - failed - rolled_back - rollback_incomplete - blocked - halted restoration_summary: type: - string - 'null' enum: - all_receipts_compensated_late - null policy_decision: type: - string - 'null' enum: - allow - require_approval - block - null policy_reasons: type: array items: type: string rationale: type: string idempotency_key: type: string actions: type: array items: $ref: '#/components/schemas/ActionReadItem_2' next_cursor: type: - integer - 'null' truncated: type: boolean continuation: type: string total: type: integer required: - id - workspace_id - platform_ad_account_id - status - batch_status - restoration_summary - policy_decision - policy_reasons - rationale - idempotency_key - actions required: - data title: ActionBatchRead AgentCredentialError: type: object properties: error: type: string enum: - invalid_token - insufficient_scope error_description: type: string required: - error - error_description title: AgentCredentialError ApiRouteNotFound: type: object properties: error: type: object properties: code: type: string enum: - api_route_not_found message: type: string resolution: type: string required: - code - message - resolution request: type: object properties: method: type: string path: type: string required: - method - path resources: type: object properties: documentation: type: string openapi: type: string required: - documentation - openapi required: - error - request - resources title: ApiRouteNotFound ActionListRead_2: type: object properties: data: type: array items: $ref: '#/components/schemas/ActionReadItem_2' meta: type: object description: Complete projection rows are paged within 80,000 JSON bytes, accounting for both MCP representations. Defaults are bounded. Follow next_cursor with the same scope and filters. One oversized row is explicitly refused; fields are never silently clipped. properties: current_page: type: integer last_page: type: integer per_page: type: integer total: type: integer next_cursor: type: - integer - 'null' truncated: type: boolean continuation: type: string required: - current_page - last_page - per_page - total required: - data - meta title: ActionListRead ActionReceiptUnavailable: type: object properties: error: type: object properties: code: type: string enum: - receipt_not_available message: type: string required: - code - message required: - error title: ActionReceiptUnavailable ActionReadItem_2: type: object properties: id: type: string batch_id: type: string workspace_id: type: integer type: type: string enum: - increase_budget - decrease_budget - pause - resume - replace_creative - shift_spend - rollback - create_campaign - create_ad_set - create_ad - upload_asset - adjust_budget - set_status - duplicate_ad_with_creative - duplicate_adset - duplicate_ad_with_creative_v2 target_entity_type: type: string target_entity_id: type: string target_entity_name: type: - string - 'null' counted_evidence: type: - object - 'null' description: Frozen proposal-time target figures over completed account-local dates. Purchase values are decimal strings in the account currency; counted values in other currencies are excluded and never converted. Null means figures were not captured. Display only; never an enforcement input. properties: target: type: object properties: kind: type: string id: type: string required: - kind - id captured_at: type: string window: type: - object - 'null' properties: since: type: string until: type: string timezone: type: string days: type: integer required: - since - until - timezone currency: type: - string - 'null' currency_note: type: string meta_reported: type: object properties: inline_link_clicks: type: - integer - 'null' purchase_count: type: - integer - 'null' purchase_value: type: - string - 'null' spend: type: - string - 'null' impressions: type: - integer - 'null' required: - inline_link_clicks - purchase_count - purchase_value - spend - impressions counted: type: object properties: arrivals: type: - integer - 'null' purchase_count: type: - integer - 'null' purchase_value: type: - string - 'null' required: - arrivals - purchase_count - purchase_value coverage: type: object properties: arrivals: type: - object - 'null' properties: since: type: string until: type: string timezone: type: string days: type: integer required: - since - until - timezone purchases: type: - object - 'null' properties: since: type: string until: type: string timezone: type: string days: type: integer required: - since - until - timezone required: - arrivals - purchases required: - target - captured_at - window - currency - currency_note - meta_reported - counted - coverage params: anyOf: - type: object additionalProperties: {} - type: array items: {} rationale: type: string proposer: type: object properties: type: type: string enum: - user - agent - system name: type: string description: PlainRouter for a system proposer; omitted for people and agents. required: - type evidence: description: System evidence cites either the original action and its counted outcome or the rule, revision, run and decision. anyOf: - type: object properties: original_action_id: type: string outcome: type: object description: Write-once outcome. Management comparisons use PlainRouter counted arrivals and Inventory spend. Resume compares the target after the change with the rest of the same account over those same days. Pause is not judged. Missing data never yields a verdict. Other action types retain their existing payloads. properties: status: type: string enum: - measurable - not_measurable - unavailable observed_at: type: string format: date-time reason_code: type: - string - 'null' reason: type: - string - 'null' baseline: anyOf: - type: object properties: scope: type: string enum: - target - rest_of_account days: type: array description: Three whole days in the ad account timezone; excludes the change day. items: type: string format: date currency: type: - string - 'null' timezone: type: string spend_minor: type: - string - 'null' description: Decimal spend in ISO currency minor units; null when daily mirror data is missing. counted_arrivals: type: - integer - 'null' description: Arrivals counted by PlainRouter through Signals, never provider conversions. cost_per_counted_arrival_minor: type: - string - 'null' description: Spend divided by counted arrivals, in ISO currency minor units, displayed to six decimal places. - type: array items: type: string metrics: anyOf: - type: object properties: scope: type: string enum: - target - rest_of_account days: type: array description: Three whole days in the ad account timezone; excludes the change day. items: type: string format: date currency: type: - string - 'null' timezone: type: string spend_minor: type: - string - 'null' description: Decimal spend in ISO currency minor units; null when daily mirror data is missing. counted_arrivals: type: - integer - 'null' description: Arrivals counted by PlainRouter through Signals, never provider conversions. cost_per_counted_arrival_minor: type: - string - 'null' description: Spend divided by counted arrivals, in ISO currency minor units, displayed to six decimal places. verdict: type: - string - 'null' enum: - held - lost - not_judged - null loss_threshold_percent: type: string - type: array items: type: string inverse: type: object properties: status: type: string enum: - proposed - inverse_not_proposed batch_id: type: string reason_code: type: string required: - status additionalProperties: {} required: - original_action_id - outcome - type: object properties: rule_id: type: string revision_id: type: string run_id: type: string decision_id: type: string required: - rule_id - revision_id - run_id - decision_id - type: object description: System evidence from a completed Test cites its Test, verdict and selected winner member. properties: test_id: type: string verdict_id: type: string winner_member_id: type: string required: - test_id - verdict_id - winner_member_id status: type: string enum: - pending - approved_without_execution - rejected - executing - executed_pending_verification - compensating - measuring - verified - failed - execution_uncertain - rolled_back - blocked batch_status: type: string enum: - pending - approved - approved_without_execution - auto_approved - rejected - executing - executed_pending_verification - compensating - measuring - completed - failed - rolled_back - rollback_incomplete - blocked - halted disposition: $ref: '#/components/schemas/ActionCurrentDisposition' policy_decision: type: - string - 'null' enum: - allow - require_approval - block - null policy_reasons: type: array items: type: string policy_result: anyOf: - $ref: '#/components/schemas/ActionPolicyResult' - type: 'null' policy_results: type: array items: $ref: '#/components/schemas/ActionPolicyResult' required: - id - batch_id - workspace_id - type - target_entity_type - target_entity_id - target_entity_name - params - rationale - status - batch_status - disposition - policy_decision - policy_reasons - policy_result - policy_results title: ActionReadItem securitySchemes: workspaceSecret: type: http description: Per-workspace Server secret. It authenticates only the Signals workspace represented by the credential. scheme: bearer sandboxCredential: type: http description: Short-lived Sandbox key issued by POST /sandbox/keys. scheme: bearer workspaceActionKey: type: http description: Workspace key with read-actions for reads or propose-actions for writes. Unbound keys select an available advertising account with account_id. scheme: bearer planWriter: type: http description: An OAuth agent or account-bound Workspace Key with write access and the plan-create grant. scheme: bearer workspaceInventoryKey: type: http description: Workspace read key with the get_inventory_metrics grant. Account-bound keys can read only their bound account. scheme: bearer planReader: type: http description: An OAuth agent or account-bound Workspace Key with read access to the approved ad account. scheme: bearer creativeWriter: type: http description: Workspace-bound write credential with a grant authorizing creative intake. scheme: bearer testReader: type: http description: A workspace principal with read tier and the launch.plans.index and launch.plans.show grants for this account. scheme: bearer testWriter: type: http description: A workspace principal with write tier and the launch.plans.store grant for this account. scheme: bearer ruleReader: type: http description: 'A workspace-scoped key with read ability and actions.rules.index or actions.rules.show access to the bound account. Send Accept: application/json.' scheme: bearer ruleWriter: type: http description: 'A workspace-scoped key with write ability and the actions.rules.store or actions.rules.update grant. Send Accept: application/json.' scheme: bearer agentContextKey: type: http description: Workspace key with read ability, ad-account.read permission and the agent.context grant. scheme: bearer agentContextOAuth: type: oauth2 description: OAuth access token for an active approved agent principal with mcp:use, ad-account.read and agent.context authorization. Authorization code with PKCE and device authorization tokens are accepted. This scheme applies only to agent context. flows: authorizationCode: authorizationUrl: https://plainrouter.com/oauth2/authorize tokenUrl: https://plainrouter.com/oauth2/token refreshUrl: https://plainrouter.com/oauth2/token scopes: mcp:use: Use the approved agent principal. x-refined-from: - dev-plainrouter-openapi.json - plainrouter-openapi.json x-action-types: - increase_budget - decrease_budget - pause - resume - replace_creative - shift_spend - rollback - create_campaign - create_ad_set - create_ad - upload_asset x-signed: true