openapi: 3.2.0 info: title: Plainrouter Conversion Launch Policy API version: 0.5.0 description: Plainrouter public Signals Conversion API. servers: - url: https://plainrouter.com/api/v1 description: Production security: - workspaceSecret: [] tags: - name: LaunchPolicy paths: /workspaces/{workspace}/admin/policies: post: operationId: launch.policies.store description: Read or maintain versioned naming and UTM policies in the authorized workspace. Policies apply to plans without submitting provider writes. summary: Create a Launch policy tags: - LaunchPolicy parameters: - name: workspace in: path required: true description: The workspace ID schema: type: integer requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/StoreLaunchPolicyRequest' responses: '201': description: '' content: application/json: schema: type: object properties: policy: type: array items: {} required: - policy '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: A missing workspace returns the api_route_not_found envelope. content: application/json: schema: $ref: '#/components/schemas/ApiRouteNotFound' '422': description: JSON booleans in integer inputs, including workspace selectors, return message plus errors mapping field names to arrays of messages. Numeric strings retain their existing validation and coercion. content: application/json: schema: $ref: '#/components/schemas/ValidationError' get: operationId: launch.policies.index description: Read or maintain versioned naming and UTM policies in the authorized workspace. Policies apply to plans without submitting provider writes. summary: List Launch policies tags: - LaunchPolicy parameters: - name: workspace in: path required: true description: The workspace ID schema: type: integer - name: per_page in: query schema: type: integer - name: page in: query description: Integer page from 1 through 10000000000000000; integer strings are accepted. Zero, negatives, fractions, non-numeric strings and booleans return 422 with a page field validation error. schema: type: integer minimum: 1 maximum: 10000000000000000 responses: '200': description: '' content: application/json: schema: type: object properties: policies: type: object properties: current_page: type: integer minimum: 1 data: type: array items: $ref: '#/components/schemas/LaunchPolicy' first_page_url: type: - string - 'null' from: type: - integer - 'null' minimum: 1 last_page_url: type: - string - 'null' last_page: type: integer minimum: 1 links: type: array description: Generated paginator links. 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' description: Base path for paginator generated URLs. per_page: type: integer description: Number of items shown per page. minimum: 0 prev_page_url: type: - string - 'null' to: type: - integer - 'null' description: Number of the last item in the slice. minimum: 1 total: type: integer description: Total number of items being paginated. minimum: 0 required: - current_page - data - first_page_url - from - last_page_url - last_page - links - next_page_url - path - per_page - prev_page_url - to - total required: - policies '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: A missing workspace returns the api_route_not_found envelope. content: application/json: schema: $ref: '#/components/schemas/ApiRouteNotFound' '422': description: JSON booleans in integer inputs, including workspace selectors, return message plus errors mapping field names to arrays of messages. Numeric strings retain their existing validation and coercion. content: application/json: schema: $ref: '#/components/schemas/ValidationError' /workspaces/{workspace}/admin/policies/{launch_policy}/retire: post: operationId: launch.policies.retire description: Read or maintain versioned naming and UTM policies in the authorized workspace. Policies apply to plans without submitting provider writes. summary: Retire a Launch policy tags: - LaunchPolicy parameters: - name: workspace in: path required: true description: The workspace ID schema: type: integer - name: launch_policy in: path required: true schema: type: string responses: '200': description: '' content: application/json: schema: type: object properties: policy: type: array items: {} required: - policy '401': description: Invalid or missing Server secret. content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' '404': description: A missing workspace returns the api_route_not_found envelope. content: application/json: schema: $ref: '#/components/schemas/ApiRouteNotFound' '422': description: JSON booleans in integer inputs, including workspace selectors, return message plus errors mapping field names to arrays of messages. Numeric strings retain their existing validation and coercion. content: application/json: schema: $ref: '#/components/schemas/ValidationError' components: schemas: 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 ValidationError: type: object properties: message: type: string errors: type: object additionalProperties: type: array items: type: string required: - message - errors title: ValidationError LaunchPolicy: type: object properties: id: type: string workspace_id: type: integer kind: type: string name: type: string version: type: integer body: type: array items: {} status: type: string created_at: type: - string - 'null' format: date-time updated_at: type: - string - 'null' format: date-time required: - id - workspace_id - kind - name - version - body - status - created_at - updated_at title: LaunchPolicy ErrorMessage: type: object properties: message: type: string required: - message title: ErrorMessage StoreLaunchPolicyRequest: type: object properties: kind: type: string enum: - utm - naming name: type: string maxLength: 255 body: type: array items: type: string minItems: 1 required: - kind - name - body title: StoreLaunchPolicyRequest 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. Optional positive account ID. A bound key may name only its own account; a different ID returns 422. An unbound key requires exactly one active available advertising account with an active connection; omission uses that account and a supplied ID must match it. Multiple active accounts return 422 even when account_id is supplied. 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 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. 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 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