{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://dee-wan.dev/schemas/plugins/protocol-v1.schema.json",
  "title": "Dee Wan plugin protocol v1",
  "description": "Request and response shapes for /api/plugin/v1 and the administrative /api/plugins routes. Generated from backend/src/lib/plugins/{protocol,schema}.ts, which the routes use.",
  "protocol_versions": [
    1
  ],
  "capabilities": [
    "content:read",
    "workflow:read",
    "workflow:publish",
    "workflow:unpublish"
  ],
  "installation_states": [
    "pending",
    "active",
    "disabled",
    "revoked"
  ],
  "transition_kinds": [
    "publish",
    "unpublish"
  ],
  "outcomes": {
    "transition_applied": {
      "http": 200,
      "retry": false,
      "message": "The transition was applied."
    },
    "idempotent_replay": {
      "http": 200,
      "retry": false,
      "message": "This command was already applied. The first result is returned."
    },
    "invalid_request": {
      "http": 400,
      "retry": false,
      "message": "The request is not valid for protocol v1."
    },
    "plugin_unauthorized": {
      "http": 401,
      "retry": false,
      "message": "The installation token is missing, unknown, disabled or revoked."
    },
    "capability_refused": {
      "http": 403,
      "retry": false,
      "message": "This installation was not granted that capability or model."
    },
    "requester_unauthorized": {
      "http": 403,
      "retry": false,
      "message": "The person who requested this no longer holds the authority it needs."
    },
    "content_not_found": {
      "http": 404,
      "retry": false,
      "message": "No such content in this installation’s scope."
    },
    "scheduled_target_stale": {
      "http": 409,
      "retry": false,
      "message": "The pinned version is no longer the one this transition would move."
    },
    "workflow_conflict": {
      "http": 409,
      "retry": false,
      "message": "The content moved through its workflow after this was requested."
    },
    "dependent_content": {
      "http": 409,
      "retry": false,
      "message": "Other content depends on this item. A person must review the unpublish in Dee Wan."
    },
    "idempotency_key_reused": {
      "http": 409,
      "retry": false,
      "message": "This idempotency key was already used for a different command."
    },
    "transition_unavailable": {
      "http": 422,
      "retry": false,
      "message": "That transition is not available from the content’s current state."
    },
    "transition_refused": {
      "http": 422,
      "retry": false,
      "message": "The lifecycle refused this transition. Nothing was changed."
    },
    "rate_limited": {
      "http": 429,
      "retry": true,
      "message": "Too many requests for this installation."
    },
    "temporary_failure": {
      "http": 503,
      "retry": true,
      "message": "Dee Wan could not complete the request. Nothing is known to have changed."
    }
  },
  "limits": {
    "token_prefix": "dwp_",
    "launch_code_prefix": "dwl_",
    "max_request_bytes": 16384,
    "max_manifest_bytes": 32768,
    "max_idempotency_key_length": 128,
    "max_page_size": 50,
    "launch_code_ttl_ms": 60000,
    "token_rotation_overlap_ms": 600000,
    "remote_call_timeout_ms": 5000,
    "rate_limit": {
      "max_requests": 120,
      "window_ms": 60000,
      "keyed_by": "installation"
    }
  },
  "$defs": {
    "outcome_envelope": {
      "type": "object",
      "properties": {
        "outcome": {
          "type": "object",
          "properties": {
            "code": {
              "type": "string",
              "enum": [
                "transition_applied",
                "idempotent_replay",
                "invalid_request",
                "plugin_unauthorized",
                "capability_refused",
                "requester_unauthorized",
                "content_not_found",
                "scheduled_target_stale",
                "workflow_conflict",
                "dependent_content",
                "idempotency_key_reused",
                "transition_unavailable",
                "transition_refused",
                "rate_limited",
                "temporary_failure"
              ]
            },
            "message": {
              "type": "string"
            },
            "retry": {
              "type": "boolean"
            }
          },
          "required": [
            "code",
            "message",
            "retry"
          ],
          "additionalProperties": false
        },
        "data": {}
      },
      "required": [
        "outcome"
      ],
      "additionalProperties": false
    },
    "publish_command": {
      "type": "object",
      "properties": {
        "kind": {
          "type": "string",
          "const": "publish"
        },
        "expected_current_version_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64
        },
        "expected_workflow_revision": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "delegation_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64
        }
      },
      "required": [
        "kind",
        "expected_current_version_id",
        "expected_workflow_revision",
        "delegation_id"
      ],
      "additionalProperties": false
    },
    "unpublish_command": {
      "type": "object",
      "properties": {
        "kind": {
          "type": "string",
          "const": "unpublish"
        },
        "expected_published_version_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64
        },
        "expected_workflow_revision": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "delegation_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64
        }
      },
      "required": [
        "kind",
        "expected_published_version_id",
        "expected_workflow_revision",
        "delegation_id"
      ],
      "additionalProperties": false
    },
    "transition_command": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "const": "publish"
            },
            "expected_current_version_id": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "expected_workflow_revision": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "delegation_id": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "required": [
            "kind",
            "expected_current_version_id",
            "expected_workflow_revision",
            "delegation_id"
          ],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "const": "unpublish"
            },
            "expected_published_version_id": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "expected_workflow_revision": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "delegation_id": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "required": [
            "kind",
            "expected_published_version_id",
            "expected_workflow_revision",
            "delegation_id"
          ],
          "additionalProperties": false
        }
      ]
    },
    "launch_exchange_request": {
      "type": "object",
      "properties": {
        "code": {
          "type": "string",
          "pattern": "^dwl_[A-Za-z0-9_-]{43}$"
        }
      },
      "required": [
        "code"
      ],
      "additionalProperties": false
    },
    "content_list_query": {
      "type": "object",
      "properties": {
        "model_id": {
          "type": "string",
          "minLength": 1
        },
        "published": {
          "type": "string",
          "enum": [
            "true",
            "false"
          ]
        },
        "after": {
          "type": "string"
        },
        "limit": {
          "type": "string",
          "pattern": "^\\d{1,3}$",
          "description": "Page size, 1..50. Default 20. Anything else is invalid_request."
        }
      },
      "required": [
        "model_id"
      ],
      "additionalProperties": false
    },
    "content_item_query": {
      "type": "object",
      "properties": {
        "delegation_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64
        }
      },
      "additionalProperties": false
    },
    "context": {
      "type": "object",
      "properties": {
        "installation_id": {
          "type": "string"
        },
        "site": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "default_lang": {
              "type": "string"
            }
          },
          "required": [
            "id",
            "name",
            "default_lang"
          ],
          "additionalProperties": false
        },
        "protocol_version": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "capabilities": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "content:read",
              "workflow:read",
              "workflow:publish",
              "workflow:unpublish"
            ]
          }
        },
        "model_ids": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "required": [
        "installation_id",
        "site",
        "protocol_version",
        "capabilities",
        "model_ids"
      ],
      "additionalProperties": false
    },
    "content_summary": {
      "type": "object",
      "properties": {
        "instance_id": {
          "type": "string"
        },
        "primary_instance_id": {
          "type": "string"
        },
        "translation_group_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "model_id": {
          "type": "string"
        },
        "model_slug": {
          "type": "string"
        },
        "lang": {
          "type": "string"
        },
        "label": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "slug": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "current_version_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "published_version_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "workflow": {
          "type": "object",
          "properties": {
            "state": {
              "type": "string"
            },
            "revision": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            },
            "transitions": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "to": {
                    "type": "string"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "publish",
                      "unpublish"
                    ]
                  }
                },
                "required": [
                  "to",
                  "kind"
                ],
                "additionalProperties": false
              }
            }
          },
          "required": [
            "state",
            "revision",
            "transitions"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "instance_id",
        "primary_instance_id",
        "translation_group_id",
        "model_id",
        "model_slug",
        "lang",
        "label",
        "slug",
        "current_version_id",
        "published_version_id"
      ],
      "additionalProperties": false
    },
    "content_page": {
      "type": "object",
      "properties": {
        "data": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "instance_id": {
                "type": "string"
              },
              "primary_instance_id": {
                "type": "string"
              },
              "translation_group_id": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "model_id": {
                "type": "string"
              },
              "model_slug": {
                "type": "string"
              },
              "lang": {
                "type": "string"
              },
              "label": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "slug": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "current_version_id": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "published_version_id": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "workflow": {
                "type": "object",
                "properties": {
                  "state": {
                    "type": "string"
                  },
                  "revision": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "transitions": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "to": {
                          "type": "string"
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "publish",
                            "unpublish"
                          ]
                        }
                      },
                      "required": [
                        "to",
                        "kind"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "state",
                  "revision",
                  "transitions"
                ],
                "additionalProperties": false
              }
            },
            "required": [
              "instance_id",
              "primary_instance_id",
              "translation_group_id",
              "model_id",
              "model_slug",
              "lang",
              "label",
              "slug",
              "current_version_id",
              "published_version_id"
            ],
            "additionalProperties": false
          }
        },
        "next": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "required": [
        "data",
        "next"
      ],
      "additionalProperties": false
    },
    "transition_result": {
      "type": "object",
      "properties": {
        "instance_id": {
          "type": "string"
        },
        "primary_instance_id": {
          "type": "string"
        },
        "from": {
          "type": "string"
        },
        "to": {
          "type": "string"
        },
        "published": {
          "type": "boolean"
        },
        "published_changed": {
          "type": "boolean"
        },
        "published_version_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "revision": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        }
      },
      "required": [
        "instance_id",
        "primary_instance_id",
        "from",
        "to",
        "published",
        "published_changed",
        "published_version_id",
        "revision"
      ],
      "additionalProperties": false
    },
    "launch_delegation": {
      "type": "object",
      "properties": {
        "delegation_id": {
          "type": "string"
        },
        "installation_id": {
          "type": "string"
        },
        "site_id": {
          "type": "string"
        },
        "action": {
          "type": "string"
        },
        "instance_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "user": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "email": {
              "type": "string"
            }
          },
          "required": [
            "id",
            "email"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "delegation_id",
        "installation_id",
        "site_id",
        "action",
        "instance_id",
        "user"
      ],
      "additionalProperties": false
    },
    "installation": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "plugin_id": {
          "type": "string"
        },
        "plugin_name": {
          "type": "string"
        },
        "plugin_version": {
          "type": "string"
        },
        "protocol_version": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "state": {
          "type": "string",
          "enum": [
            "pending",
            "active",
            "disabled",
            "revoked"
          ]
        },
        "capabilities": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "content:read",
              "workflow:read",
              "workflow:publish",
              "workflow:unpublish"
            ]
          }
        },
        "requested_capabilities": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "content:read",
              "workflow:read",
              "workflow:publish",
              "workflow:unpublish"
            ]
          }
        },
        "model_ids": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "content_actions": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "label": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "label"
            ],
            "additionalProperties": false
          }
        },
        "manifest_url": {
          "type": "string"
        },
        "management_origin": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "created_by_email": {
          "type": "string"
        },
        "created_at": {
          "type": "string"
        },
        "updated_at": {
          "type": "string"
        }
      },
      "required": [
        "id",
        "plugin_id",
        "plugin_name",
        "plugin_version",
        "protocol_version",
        "state",
        "capabilities",
        "requested_capabilities",
        "model_ids",
        "content_actions",
        "manifest_url",
        "management_origin",
        "created_by_email",
        "created_at",
        "updated_at"
      ],
      "additionalProperties": false
    },
    "launch": {
      "type": "object",
      "properties": {
        "url": {
          "type": "string"
        }
      },
      "required": [
        "url"
      ],
      "additionalProperties": false
    }
  },
  "secrets": {
    "installation_token": {
      "pattern": "^dwp_[A-Za-z0-9_-]{43}$",
      "sent_as": "Authorization: Bearer <token>",
      "stored_by_core": "SHA-256 hash only"
    },
    "launch_code": {
      "pattern": "^dwl_[A-Za-z0-9_-]{43}$",
      "sent_as": "query parameter dee_wan_launch",
      "stored_by_core": "SHA-256 hash only"
    }
  }
}
