PublicPolicyResponse
A policy as returned by the public API: a workflow, authored here or in the app. Read responses surface every action type a workflow can carry, including ones the narrower ``PublicPolicyActions`` request shape does not accept. Policies managed by data contracts are not part of this surface.
Properties
| Name | Type | Description |
|---|---|---|
| id | string | Stable identifier of the policy. |
| name | string | Policy name (unique within the organization). |
| isEnabled | boolean | Whether the policy currently fires. |
| triggeringEvents | array | Events that cause the policy to evaluate. |
| rulesData | object | Rules that decide when the policy fires. |
| actionsData | object | Actions taken when the policy fires. A `send_webhook` action's `url` is shown as its scheme and host only (`https://hooks.example.com`), since a webhook URL often carries its receiver's credential. |
| repositoryNames | array | Repository full names this policy is scoped to. Empty list means it applies to every repository. |
| createdAt | string | When the policy was created (UTC). |
| updatedAt | object | When the policy was last updated (UTC). `null` if it has never been updated. |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/foundational/json-schema/foundational-public-policy-response-schema.json",
"title": "PublicPolicyResponse",
"description": "A policy as returned by the public API: a workflow, authored here or in the app.\n\nRead responses surface every action type a workflow can carry, including ones the narrower\n``PublicPolicyActions`` request shape does not accept. Policies managed by data contracts are\nnot part of this surface.",
"x-generated": "2026-10-29",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/foundational-openapi.json#/components/schemas/PublicPolicyResponse",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"title": "Id",
"description": "Stable identifier of the policy."
},
"name": {
"type": "string",
"title": "Name",
"description": "Policy name (unique within the organization)."
},
"isEnabled": {
"type": "boolean",
"title": "Isenabled",
"description": "Whether the policy currently fires."
},
"triggeringEvents": {
"items": {
"$ref": "#/$defs/PolicyTriggeringEvent"
},
"type": "array",
"title": "Triggeringevents",
"description": "Events that cause the policy to evaluate."
},
"rulesData": {
"$ref": "#/$defs/WorkflowRulesData",
"description": "Rules that decide when the policy fires."
},
"actionsData": {
"$ref": "#/$defs/PolicyActionsData",
"description": "Actions taken when the policy fires. A `send_webhook` action's `url` is shown as its scheme and host only (`https://hooks.example.com`), since a webhook URL often carries its receiver's credential."
},
"repositoryNames": {
"items": {
"type": "string"
},
"type": "array",
"title": "Repositorynames",
"description": "Repository full names this policy is scoped to. Empty list means it applies to every repository."
},
"createdAt": {
"type": "string",
"format": "date-time",
"title": "Createdat",
"description": "When the policy was created (UTC)."
},
"updatedAt": {
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "null"
}
],
"title": "Updatedat",
"description": "When the policy was last updated (UTC). `null` if it has never been updated."
}
},
"type": "object",
"required": [
"id",
"name",
"isEnabled",
"triggeringEvents",
"rulesData",
"actionsData",
"repositoryNames",
"createdAt"
],
"$defs": {
"AddPRReviewerAction": {
"properties": {
"action_type": {
"type": "string",
"const": "add_pr_reviewer",
"title": "Action Type",
"default": "add_pr_reviewer"
},
"reviewers": {
"items": {
"type": "string"
},
"type": "array",
"title": "Reviewers"
}
},
"type": "object",
"required": [
"reviewers"
],
"title": "AddPRReviewerAction"
},
"ChangeAffectingEntitiesQueryRule": {
"properties": {
"rule_type": {
"type": "string",
"const": "change_affecting_entities_query_rule",
"title": "Rule Type",
"default": "change_affecting_entities_query_rule"
},
"matching_entity_queries": {
"items": {
"type": "string"
},
"type": "array",
"title": "Matching Entity Queries",
"default": []
},
"upstream_entity_queries": {
"items": {
"type": "string"
},
"type": "array",
"title": "Upstream Entity Queries",
"default": []
}
},
"additionalProperties": false,
"type": "object",
"title": "ChangeAffectingEntitiesQueryRule",
"description": "A rule that triggers when a change lands on a watched entity or anywhere in its upstream.\n\nA *subject* watch: ``matching_entity_queries`` names the entities the user is protecting, so a\nchange inside a matched entity -- a column of a watched table -- counts as a change affecting it,\nand is reported against the matched ancestor the user configured.\n\nThe rule is the union of two arms, either of which fires it:\n\n* the **self** arm, a change of any type (added, removed or modified) on a watched entity or\n inside one. Never narrowed by ``upstream_entity_queries``: a filter naming where a change may\n come *from* has nothing to say about a change on the subject itself.\n* the **upstream** arm, a change of any type on something the watched entities transitively\n depend on, optionally narrowed to ``upstream_entity_queries``.\n\nThe two arms are genuinely disjoint rather than one subsuming the other, which is why both are\nneeded: the upstream traversal excludes the watched entities themselves, and the self arm does\nnot follow lineage.\n\n``matching_entity_queries`` is required non-empty -- the upstream arm resolves it against the\nwhole org, so an empty list is an unbounded watch rather than an absent filter.\n``upstream_entity_queries`` is satisfied when the changed entity itself matches; ``[]``\nimposes no constraint. An added-or-removed change on a watched entity also satisfies\n``entity_added_or_removed_query_rule``; a policy holding both types firing twice on one change is\naccepted rather than deduplicated."
},
"EntityAddedOrRemovedQueryRule": {
"properties": {
"rule_type": {
"type": "string",
"const": "entity_added_or_removed_query_rule",
"title": "Rule Type",
"default": "entity_added_or_removed_query_rule"
},
"matching_entity_queries": {
"items": {
"type": "string"
},
"type": "array",
"title": "Matching Entity Queries",
"default": []
},
"change_types": {
"anyOf": [
{
"items": {
"$ref": "#/$defs/PolicyRuleChangeType"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Change Types"
}
},
"additionalProperties": false,
"type": "object",
"title": "EntityAddedOrRemovedQueryRule",
"description": "A rule that triggers when an entity matching the rule's queries is added or removed.\n\n``change_types`` selects which of ``ENTITY_ADDED_OR_REMOVED_CHANGE_TYPES`` trigger the rule.\n``None`` and ``[]`` both mean \"every supported change type\" -- an empty selection is normalized\nto ``None`` on construction, so a consumer only ever sees ``None`` or a non-empty list. That\nmatches the editor's All/Added/Removed selector, where \"All\" is the absence of a filter rather\nthan a selection of everything. The entity kind is expressed as a ``type:`` token inside the\nquery strings, not as a field on the rule.\n\nThis rule names *the changes to report*, not a subject to protect, so a child of a matched entity\nis reported only when it matches ``matching_entity_queries`` itself (FOU-16832). The rule that\nreads a watch as a subject -- and so follows a change down into it -- is\n``change_affecting_entities_query_rule``."
},
"IssueSeverity": {
"type": "string",
"enum": [
"critical",
"error",
"warning",
"info"
],
"title": "IssueSeverity"
},
"NewDownstreamConsumersQueryRule": {
"properties": {
"rule_type": {
"type": "string",
"const": "new_downstream_consumers_query_rule",
"title": "Rule Type",
"default": "new_downstream_consumers_query_rule"
},
"matching_entity_queries": {
"items": {
"type": "string"
},
"type": "array",
"title": "Matching Entity Queries",
"default": []
},
"downstream_consumer_queries": {
"items": {
"type": "string"
},
"type": "array",
"title": "Downstream Consumer Queries",
"default": []
}
},
"additionalProperties": false,
"type": "object",
"title": "NewDownstreamConsumersQueryRule",
"description": "A rule that triggers when something new starts reading from a watched entity.\n\nKeyed on lineage *edges* added by the change, not on entities: a new edge between two\npre-existing entities -- a query that starts reading another table -- fires the rule, and an\nentity added without any edge cannot. A watched entity counts as the edge's source when the\nsource is the watched entity itself, is transitively upstream of it, or is a column of it.\n\n``matching_entity_queries`` is required non-empty: unlike its issue- and diff-bounded siblings\nthis rule has no candidate set to fall back on, so an empty watch list makes it permanently inert\nrather than unconstrained.\n\n``downstream_consumer_queries`` limits which new consumers count -- the edge's destination, or\nits parent, must match one of the queries. ``[]`` imposes no constraint, which is exactly the\nbehaviour the rule had before the field existed."
},
"NewIssueQueryRule": {
"properties": {
"rule_type": {
"type": "string",
"const": "new_issue_query_rule",
"title": "Rule Type",
"default": "new_issue_query_rule"
},
"matching_entity_queries": {
"items": {
"type": "string"
},
"type": "array",
"title": "Matching Entity Queries",
"default": []
},
"downstream_entity_queries": {
"items": {
"type": "string"
},
"type": "array",
"title": "Downstream Entity Queries",
"default": []
},
"issue_types": {
"items": {
"type": "string"
},
"type": "array",
"title": "Issue Types",
"default": [
"*"
]
},
"issue_severities": {
"items": {
"$ref": "#/$defs/IssueSeverity"
},
"type": "array",
"title": "Issue Severities",
"default": []
}
},
"additionalProperties": false,
"type": "object",
"title": "NewIssueQueryRule",
"description": "A rule that triggers when a new issue is detected on an entity matching the rule's queries.\n\n``issue_severities`` is a membership filter, not a minimum: an empty list matches every severity.\n``issue_types`` is the same kind of filter: an empty list, or any list containing ``\"*\"`` (the\ndefault), matches every issue type; anything else is exact membership -- a \"deselect all\" in the\nUI must not silently produce a rule that can never fire.\n\nA selection covering the whole issue-type catalog, or a whole category of it, is stored in a\nform that keeps up with the catalog, so a type added later fires the rule without it being\nre-saved. Reading such a rule back therefore reports the types that qualify *now*, which can be\nmore (or differently ordered) than what was submitted.\n\nThat form reserves the ``category:`` prefix, so entries starting with it are rejected on write.\nAn entry naming no known issue type is otherwise accepted, and matches nothing.\n\n``downstream_entity_queries`` narrows the rule to watched entities that reach one of the queries\n-- the entity itself, its parent, or one of its transitive downstreams matches a query; ``[]``\nimposes no such constraint. It is the one query list this category resolves *leniently*: with no\nlineage graph it is ignored when ``matching_entity_queries`` is also set, since it only narrows\nan already-bounded candidate set. Without ``matching_entity_queries`` it is the sole entity\nscoping and fails closed. An entity-free issue type (``entity_free_issue_type()`` returns\n``True``) skips both constraints, so types that can never carry an entity still reach a rule that\nasks for one; entity-capable types with unresolved required descriptors fail closed.\n\nThis is the only rule type carrying ``downstream_entity_queries``. Whether a given issue type\ncan be filtered by it at all is a per-category affordance the ``/workflows/issue_types`` surface\npublishes as ``supports_downstream_filter``."
},
"PolicyActionsData": {
"properties": {
"actions": {
"items": {
"oneOf": [
{
"$ref": "#/$defs/SendEmailAction"
},
{
"$ref": "#/$defs/SendSlackMessageAction"
},
{
"$ref": "#/$defs/SendTeamsMessageAction"
},
{
"$ref": "#/$defs/AddPRReviewerAction"
},
{
"$ref": "#/$defs/SubmitPRReviewAction"
},
{
"$ref": "#/$defs/SendWebhookAction"
}
]
},
"type": "array",
"title": "Actions"
}
},
"type": "object",
"required": [
"actions"
],
"title": "PolicyActionsData"
},
"PolicyRuleChangeType": {
"type": "string",
"enum": [
"added",
"removed",
"modified",
"renamed"
],
"title": "PolicyRuleChangeType",
"description": "The type of the lineage entity change (eg. added / removed / modified / renamed)"
},
"PolicyTriggeringEvent": {
"type": "string",
"enum": [
"*",
"on_pr_in_progress",
"on_pr_merged",
"on_non_code_scanned",
"on_pushed_to_default_branch",
"on_observability_scan"
],
"title": "PolicyTriggeringEvent"
},
"SendEmailAction": {
"properties": {
"action_type": {
"type": "string",
"const": "send_email",
"title": "Action Type",
"default": "send_email"
},
"recipients": {
"items": {
"type": "string"
},
"type": "array",
"title": "Recipients"
}
},
"type": "object",
"required": [
"recipients"
],
"title": "SendEmailAction"
},
"SendSlackMessageAction": {
"properties": {
"action_type": {
"type": "string",
"const": "send_slack_message",
"title": "Action Type",
"default": "send_slack_message"
},
"channels": {
"items": {
"type": "string"
},
"type": "array",
"title": "Channels"
}
},
"type": "object",
"required": [
"channels"
],
"title": "SendSlackMessageAction"
},
"SendTeamsMessageAction": {
"properties": {
"action_type": {
"type": "string",
"const": "send_teams_message",
"title": "Action Type",
"default": "send_teams_message"
},
"channels": {
"items": {
"type": "string"
},
"type": "array",
"title": "Channels"
}
},
"type": "object",
"required": [
"channels"
],
"title": "SendTeamsMessageAction"
},
"SendWebhookAction": {
"properties": {
"action_type": {
"type": "string",
"const": "send_webhook",
"title": "Action Type",
"default": "send_webhook"
},
"url": {
"type": "string",
"title": "Url"
}
},
"type": "object",
"required": [
"url"
],
"title": "SendWebhookAction",
"description": "POST the trigger payload to an HTTPS endpoint when the policy fires."
},
"SubmitPRReviewAction": {
"properties": {
"action_type": {
"type": "string",
"const": "submit_pr_review",
"title": "Action Type",
"default": "submit_pr_review"
}
},
"type": "object",
"title": "SubmitPRReviewAction",
"description": "Submit a PR review on every evaluation: REQUEST_CHANGES when the policy triggers,\nAPPROVE when it does not."
},
"WorkflowRulesData": {
"properties": {
"conjunctive_evaluation": {
"type": "boolean",
"title": "Conjunctive Evaluation"
},
"rules": {
"items": {
"oneOf": [
{
"$ref": "#/$defs/NewIssueQueryRule"
},
{
"$ref": "#/$defs/EntityAddedOrRemovedQueryRule"
},
{
"$ref": "#/$defs/ChangeAffectingEntitiesQueryRule"
},
{
"$ref": "#/$defs/NewDownstreamConsumersQueryRule"
}
]
},
"type": "array",
"minItems": 1,
"title": "Rules"
}
},
"type": "object",
"required": [
"conjunctive_evaluation",
"rules"
],
"title": "WorkflowRulesData",
"description": "``PolicyRulesData`` restricted to the query-targeted rule types — the shape the workflows API exposes.\n\n``rules`` must be non-empty: a rule-less workflow could never fire."
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
curl "https://apis.io/api/v1/json-schemas/foundational-public-policy-response"
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.