{
  "openapi": "3.1.0",
  "info": {
    "title": "Envoke Subscription API",
    "version": "2.0.0",
    "description": "Full CRUD API for managing email subscriptions and their contact assignments. All endpoints require HTTP Basic Auth and return JSON. Subscriptions cannot be deleted while contacts are assigned to them — remove all contacts first."
  },
  "servers": [
    {
      "url": "https://e1.envoke.com/v2",
      "description": "Production"
    }
  ],
  "security": [
    {
      "basicAuth": []
    }
  ],
  "tags": [
    {
      "name": "Subscriptions",
      "description": "Operations on subscriptions."
    },
    {
      "name": "Subscription Contacts",
      "description": "Bulk add and remove contacts from a subscription."
    }
  ],
  "components": {
    "securitySchemes": {
      "basicAuth": {
        "type": "http",
        "scheme": "basic",
        "description": "HTTP Basic Auth. Use your API ID as the username and API Key as the password."
      }
    },
    "schemas": {
      "Subscription": {
        "type": "object",
        "description": "A subscription definition.",
        "required": [
          "id",
          "external_id",
          "name",
          "group",
          "prefpage_access",
          "display_names",
          "display_descriptions"
        ],
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true,
            "description": "Unique identifier assigned on creation. Returned as a string.",
            "examples": [
              "12"
            ]
          },
          "external_id": {
            "type": "string",
            "readOnly": true,
            "description": "Externally visible identifier used in public-facing integrations.",
            "examples": [
              "a1b2c3d4e5f6"
            ]
          },
          "name": {
            "type": "string",
            "description": "The subscription name.",
            "examples": [
              "Campus Weekly Newsletter"
            ]
          },
          "group": {
            "type": "string",
            "description": "Name of the group the subscription belongs to. Empty string (`\"\"`) when no group is assigned.",
            "examples": [
              "Student Communications",
              ""
            ]
          },
          "prefpage_access": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ],
            "description": "Controls whether this subscription appears on the public preference page. `\"public\"` (default) means it is visible to contacts. `\"private\"` hides it from public preference pages — requires the private subscriptions feature.",
            "examples": [
              "public"
            ]
          },
          "display_names": {
            "type": "object",
            "description": "Translated display labels keyed by ISO language code. Shown to contacts on the preference page. Values are empty strings when no translation is set. All enabled account languages are included as keys.",
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "en": "Campus Weekly Newsletter",
                "fr": "Bulletin hebdomadaire du campus"
              }
            ]
          },
          "display_descriptions": {
            "type": "object",
            "description": "Translated descriptions keyed by ISO language code. Shown alongside the display name on the preference page. Values are empty strings when no translation is set. All enabled account languages are included as keys.",
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "en": "A weekly roundup of campus news and events.",
                "fr": "Un résumé hebdomadaire des nouvelles et événements du campus."
              }
            ]
          }
        }
      },
      "SubscriptionCreate": {
        "type": "object",
        "description": "Request body for creating a new subscription. `name` is required.",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "The subscription name.",
            "examples": [
              "Campus Weekly Newsletter"
            ]
          },
          "group": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Group to assign the subscription to. Accepts the group name (string) or group ID (integer). The group must be of type `subscription`.",
            "examples": [
              "Student Communications",
              5
            ]
          },
          "prefpage_access": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ],
            "description": "Preference page visibility. Defaults to `\"public\"`. Setting to `\"private\"` requires the private subscriptions feature.",
            "examples": [
              "public"
            ]
          },
          "display_names": {
            "type": "object",
            "description": "Translated display labels keyed by ISO language code.",
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "en": "Campus Weekly Newsletter",
                "fr": "Bulletin hebdomadaire du campus"
              }
            ]
          },
          "display_descriptions": {
            "type": "object",
            "description": "Translated descriptions keyed by ISO language code.",
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "en": "A weekly roundup of campus news and events."
              }
            ]
          }
        }
      },
      "SubscriptionUpdate": {
        "type": "object",
        "description": "Request body for updating a subscription. At least one field must be provided. `external_id` is silently ignored if included. If `id` is included, it must match the `{id}` in the URL — if they differ, a validation envelope is returned.",
        "minProperties": 1,
        "properties": {
          "id": {
            "type": [
              "integer",
              "string"
            ],
            "description": "Optional. If provided, must match the `{id}` in the URL. A mismatch returns a validation envelope.",
            "examples": [
              12
            ]
          },
          "name": {
            "type": "string",
            "description": "New name for the subscription.",
            "examples": [
              "Updated Subscription Name"
            ]
          },
          "group": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Group to assign the subscription to. Accepts group name or group ID. Pass `\"\"` (empty string) to remove the group assignment.",
            "examples": [
              "Alumni Relations",
              ""
            ]
          },
          "prefpage_access": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ],
            "description": "Preference page visibility. Setting to `\"private\"` requires the private subscriptions feature.",
            "examples": [
              "public"
            ]
          },
          "display_names": {
            "type": "object",
            "description": "Translated display labels keyed by ISO language code.",
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "en": "Updated Subscription Name"
              }
            ]
          },
          "display_descriptions": {
            "type": "object",
            "description": "Translated descriptions keyed by ISO language code.",
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "en": "Updated description."
              }
            ]
          }
        }
      },
      "ContactsRequest": {
        "type": "object",
        "description": "Request body for adding or removing contacts. Provide exactly one of `contact_ids` or `contact_emails`.",
        "oneOf": [
          {
            "required": [
              "contact_ids"
            ],
            "properties": {
              "contact_ids": {
                "type": "array",
                "items": {
                  "type": "integer"
                },
                "minItems": 1,
                "maxItems": 1000,
                "description": "Envoke contact IDs to add or remove.",
                "examples": [
                  [
                    101,
                    102,
                    103
                  ]
                ]
              }
            }
          },
          {
            "required": [
              "contact_emails"
            ],
            "properties": {
              "contact_emails": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "minItems": 1,
                "maxItems": 1000,
                "description": "Contact email addresses to add or remove.",
                "examples": [
                  [
                    "alice@example.com",
                    "bob@example.com"
                  ]
                ]
              }
            }
          }
        ]
      },
      "ContactsSuccessResponse": {
        "type": "object",
        "description": "Returned after a contacts add or remove operation.",
        "required": [
          "success",
          "result_text",
          "result_data"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "`true` if no found contacts failed to update. `true` even when some identifiers were not found."
          },
          "result_text": {
            "type": "string",
            "description": "Human-readable summary.",
            "examples": [
              "Set to contacts",
              "Set to contacts. Some contacts not found",
              "Error setting to contacts"
            ]
          },
          "result_data": {
            "type": "object",
            "required": [
              "processed"
            ],
            "properties": {
              "processed": {
                "type": "integer",
                "description": "Total number of input identifiers submitted."
              },
              "not_found": {
                "type": "array",
                "description": "IDs or emails that were not matched to any contact. Only present when at least one was not found.",
                "items": {
                  "type": [
                    "string",
                    "integer"
                  ]
                }
              },
              "failed": {
                "type": "array",
                "description": "Contacts that were found but failed during the update. Only present when failures occurred.",
                "items": {
                  "type": "object",
                  "required": [
                    "contact_id",
                    "reason"
                  ],
                  "properties": {
                    "contact_id": {
                      "type": [
                        "string",
                        "integer"
                      ]
                    },
                    "reason": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "CreateSuccessResponse": {
        "type": "object",
        "description": "Returned on successful subscription creation.",
        "required": [
          "success",
          "result_text",
          "result_data"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "result_text": {
            "type": "string",
            "const": "Created"
          },
          "result_data": {
            "$ref": "#/components/schemas/Subscription"
          }
        }
      },
      "UpdateSuccessResponse": {
        "type": "object",
        "description": "Returned on successful subscription update.",
        "required": [
          "success",
          "result_text",
          "result_data"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "result_text": {
            "type": "string",
            "const": "Updated"
          },
          "result_data": {
            "$ref": "#/components/schemas/Subscription"
          }
        }
      },
      "DeleteSuccessResponse": {
        "type": "object",
        "description": "Returned on successful subscription deletion.",
        "required": [
          "success",
          "result_text",
          "result_data"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "result_text": {
            "type": "string",
            "const": "Deleted"
          },
          "result_data": {
            "type": "array",
            "maxItems": 0
          }
        }
      },
      "ValidationErrorResponse": {
        "type": "object",
        "description": "Returned when request body or path parameter validation fails.",
        "required": [
          "success",
          "result_text",
          "result_data"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": false
          },
          "result_text": {
            "type": "string",
            "const": "Validation failed, see 'result_data' -> 'errors'"
          },
          "result_data": {
            "type": "object",
            "required": [
              "errors"
            ],
            "properties": {
              "errors": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "One or more human-readable validation error messages."
              }
            }
          }
        }
      }
    },
    "parameters": {
      "SubscriptionId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "The unique ID of the subscription.",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "Maximum number of records to return. Default is 10, hard cap is 100. When used alongside `?fields=` or `?result_type=kvp`, the cap is lifted and an explicit limit above 100 is honoured as-is.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 10
        }
      },
      "Skip": {
        "name": "skip",
        "in": "query",
        "description": "Number of records to skip. Used for pagination.",
        "schema": {
          "type": "integer",
          "minimum": 0,
          "default": 0
        }
      },
      "Fields": {
        "name": "fields",
        "in": "query",
        "description": "Comma-separated list of fields to include in each response object. When set, the default limit increases to 10,000 and the 100-record hard cap is lifted.",
        "schema": {
          "type": "string"
        },
        "example": "id,name,group"
      },
      "ResultType": {
        "name": "result_type",
        "in": "query",
        "description": "Set to `kvp` to receive results as a flat key-value object (`{ \"<id>\": \"<name>\" }`) instead of an array of objects. When set, the default limit increases to 10,000 and the hard cap is lifted.",
        "schema": {
          "type": "string",
          "enum": [
            "kvp"
          ]
        }
      }
    },
    "responses": {
      "NotFoundGet": {
        "description": "The requested subscription ID was not found. Returns an empty array.",
        "content": {
          "application/json": {
            "schema": {
              "type": "array",
              "maxItems": 0
            },
            "example": []
          }
        }
      }
    }
  },
  "paths": {
    "/subscriptions": {
      "get": {
        "summary": "List subscriptions",
        "description": "Returns a paginated array of subscriptions for the authenticated account, sorted alphabetically by name by default. Supports filtering by `id`, `name`, `external_id`, `group`, and `prefpage_access`. Use `?result_type=kvp` for a flat id-to-name map. Filter operators supported: exact match and `(ne)` (not equal).",
        "operationId": "listSubscriptions",
        "tags": [
          "Subscriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Skip"
          },
          {
            "$ref": "#/components/parameters/Fields"
          },
          {
            "$ref": "#/components/parameters/ResultType"
          },
          {
            "name": "filter[id]",
            "in": "query",
            "description": "Filter by subscription ID. Supports `(ne)` operator.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filter[name]",
            "in": "query",
            "description": "Filter by subscription name. Supports `(ne)` operator.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filter[external_id]",
            "in": "query",
            "description": "Filter by external ID. Supports `(ne)` operator.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filter[group]",
            "in": "query",
            "description": "Filter by group name. Supports `(ne)` operator.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filter[prefpage_access]",
            "in": "query",
            "description": "Filter by preference page access. Supports `(ne)` operator.",
            "schema": {
              "type": "string",
              "enum": [
                "public",
                "private"
              ]
            }
          },
          {
            "name": "sort[name]",
            "in": "query",
            "description": "Sort by name. Value: `asc` or `desc`.",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A list of subscriptions.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Subscription"
                      }
                    },
                    {
                      "type": "object",
                      "description": "Key-value map of subscription ID to name.",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  ]
                },
                "examples": {
                  "array": {
                    "summary": "Default array response",
                    "value": [
                      {
                        "id": "12",
                        "external_id": "a1b2c3d4e5f6",
                        "name": "Campus Weekly Newsletter",
                        "group": "Student Communications",
                        "prefpage_access": "public",
                        "display_names": {
                          "en": "Campus Weekly Newsletter",
                          "fr": "Bulletin hebdomadaire du campus"
                        },
                        "display_descriptions": {
                          "en": "A weekly roundup of campus news and events.",
                          "fr": ""
                        }
                      }
                    ]
                  },
                  "kvp": {
                    "summary": "Key-value pair response (result_type=kvp)",
                    "value": {
                      "12": "Campus Weekly Newsletter",
                      "13": "Alumni Quarterly"
                    }
                  },
                  "empty": {
                    "summary": "No subscriptions",
                    "value": []
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a subscription",
        "description": "Creates a new subscription. `name` is required. Optional fields: `group`, `prefpage_access`, `display_names`, `display_descriptions`.",
        "operationId": "createSubscription",
        "tags": [
          "Subscriptions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscriptionCreate"
              },
              "examples": {
                "basic": {
                  "summary": "Create a basic subscription",
                  "value": {
                    "name": "Campus Weekly Newsletter"
                  }
                },
                "with_group": {
                  "summary": "Create with group",
                  "value": {
                    "name": "Alumni Quarterly",
                    "group": "Alumni Relations"
                  }
                },
                "with_translations": {
                  "summary": "Create with display names and descriptions",
                  "value": {
                    "name": "Campus Weekly Newsletter",
                    "group": "Student Communications",
                    "display_names": {
                      "en": "Campus Weekly Newsletter",
                      "fr": "Bulletin hebdomadaire du campus"
                    },
                    "display_descriptions": {
                      "en": "A weekly roundup of campus news and events."
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscription created successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateSuccessResponse"
                },
                "example": {
                  "success": true,
                  "result_text": "Created",
                  "result_data": {
                    "id": "12",
                    "external_id": "a1b2c3d4e5f6",
                    "name": "Campus Weekly Newsletter",
                    "group": "Student Communications",
                    "prefpage_access": "public",
                    "display_names": {
                      "en": "Campus Weekly Newsletter",
                      "fr": ""
                    },
                    "display_descriptions": {
                      "en": "A weekly roundup of campus news and events.",
                      "fr": ""
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                },
                "examples": {
                  "name_required": {
                    "summary": "Missing name",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "The field 'name' is required"
                        ]
                      }
                    }
                  },
                  "invalid_group": {
                    "summary": "Group not found",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Invalid 'group': 'Nonexistent Group'"
                        ]
                      }
                    }
                  },
                  "invalid_prefpage_access": {
                    "summary": "Invalid prefpage_access value",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "'prefpage_access' must be 'public' or 'private'"
                        ]
                      }
                    }
                  },
                  "prefpage_access_feature_required": {
                    "summary": "Private subscriptions feature not enabled",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Setting 'prefpage_access' to 'private' requires the private subscriptions feature"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/subscriptions/{id}": {
      "get": {
        "summary": "Get a single subscription",
        "description": "Returns a single subscription by its ID. Returns an empty array (`[]`) if the ID is not found.",
        "operationId": "getSubscription",
        "tags": [
          "Subscriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SubscriptionId"
          },
          {
            "$ref": "#/components/parameters/Fields"
          }
        ],
        "responses": {
          "200": {
            "description": "The requested subscription, or an empty array if not found.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Subscription"
                    },
                    {
                      "type": "array",
                      "maxItems": 0
                    }
                  ]
                },
                "examples": {
                  "found": {
                    "summary": "Subscription found",
                    "value": {
                      "id": "12",
                      "external_id": "a1b2c3d4e5f6",
                      "name": "Campus Weekly Newsletter",
                      "group": "Student Communications",
                      "prefpage_access": "public",
                      "display_names": {
                        "en": "Campus Weekly Newsletter",
                        "fr": "Bulletin hebdomadaire du campus"
                      },
                      "display_descriptions": {
                        "en": "A weekly roundup of campus news and events.",
                        "fr": ""
                      }
                    }
                  },
                  "not_found": {
                    "summary": "Subscription not found",
                    "value": []
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a subscription",
        "description": "Updates one or more fields on an existing subscription. `name`, `group`, `prefpage_access`, `display_names`, and `display_descriptions` are updatable. `external_id` is silently ignored if included. If `id` is included in the body, it must match the `{id}` in the URL — if they differ, a validation envelope is returned.",
        "operationId": "updateSubscription",
        "tags": [
          "Subscriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SubscriptionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscriptionUpdate"
              },
              "examples": {
                "rename": {
                  "summary": "Rename the subscription",
                  "value": {
                    "name": "Campus Weekly (Updated)"
                  }
                },
                "assign_group": {
                  "summary": "Assign to a group",
                  "value": {
                    "group": "Student Communications"
                  }
                },
                "remove_group": {
                  "summary": "Remove group assignment",
                  "value": {
                    "group": ""
                  }
                },
                "update_display_names": {
                  "summary": "Update display names",
                  "value": {
                    "display_names": {
                      "en": "Campus Weekly",
                      "fr": "Campus hebdo"
                    }
                  }
                },
                "update_display_descriptions": {
                  "summary": "Update display descriptions",
                  "value": {
                    "display_descriptions": {
                      "en": "Updated description for the weekly newsletter."
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscription updated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateSuccessResponse"
                },
                "example": {
                  "success": true,
                  "result_text": "Updated",
                  "result_data": {
                    "id": "12",
                    "external_id": "a1b2c3d4e5f6",
                    "name": "Campus Weekly (Updated)",
                    "group": "Student Communications",
                    "prefpage_access": "public",
                    "display_names": {
                      "en": "Campus Weekly",
                      "fr": "Campus hebdo"
                    },
                    "display_descriptions": {
                      "en": "Updated description for the weekly newsletter.",
                      "fr": ""
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error, subscription not found, or id mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                },
                "examples": {
                  "not_found": {
                    "summary": "Subscription not found",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Item with id '999999' not found"
                        ]
                      }
                    }
                  },
                  "invalid_group": {
                    "summary": "Group not found",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Invalid 'group': 'Does Not Exist'"
                        ]
                      }
                    }
                  },
                  "prefpage_access_feature_required": {
                    "summary": "Private subscriptions feature not enabled",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Setting 'prefpage_access' to 'private' requires the private subscriptions feature"
                        ]
                      }
                    }
                  },
                  "id_mismatch": {
                    "summary": "id in body does not match URL id",
                    "value": {
                      "success": false,
                      "result_text": "Provided 'id': 12 does not match 'id' in request body (999)",
                      "result_data": []
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a subscription",
        "description": "Permanently deletes a subscription. **The subscription must have no contacts assigned to it** — attempting to delete one with contacts assigned returns a validation error. Remove all contacts first using the `DELETE /subscriptions/{id}/contacts` endpoint.",
        "operationId": "deleteSubscription",
        "tags": [
          "Subscriptions"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SubscriptionId"
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription deleted successfully, or a validation error.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/DeleteSuccessResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ValidationErrorResponse"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "Deleted successfully",
                    "value": {
                      "success": true,
                      "result_text": "Deleted",
                      "result_data": []
                    }
                  },
                  "not_found": {
                    "summary": "Subscription not found",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Item with id '999999' not found"
                        ]
                      }
                    }
                  },
                  "has_contacts": {
                    "summary": "Cannot delete — contacts assigned",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Cannot delete a subscription that has contacts assigned to it"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/subscriptions/{id}/contacts": {
      "post": {
        "summary": "Add contacts to a subscription",
        "description": "Bulk-assigns contacts to a subscription. Accepts either `contact_ids` or `contact_emails` (not both). Maximum 1,000 items per request. The operation is idempotent — adding a contact that is already subscribed is a no-op.",
        "operationId": "addSubscriptionContacts",
        "tags": [
          "Subscription Contacts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SubscriptionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactsRequest"
              },
              "examples": {
                "by_ids": {
                  "summary": "Add by contact IDs",
                  "value": {
                    "contact_ids": [
                      101,
                      102,
                      103
                    ]
                  }
                },
                "by_emails": {
                  "summary": "Add by email addresses",
                  "value": {
                    "contact_emails": [
                      "alice@example.com",
                      "bob@example.com"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operation completed. Check `success` and `result_data` for details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactsSuccessResponse"
                },
                "examples": {
                  "all_found": {
                    "summary": "All contacts found and updated",
                    "value": {
                      "success": true,
                      "result_text": "Set to contacts",
                      "result_data": {
                        "processed": 3
                      }
                    }
                  },
                  "some_not_found": {
                    "summary": "Some contacts not found",
                    "value": {
                      "success": true,
                      "result_text": "Set to contacts. Some contacts not found",
                      "result_data": {
                        "processed": 3,
                        "not_found": [
                          "ghost@example.com"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error or subscription not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                },
                "examples": {
                  "no_field": {
                    "summary": "Neither contact_ids nor contact_emails provided",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Either 'contact_ids' or 'contact_emails' must be provided"
                        ]
                      }
                    }
                  },
                  "both_fields": {
                    "summary": "Both contact_ids and contact_emails provided",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Provide either 'contact_ids' or 'contact_emails', not both"
                        ]
                      }
                    }
                  },
                  "subscription_not_found": {
                    "summary": "Subscription not found",
                    "value": {
                      "success": false,
                      "result_text": "Validation failed, see 'result_data' -> 'errors'",
                      "result_data": {
                        "errors": [
                          "Item with id '999999' not found"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Remove contacts from a subscription",
        "description": "Bulk-removes contacts from a subscription. Accepts either `contact_ids` or `contact_emails` (not both). Maximum 1,000 items per request. The operation is idempotent — removing a contact that is not subscribed is a no-op.",
        "operationId": "removeSubscriptionContacts",
        "tags": [
          "Subscription Contacts"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/SubscriptionId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactsRequest"
              },
              "examples": {
                "by_ids": {
                  "summary": "Remove by contact IDs",
                  "value": {
                    "contact_ids": [
                      101,
                      102
                    ]
                  }
                },
                "by_emails": {
                  "summary": "Remove by email addresses",
                  "value": {
                    "contact_emails": [
                      "alice@example.com"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Operation completed. Check `success` and `result_data` for details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactsSuccessResponse"
                },
                "example": {
                  "success": true,
                  "result_text": "Set to contacts",
                  "result_data": {
                    "processed": 2
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error or subscription not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  }
}
