openapi: 3.2.0 info: title: Plainrouter Operations API version: 0.5.0 description: 'Operations tagged Operations 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: Operations paths: /dashboard/events: get: operationId: listEvents description: Returns retained customer-readable events with stable pagination and aggregate destination-delivery acceptance metrics for the workspace. summary: List recent events tags: - Operations parameters: - name: per_page in: query description: Events per page, capped at 100. schema: type: integer default: 25 responses: '200': description: Page-number-paginated events and delivery acceptance metrics. content: application/json: schema: type: object properties: events: type: object properties: current_page: type: integer data: type: array items: type: object properties: id: type: string workspace_id: type: integer signal_tracker_id: type: string description: Deprecated alias of workspace_id; contains the workspace ID in decimal string form. deprecated: true parent_event_id: type: - string - 'null' event_name: type: string event_time: type: string action_source: type: string event_class: type: string order_id: type: - string - 'null' value_amount: type: - integer - 'null' value_currency: type: - string - 'null' created_at: type: string consent_basis: type: string measurement_class: type: string attribution_join: type: string enforcement_scope: type: string consent_normalization_version: type: string consent: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' user_data_hashed: description: Deprecated compatibility field. The value is always null; delivery identity is never returned. anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' click_ids: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' session: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' value_data: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' event_source: type: - string - 'null' payload_expired: type: boolean deliveries: type: array items: type: object properties: id: type: integer workspace_id: type: integer signal_tracker_id: type: string description: Deprecated alias of workspace_id; contains the workspace ID in decimal string form. deprecated: true event_id: type: string destination_id: type: - string - 'null' status: $ref: '#/components/schemas/DeliveryStatus' is_test: type: boolean attempt_count: type: integer last_error: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' platform_response: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' platform_trace_id: type: - string - 'null' next_attempt_at: type: - string - 'null' created_at: type: string updated_at: type: - string - 'null' required: - id - workspace_id - signal_tracker_id - event_id - destination_id - status - is_test - attempt_count - last_error - platform_response - platform_trace_id - next_attempt_at - created_at - updated_at required: - id - workspace_id - signal_tracker_id - parent_event_id - event_name - event_time - action_source - event_class - order_id - value_amount - value_currency - created_at - consent_basis - measurement_class - attribution_join - enforcement_scope - consent_normalization_version - consent - user_data_hashed - click_ids - session - value_data - event_source - payload_expired - deliveries first_page_url: type: - string - 'null' from: type: - integer - 'null' last_page: type: integer last_page_url: type: - string - 'null' links: type: array items: type: object properties: url: type: - string - 'null' label: type: string active: type: boolean required: - url - label - active next_page_url: type: - string - 'null' path: type: - string - 'null' per_page: type: integer prev_page_url: type: - string - 'null' to: type: - integer - 'null' total: type: integer required: - current_page - data - first_page_url - from - last_page - last_page_url - links - next_page_url - path - per_page - prev_page_url - to - total metrics: type: object properties: accepted: type: integer total_deliveries: type: integer acceptance_rate: type: - number - 'null' acceptance_rate_window: type: string required: - accepted - total_deliveries - acceptance_rate - acceptance_rate_window required: - events - metrics '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' servers: - url: https://plainrouter.com/api/v1 description: Production /dashboard/events/cursor: get: operationId: listEventsByCursor description: Returns retained customer-readable events using stable cursor pagination and aggregate destination-delivery acceptance metrics. summary: List recent events by cursor tags: - Operations parameters: - name: per_page in: query description: Events per cursor page, capped at 100. schema: type: integer default: 25 - name: cursor in: query description: Opaque cursor returned by a previous response. Omit it on the first request. schema: type: string responses: '200': description: Cursor-paginated events and delivery acceptance metrics. content: application/json: schema: type: object properties: events: type: object properties: data: type: array items: type: object properties: id: type: string workspace_id: type: integer signal_tracker_id: type: string description: Deprecated alias of workspace_id; contains the workspace ID in decimal string form. deprecated: true parent_event_id: type: - string - 'null' event_name: type: string event_time: type: string action_source: type: string event_class: type: string order_id: type: - string - 'null' value_amount: type: - integer - 'null' value_currency: type: - string - 'null' created_at: type: string consent_basis: type: string measurement_class: type: string attribution_join: type: string enforcement_scope: type: string consent_normalization_version: type: string consent: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' user_data_hashed: description: Deprecated compatibility field. The value is always null; delivery identity is never returned. anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' click_ids: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' session: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' value_data: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' event_source: type: - string - 'null' payload_expired: type: boolean deliveries: type: array items: type: object properties: id: type: integer workspace_id: type: integer signal_tracker_id: type: string description: Deprecated alias of workspace_id; contains the workspace ID in decimal string form. deprecated: true event_id: type: string destination_id: type: - string - 'null' status: $ref: '#/components/schemas/DeliveryStatus' is_test: type: boolean attempt_count: type: integer last_error: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' platform_response: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' platform_trace_id: type: - string - 'null' next_attempt_at: type: - string - 'null' created_at: type: string updated_at: type: - string - 'null' required: - id - workspace_id - signal_tracker_id - event_id - destination_id - status - is_test - attempt_count - last_error - platform_response - platform_trace_id - next_attempt_at - created_at - updated_at required: - id - workspace_id - signal_tracker_id - parent_event_id - event_name - event_time - action_source - event_class - order_id - value_amount - value_currency - created_at - consent_basis - measurement_class - attribution_join - enforcement_scope - consent_normalization_version - consent - user_data_hashed - click_ids - session - value_data - event_source - payload_expired - deliveries path: type: - string - 'null' per_page: type: integer next_cursor: type: - string - 'null' next_page_url: type: - string - 'null' prev_cursor: type: - string - 'null' prev_page_url: type: - string - 'null' required: - data - path - per_page - next_cursor - next_page_url - prev_cursor - prev_page_url metrics: type: object properties: accepted: type: integer total_deliveries: type: integer acceptance_rate: type: - number - 'null' acceptance_rate_window: type: string required: - accepted - total_deliveries - acceptance_rate - acceptance_rate_window required: - events - metrics '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' servers: - url: https://plainrouter.com/api/v1 description: Production /destinations/{destination}/test-mode: patch: operationId: setDestinationTestMode description: Enables or disables Meta Test Events mode for a destination owned by the authenticated Signals workspace. summary: Configure destination test mode tags: - Operations parameters: - name: destination in: path required: true description: The destination ID schema: type: string requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean test_event_code: type: - string - 'null' maxLength: 100 required: - enabled responses: '200': description: Updated destination and its effective test-mode state. content: application/json: schema: type: object properties: destination: type: object properties: id: type: string workspace_id: type: integer signal_tracker_id: type: string description: Deprecated alias of workspace_id; contains the workspace ID in decimal string form. deprecated: true platform_ad_account_id: type: - integer - 'null' type: $ref: '#/components/schemas/DestinationType' credential_source: $ref: '#/components/schemas/DestinationCredentialSource' config: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' status: $ref: '#/components/schemas/DestinationStatus' created_at: type: - string - 'null' updated_at: type: - string - 'null' required: - id - workspace_id - signal_tracker_id - platform_ad_account_id - type - credential_source - config - status - created_at - updated_at test_mode: type: boolean required: - destination - test_mode '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: Resource not found. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Request validation failed. content: application/json: schema: $ref: '#/components/schemas/ValidationError' servers: - url: https://plainrouter.com/api/v1 description: Production /destinations/{destination}/test-purchase: post: operationId: sendTestPurchase description: Creates an identity-free synthetic purchase and sends it only to the selected destination while test mode is enabled. summary: Send a controlled test purchase tags: - Operations parameters: - name: destination in: path required: true description: The destination ID schema: type: string requestBody: content: application/json: schema: type: object properties: value: type: - string - 'null' pattern: ^-?\d+(?:\.\d+)?$ currency: type: - string - 'null' minLength: 3 maxLength: 3 order_id: type: - string - 'null' maxLength: 128 responses: '200': description: Meta accepted the test purchase. content: application/json: schema: type: object properties: event_id: type: string status: $ref: '#/components/schemas/DeliveryStatus' trace_id: type: - string - 'null' required: - event_id - status - trace_id '502': description: Meta did not accept the test purchase. content: application/json: schema: type: object properties: event_id: type: string status: $ref: '#/components/schemas/DeliveryStatus' trace_id: type: - string - 'null' required: - event_id - status - trace_id '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: Resource not found. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Test mode is disabled or request validation failed. content: application/json: schema: anyOf: - $ref: '#/components/schemas/ValidationError' - $ref: '#/components/schemas/ErrorMessage' servers: - url: https://plainrouter.com/api/v1 description: Production /deliveries/replay: post: operationId: replayDeliveries description: Evaluates retained failed deliveries, queues the eligible subset for another delivery attempt, and reports which records were accepted or rejected. summary: Replay eligible deliveries tags: - Operations requestBody: content: application/json: schema: type: object properties: delivery_ids: type: array items: type: integer event_name: type: - string - 'null' maxLength: 100 limit: type: - integer - 'null' minimum: 1 responses: '202': description: Replay candidates were evaluated and eligible deliveries queued. content: application/json: schema: type: object properties: queued: type: integer expired: type: integer payload_expired: type: integer capped: type: boolean required: - queued - expired - payload_expired - capped headers: Location: description: Event collection to poll for updated delivery state. schema: type: string format: uri '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Request validation failed. content: application/json: schema: $ref: '#/components/schemas/ValidationError' servers: - url: https://plainrouter.com/api/v1 description: Production /reports/reconciliation: get: operationId: getReconciliationReport description: Returns stored delivery-versus-platform reconciliation results for one date. Dates before the workspace read bound return 422. summary: Get a reconciliation report tags: - Operations parameters: - name: date in: query required: true schema: type: string format: date responses: '200': description: Stored reconciliation reports for the requested date. content: application/json: schema: type: object properties: date: type: string reports: type: array items: type: object properties: id: type: integer workspace_id: type: integer signal_tracker_id: type: string description: Deprecated alias of workspace_id; contains the workspace ID in decimal string form. deprecated: true destination_id: type: string report_date: type: string accepted_count: type: integer meta_count: type: integer observed_gap: type: integer event_counts: type: object properties: accepted: anyOf: - type: object additionalProperties: type: integer - type: array items: {} meta: anyOf: - type: object additionalProperties: type: integer - type: array items: {} required: - accepted - meta buckets: type: object additionalProperties: type: object properties: count: type: integer basis: type: string explanation: type: string required: - count - basis - explanation unexplained_residual: type: integer status: type: string created_at: type: - string - 'null' updated_at: type: - string - 'null' destination: type: object properties: id: type: string workspace_id: type: integer signal_tracker_id: type: string description: Deprecated alias of workspace_id; contains the workspace ID in decimal string form. deprecated: true platform_ad_account_id: type: - integer - 'null' type: $ref: '#/components/schemas/DestinationType' credential_source: $ref: '#/components/schemas/DestinationCredentialSource' config: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' status: $ref: '#/components/schemas/DestinationStatus' created_at: type: - string - 'null' updated_at: type: - string - 'null' required: - id - workspace_id - signal_tracker_id - platform_ad_account_id - type - credential_source - config - status - created_at - updated_at required: - id - workspace_id - signal_tracker_id - destination_id - report_date - accepted_count - meta_count - observed_gap - event_counts - buckets - unexplained_residual - status - created_at - updated_at - destination required: - date - reports '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Request validation failed. content: application/json: schema: $ref: '#/components/schemas/ValidationError' servers: - url: https://plainrouter.com/api/v1 description: Production /reports/emq: get: operationId: getEmqReport description: Returns recent Meta Event Match Quality snapshots for the authenticated Signals workspace so callers can inspect measured quality changes over time. summary: Get Event Match Quality history tags: - Operations responses: '200': description: Recent event-match-quality snapshots. content: application/json: schema: type: object properties: snapshots: type: array items: type: object properties: id: type: integer workspace_id: type: integer signal_tracker_id: type: string description: Deprecated alias of workspace_id; contains the workspace ID in decimal string form. deprecated: true destination_id: type: string score: type: number week_over_week_change: type: - number - 'null' alerted: type: boolean platform_response: anyOf: - type: object additionalProperties: {} - type: array items: {} - type: 'null' measured_at: type: string created_at: type: - string - 'null' updated_at: type: - string - 'null' required: - id - workspace_id - signal_tracker_id - destination_id - score - week_over_week_change - alerted - platform_response - measured_at - created_at - updated_at required: - snapshots '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' servers: - url: https://plainrouter.com/api/v1 description: Production /user-data: delete: operationId: deleteUserData description: Idempotently removes retained user data using a verified raw identifier or legacy SHA-256 digest, scoped and keyed to the authenticated workspace. summary: Delete user data by verified identifier tags: - Operations requestBody: required: true content: application/json: schema: type: object properties: identifier_type: type: string enum: - email - phone - external_id identifier_hash: type: string pattern: ^[a-fA-F0-9]{64}$ identifier: type: string maxLength: 512 required: - identifier_type oneOf: - required: - identifier_hash - required: - identifier responses: '200': description: Completed idempotent deletion request. content: application/json: schema: type: object properties: deletion_request_id: type: string duplicate: type: boolean events_updated: type: integer sessions_updated: type: integer completed_at: type: string required: - deletion_request_id - duplicate - events_updated - sessions_updated - completed_at '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '422': description: Request validation failed. content: application/json: schema: $ref: '#/components/schemas/ValidationError' servers: - url: https://plainrouter.com/api/v1 description: Production components: schemas: DestinationCredentialSource: type: string enum: - oauth_connection title: DestinationCredentialSource DestinationStatus: type: string enum: - active - inactive title: DestinationStatus DestinationType: type: string enum: - meta - google_ads title: DestinationType ValidationError: type: object properties: message: type: string errors: type: object additionalProperties: type: array items: type: string required: - message - errors title: ValidationError DeliveryStatus: type: string enum: - queued - sent - accepted - retrying - failed:auth - failed:permanent - failed:unknown - expired - skipped:consent - skipped:no_destination - skipped:duplicate title: DeliveryStatus ErrorMessage: type: object properties: message: type: string required: - message title: ErrorMessage DestinationStatus_2: type: string enum: - active - needs_attention - inactive title: DestinationStatus DeliveryStatus_2: type: string enum: - queued - sent - held - accepted - retrying - failed:auth - failed:permanent - failed:unknown - expired - skipped:consent - skipped:no_destination - skipped:duplicate - skipped:lifecycle title: DeliveryStatus 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